所以我有几个事实:
%bridge(Name,From,To).
bridge(a,1,2).
bridge(b,1,2).
bridge(c,2,3).
bridge(d,3,4).
编辑:更改为原子
所以这就像“桥A从区域1到区域2的十字架”。这很简单。然而,反过来也是如此。桥A从第2区到第1区的交叉。这就是为什么我想:
bridge(B,S,E):- bridge(B,E,S).
事实上,这会扰乱我的程序,因为每当swi-prolog找不到桥的匹配时,它将继续使用桥规则一遍又一遍地反转它的参数。有没有办法阻止这个?或者有没有其他方法来创建一个简单的规则?如果我添加其他所有事实(桥(A,2,1),桥(C,3,2)等),我的程序将完美运行。
答案 0 :(得分:3)
首先请注意,您似乎在使用变量来表示使用原子来识别桥梁。
关于你的问题:你可以通过添加额外的必要事实来轻松解决这个问题,例如:
bridge(a, 1, 2).
bridge(a, 2, 1).
bridge(b, 1, 2).
bridge(b, 2, 1).
etc.
然而,正如您已经直观地注意到的那样,这显然是多余的,您可以使用辅助谓词重构它,例如bridge_/2
,其中包含两个子句:
bridge(B, X, Y) :- bridge_(B, X, Y).
brigde(B, X, Y) :- bridge_(B, Y, X).
bridge_(a, 1, 2).
bridge_(b, 2, 1).
bridge_(c, 2, 3).
etc.
答案 1 :(得分:1)
Prolog提供了一种处理每个子句读取的方法,在断言之前,通过term_expansion / 2。应该这样工作:
term_expansion(bridge(K,A,B), bridge(K,A,B)) :- assertz(bridge(K,B,A)).
也就是说,它'返回'未更改的术语读取,并添加一个带有交换'连接'的术语。 请注意,使用图形跟踪器调试转换后的源代码可能很困难......
编辑我的回答有点肤浅,我正在尝试调试它......
编辑感谢Paulo提示,这里有点工作......
:- module(bridge, [bridge/3]).
term_expansion(bridge(K,A,B), [bridge(K,A,B),bridge(K,B,A)]).
bridge(a,1,2).
bridge(b,1,2).
bridge(c,2,3).
bridge(d,3,4).