Prolog中的事实

时间:2011-11-27 18:31:16

标签: prolog

我正在写一个关于道路的节目......

例如,我有road(1, a, b, 2)(从a到b的1号公路占用2个单位的燃料)。关键是如果我有road(1, a, b, 2)我还必须road(1, b, a, 2)但如果我使用一个我不能使用另一个,否则程序将循环。

我可以写什么,如果程序使用这一个事实,它不能使用另一个?

3 个答案:

答案 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).

否则,我们选择一个我们尚未访问的航路点并继续。

相关问题