使用事实打印答案

Print Answer using Facts

我正在尝试打印 Facts 中存在的值。例如,当我有以下事实时:

terrain(2,(2,4,3,1)).
terrain(2,(3,1,2,4)).
terrain(1,(4,3,1,2)).
terrain(3,(1,2,4,3)).

输入:

v([1,2,3],R).

它应该给我:

R = [(4,3,1,2), (2,4,3,1), (3,1,2,4), (1,2,4,3)]

但是代码没有打印 Facts 中存在的 2 的第二个值,即 (3,1,2,4)。 我得到:

R = [(4,3,1,2), (2,4,3,1), (1,2,4,3)]

如何获取事实中某个值的所有可能值。

我的代码:

%Facts
terrain(2,(2,4,3,1)).
terrain(2,(3,1,2,4)).
terrain(1,(4,3,1,2)).
terrain(3,(1,2,4,3)).


v([],[]).
v([H|T],[Q|R]):-
    terrain(H,Q),
    v(T,R),!.

首先,让我们看看您的定义。你为什么在这里插入一个切口?让我们看看没有它会发生什么:

?- v([1,2,3],R).
   R = [(4,3,1,2),(2,4,3,1),(1,2,4,3)]
;  R = [(4,3,1,2),(3,1,2,4),(1,2,4,3)].

因此,您删除了第二个解决方案。现在您可能不喜欢它,但让我们记住您对 v/2 的定义。为了便于阅读,我将对您的定义进行概括。

:- op(950, fy, *).
* _G_0. % to  a goal

v([],[]).
v([H|T],[Q|R]):-
    * terrain(H,Q),
    v(T,R).

所以剩下的就是当两个参数都是相同长度的列表时为真的关系。因此也添加了 terrain/2 这将成立。无法使第二个参数成为更长的列表。如果你真的想改变这个,你必须已经修改那个通用部分。

v2([], []).
v2([H|Hs], Vs0) :-
   setof(V, terrain(H, V), Vs),
   append(Vs, Vs1,Vs0),
   v2(Hs, Vs1).

?- v2([1,2,3],R).
   R = [(4,3,1,2),(2,4,3,1),(3,1,2,4),(1,2,4,3)].

或者,最好使用 DCG:

seq([]) -->
   [].
seq([E|Es]) -->
   [E],
   seq(Es).

v([]) -->
   [].
v([H|Hs]) -->
   {setof(V, terrain(H, V), Vs)},
   seq(Vs),
   v(Hs).

?- phrase(v([1,2,3]), Vs).
   Vs = [(4,3,1,2),(2,4,3,1),(3,1,2,4),(1,2,4,3)].
?- length(Hs, 2), phrase(v(Hs), Vs).
   Hs = [1,1], Vs = [(4,3,1,2),(4,3,1,2)]
;  Hs = [1,2], Vs = [(4,3,1,2),(2,4,3,1),(3,1,2,4)]
;  Hs = [1,3], Vs = [(4,3,1,2),(1,2,4,3)]
;  Hs = [2,1], Vs = [(2,4,3,1),(3,1,2,4),(4,3,1,2)]
;  Hs = [2,2], Vs = [(2,4,3,1),(3,1,2,4),(2,4,3,1),(3,1,2,4)]
;  Hs = [2,3], Vs = [(2,4,3,1),(3,1,2,4),(1,2,4,3)]
;  Hs = [3,1], Vs = [(1,2,4,3),(4,3,1,2)]
;  Hs = [3,2], Vs = [(1,2,4,3),(2,4,3,1),(3,1,2,4)]
;  Hs = [3,3], Vs = [(1,2,4,3),(1,2,4,3)].
?- Hs = [A,B], dif(A,B), phrase(v(Hs), Vs).
   Hs = [1,2], A = 1, B = 2, Vs = [(4,3,1,2),(2,4,3,1),(3,1,2,4)]
;  Hs = [1,3], A = 1, B = 3, Vs = [(4,3,1,2),(1,2,4,3)]
;  Hs = [2,1], A = 2, B = 1, Vs = [(2,4,3,1),(3,1,2,4),(4,3,1,2)]
;  Hs = [2,3], A = 2, B = 3, Vs = [(2,4,3,1),(3,1,2,4),(1,2,4,3)]
;  Hs = [3,1], A = 3, B = 1, Vs = [(1,2,4,3),(4,3,1,2)]
;  Hs = [3,2], A = 3, B = 2, Vs = [(1,2,4,3),(2,4,3,1),(3,1,2,4)].

而且,顺便说一句,在 Prolog 中通常更喜欢写 v(4,3,1,2)) 而不是 (4,3,1,2)。只需说 write_canonical((4,3,1,2)). 即可了解原因。