问题描述
这是一个课堂作业,但我不知道如何解决我的问题。 我写了以下内容:
codeArea.textproperty().addListener(new changelistener<String>()
{
@Override
public void changed(ObservableValue<? extends String> observableValue,String s,String s2) {
String curr = "";
String currFinal = "";
for (int i = codeArea.getAnchor(); i > 0; i--) {
if (codeArea.getText().charat(i) == '\n' || codeArea.getText().charat(i) == ' ') {
break;
}else {
curr += codeArea.getText().charat(i);
}
}
for (int i = curr.length()-1; i >= 0; i--) {
currFinal += curr.charat(i);
}
if (currFinal != "") {
ArrayList<String> fil = new ArrayList<String>();
for (int i = 0; i < keyphrases.length; i++) {
if (keyphrases[i].contains(currFinal)) {
fil.add(keyphrases[i]);
}
}
System.out.println("Fil " + fil);
if (popup != null) {
popup.hide();
}
if (fil.size() > 0) {
ListView lop = new ListView();
for (int i = 0; i < fil.size(); i++) {
lop.getItems().add(fil.get(i));
}
popup = new Popup();
lop.setMaxHeight(80);
popup.getContent().addAll(lop);
popup.show(codeArea,codeArea.getCaretBounds().get().getMaxX(),codeArea.getCaretBounds().get().getMaxY());
codeArea.requestFocus();
}
codeArea.requestFocus();
}else {
if (popup != null) {
popup.hide();
}
}
}
});
我做了一个跟踪:
sentence(S0,S):- f(S0,S); t(S0,S1),n(S1,S2),t(S2,S).
f(S0,S):- termIf(S0,pLeft(S1,b(S2,S3),pRight(S3,S4),termThen(S4,S5),termBegin(S5,S6),sentence(S6,S7),termEnd(S7,S); termIf(S0,termElse(S7,S8),sentence(S8,S9),termEnd(S9,S).
b(S0,S):- t(S0,e(S1,S).
termIf(S0,S) :- S0=[if|S].
termThen(S0,S):- S0=[then|S].
termBegin(S0,S):- S0=[begin|S].
termEnd(S0,S):- S0=[end|S].
termElse(S0,S):- S0=[else|S].
pLeft(S0,S):- S0=['('|S].
pRight(S0,S):- S0=[')'|S].
t(S0,S):- S0=[x|S].
t(S0,S):- S0=[y|S].
t(S0,S):- S0=[z|S].
t(S0,S):- S0=[1|S].
t(S0,S):- S0=[0|S].
e(S0,S):- S0=[>|S].
e(S0,S):- S0=[<|S].
n(S0,S):- S0=[+|S].
n(S0,S):- S0=[-|S].
n(S0,S):- S0=[=|S].
我认为当句子被调用时它显然失败了,但它得到了一个它无法处理的 [[x,=,1],end] 。我认为显而易见的答案是 [x,1] 是列表的第一个元素,但我不知道如何将该元素传递给句子,以便正确处理事情。我很难过。
解决方法
该代码需要一个扁平的终端列表,但其中有一个嵌套的 [x,=,1]
。你想要的是
?- sentence([if,'(',x,>,')',then,begin,1,end],X).
X = []
Yes (0.00s cpu,solution 1,maybe more)
No (0.00s cpu)
,
你怎么能自己定位错误?一种可能性是概括您的查询。只要您的程序是纯单调的,以下内容就成立:
如果通用查询失败,那么更专业的查询也会失败
因此,这种概括与失败相关。
通过用 _
替换条款,我获得了以下仍然失败的查询(另外,我将您的代码翻译成 DCG 形式)...
?- phrase(sentence,[if,[x,1],end]).
false.
?- phrase(sentence,[_,_,[_| _ ]| _]).
false.
sentence--> f ; t,n,t.
(加上 CapelliC 给出的其余规则)
从这个概括我们看到,没有一个句子的第 9 个元素是一个至少有一个元素的列表。
另请注意,您现在可以枚举所有句子!
?- length(L,_),phrase(sentence,L).
L = [x,+,x]
; L = [x,y]
; L = [x,z]
; L = [x,1]
; L = [x,0]
; ...
,
问题,正如@jschimpf 所指出的,是我们在初始调用中混合了两个描述级别。列表是元数据,用 DCG 符号重写语法更明显。一旦修正了原始公式(是 sentence--> f; t,t.
),测试 ?- g.
就通过了。
sentence--> f; [L],{phrase((t,t),L)}.
f--> termIf,pLeft,b,pRight,termThen,termBegin,sentence,termEnd.
f--> termIf,termElse,termEnd.
b--> t,e,t.
termIf--> [if].
termThen--> [then].
termBegin--> [begin].
termEnd--> [end].
termElse--> [else].
pLeft--> ['('].
pRight--> [')'].
t--> [x].
t--> [y].
t--> [z].
t--> [1].
t--> [0].
e--> [>].
e--> [<].
n--> [+].
n--> [-].
n--> [=].
g :- phrase(sentence,end]).
编辑
现在我们可以修复原始代码中的问题,其中 sentence/2
具有 DCG 分配给 phrase/2 的角色:
sentence(S0,S):-
S0=[H|T],( \+is_list(H)
-> f(S0,S)
; t(H,S1),n(S1,S2),t(S2,[]),S=T
).
编辑 我已经提出了我认为对句子/2 更有指导意义的更正,但我们可以避免“不纯”的 if/then/else 结构,例如
sentence(S0,S):-
f(S0,S);S0=[H|S],H=[_|_],t(H,[]).
应该可以工作(未经测试...)