我编写了一个程序来对符号中的数字进行排序,但是它有效,但是在列表末尾给出了一个内存地址,它没有经过最后一次。为什么会这样?
separate([],[],[]).
separate([X],X,_):-number(X).
separate([X],_,X).
separate([X|Y],[X|Z],S):-number(X),separate(Y,Z,S).
separate([X|Y],Z,[X|S]):-separate(Y,Z,S).
咨询?- separate([3,a,b,4,5,c],X,Y).
我明白了:
X = [3, 4, 5|_G2592],
Y = [a, b, c] .
答案 0 :(得分:2)
我建议
separate([],[],[]).
separate([H | T], [H | Tn], Ls) :-
number(H),
separate(T, Tn, Ls).
separate([H | T], Ln, [H | Ts]) :-
\+ number(H),
separate(T, Ln, Ts).
如果你有一个终结条款separate([],[],[])
和一些普通条款separate([X|Y],[X|Z],S)
和separate([X|Y],Z,[X|S])
,你不需要半终结条款separate([X],X,_)
和separate([X],_,X)
和它们(具有未定义的值_
)避免统一其中一个列表,并获得“内存地址”(非统一变量的标识符)。
如果你有一个带有number(X)
的子句,另一个(替代)子句需要“not-number”检查(即\+ number(X)
),否则两个子句对数字都是正确的,你可以乘以解决方案,数字列表中没有数字。
答案 1 :(得分:1)
那是因为你保持列表开放:
separate([X],X,_):-number(X). separate([X],_,X).
问题是:你实际上不需要写这些语句,你可以省略它们:
separate([],[],[]).
separate([X|Y],[X|Z],S):-number(X),separate(Y,Z,S).
separate([X|Y],Z,[X|S]):-separate(Y,Z,S).
这会有效但会返回多个结果,而除了第一个,其余都是错误的。你应该通过在最后一个句子中添加一个守卫来解决这个问题:
separate([],[],[]). separate([X|Y],[X|Z],S):-number(X),separate(Y,Z,S). separate([X|Y],Z,[X|S]):-\+ number(X),separate(Y,Z,S).
\+
的行为类似于"而不是"在某种意义上,如果Prolog无法与\+ number(X)
匹配,number(X)
将会成功。
最后要注意的是,你所看到的并不是一个真正的内存地址:它只是一个未经实例化的变量,尽管这当然是一个小问题。