swi prolog提供了太多的解决方案

swi prolog提供了太多的解决方案,prolog,dcg,Prolog,Dcg,我的prolog程序应该返回一个术语中包含的所有变量的列表。它确实工作正常,因为我的结果是所有变量的列表。但是现在Prolog应该停止了,它继续并给了我八次相同的变量列表。我不明白为什么在找到解决方案后它不停止。有人能解释一下我的错误吗 variablen(X,[]):- number(X). variablen(X,[X]):- atomic(X), not(number(X)). variablen(X+Y,R):- not(number(X)), atomic(X

我的prolog程序应该返回一个术语中包含的所有变量的列表。它确实工作正常,因为我的结果是所有变量的列表。但是现在Prolog应该停止了,它继续并给了我八次相同的变量列表。我不明白为什么在找到解决方案后它不停止。有人能解释一下我的错误吗

variablen(X,[]):-
   number(X).
variablen(X,[X]):-
   atomic(X),
   not(number(X)).

variablen(X+Y,R):-
   not(number(X)), atomic(X), R1 = [X], variablen(Y,R2), append(R2,R1,R).
variablen(Y+X,R):-
   not(number(X)), atomic(X), R1 = [X], variablen(Y,R2), append(R2,R1,R).
variablen(X+Y,R):-
   variablen(X,P), variablen(Y,Q), append(P,Q,R).

variablen(X-Y, R):-
   not(number(X)), atomic(X), R1 = [X], variablen(Y,R2), append(R2,R1,R).
variablen(Y-X, R):-
   not(number(X)), atomic(X), R1 = [X], variablen(Y,R2), append(R2,R1,R).
variablen(X-Y,R):-
   variablen(X,P), variablen(Y,Q), append(P,Q,R).

variablen(X*Y,R):-
   not(number(X)),atomic(X), R1 = [X], variablen(Y,R2), append(R2,R1,R).
variablen(Y*X, R):-
   not(number(X)), atomic(X),R1 = [X], variablen(Y,R2), append(R2,R1,R).
variablen(X*Y,R):-
   variablen(X,P), variablen(Y,Q), append(P,Q,R).

variablen(X/Y, R):-
   not(number(X)), atomic(X), R1 = [X], variablen(Y,R2), append(R2,R1,R).
variablen(Y/X, R):-
   not(number(X)), atomic(X), R1 = [X], variablen(Y,R2), append(R2,R1,R).
variablen(X/Y,R):-
   variablen(X,P), variablen(Y,Q), append(P,Q,R).

这里有几个问题

首先,
variablen(a,R)。
通过
R=[a]
成功。您说过列表应该包含所有变量。所以也许你想收集所有对你有变量意义的原子

第二,用相应的ISO内置
(\+)/1
替换非常特定于实现的
而不是/1

现在,对于找到的冗余解决方案。我将只看一个特定的查询:

?- variablen(a/b,L).
L = [b, a] ;
L = [a, b] ;
L = [a, b].
因此,有几种方法可以应用这些规则。我就要
/

variablen(X/Y, R):-
   \+number(X), atomic(X), R1 = [X], variablen(Y,R2), append(R2,R1,R).
variablen(Y/X, R):-
   \+number(X), atomic(X), R1 = [X], variablen(Y,R2), append(R2,R1,R).
variablen(X/Y,R):-
   variablen(X,P), variablen(Y,Q), append(P,Q,R).
对于
a/b
这三条规则都适用。因此你被解雇了

最好的解决方案是使用Definite子句语法,因为它们更优雅地处理连接:

variablen(N) -->
   {functor(N,_,0)}, !,   % rare green cut
   ( {number(N)} ; {atom(N)}, [N] ).
variablen(A+B) -->
   variablen(A),
   variablen(B).
variablen(A-B) -->
   variablen(A),
   variablen(B).
variablen(A*B) -->
   variablen(A),
   variablen(B).
variablen(A/B) -->
   variablen(A),
   variablen(B).
现在,您可以使用它:

?- phrase(variablen(a/b),L).
L = [a,b].

是的,这是有意的。问题现在解决了,因为我从Prolog编辑器(不起作用)切换到普通的swi Prolog,现在我只得到了一个应该得到的解决方案。但我不明白你所说的“这里是term_variables/2作为ISO内置谓词”是什么意思?