我正在写一个关于道路的节目......
例如,我有road(1, a, b, 2)
(从a到b的1号公路占用2个单位的燃料)。关键是如果我有road(1, a, b, 2)
我还必须road(1, b, a, 2)
但如果我使用一个我不能使用另一个,否则程序将循环。
我可以写什么,如果程序使用这一个事实,它不能使用另一个?
答案 0 :(得分:1)
我不确定我是否理解你,但也许 -
direct_road(1,a,b,2).
direct_road(1,b,a,2).
road(X,A,B,Y) :-
direct_road(X,A,B,Y),
direct_road(X,B,A,Y).
答案 1 :(得分:1)
您可以使用一个规则来捕获对称性,但将其放在具有相同名称和arity的所有其他规则之后。如果对于你的查询存在任何解决方案,它们将在进入任何类型的无限循环之前显示。
道路(R,A,B,F): - 道路(R,B,A,F)。
答案 2 :(得分:1)
如果你想保留你的对称事实(即使我不明白为什么),你可以保留一个被访问点列表以避免周期。我编写了一个没有道路编号的小例子:
road(a, b, 2).
road(b, a, 3).
road(b, c, 5).
get_road(a, c, FuelConsumed) :-
get_road(a, c, [a], 0, FuelConsumed).
我们在这里介绍两个新参数,第三个是访问点列表,第四个是跟踪消耗燃料的累加器。
get_road(Start, End, _Visited, TotalFuel, FuelConsumed) :-
road(Start, End, Fuel),
FuelConsumed is TotalFuel + Fuel.
如果这一步是最后一步,我们就会停止。
get_road(Start, End, Visited, TotalFuel, FuelConsumed) :-
road(Start, Waypoint, Fuel),
\+ member(Waypoint, Visited),
NewTotalFuel is TotalFuel + Fuel,
get_road(Waypoint, End, [Waypoint|Visited], NewTotalFuel, FuelConsumed).
否则,我们选择一个我们尚未访问的航路点并继续。