Prolog中的事实

3
我正在编写一份关于道路的程序...
例如,我有road(1, a, b, 2)(从a到b的第1条道路需要2个单位的燃料)。问题在于,如果我有road(1, a, b, 2),那么我也必须有road(1, b, a, 2),但如果我使用其中一个,就不能使用另一个,否则程序将会循环。
我该怎么写才能让程序只使用这一个事实,而不能使用另一个事实呢?
3个回答

1

你可以使用一个规则来捕获对称性,但是将其放在所有具有相同名称和元数的其他规则之后。如果存在任何解决方案,无论你的查询是什么,它们都将在进入任何无限循环之前显示。

road(R,A,B,F) :- road(R,B,A,F)。


我不明白这个条款如何帮助解决问题。如果有什么作用,我觉得它只会让事情变得更糟。您能详细说明一下为什么它应该解决所述问题吗? - m09

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

如果您想保留对称事实(尽管我不知道为什么要这样做),可以保留已访问点的列表以避免循环。我编写了一个没有路线编号的小例子:

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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接