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