2

所以我有几个事实:

%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)等),我的程序将完美运行。

4

2 回答 2

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.
于 2013-10-28T14:38:04.757 回答
1

Prolog 提供了一种方法来处理每个读取的子句,断言它之前,通过term_expansion /2。应该这样工作:

term_expansion(bridge(K,A,B), bridge(K,A,B)) :- assertz(bridge(K,B,A)).

也就是说,它“返回”读取的未更改术语,并添加一个具有交换“连接”的术语。请注意,使用图形跟踪器可能难以调试转换后的源...

编辑我的答案有点肤浅,我正在尝试调试它...

编辑感谢保罗提示,这里有一些工作......

:- 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).
于 2013-10-28T15:05:15.267 回答