Я пишу програму про дороги ...
Наприклад, у мене є road(1, a, b, 2)
(дорога № 1 від а до б, яка займає 2 одиниці палива). Справа в тому, якщо у мене є road(1, a, b, 2)
Я повинен також мати road(1, b, a, 2)
але якщо я використовую один, я не можу використовувати інший, інакше програма буде петля.
Що я можу писати так, щоб, якщо програма використовує цей факт, він не може використовувати інший?
Відповіді:
1 для відповіді № 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 для відповіді № 2
Ви можете використовувати одне правило для захоплення симетрії, алепокладіть його за всіма іншими правилами з однаковим ім'ям і артиллю. Якщо існують будь-які рішення для будь-якого вашого запиту, вони будуть показані, перш ніж потрапити до будь-якого нескінченного циклу.
дорога (R, A, B, F): - дорога (R, B, A, F).
1 для відповіді № 3
Ви можете зберегти список відвіданих точок, щоб уникнути циклів, якщо ви хочете зберегти свої симметричні факти (хоча я не розумію, чому). Я кодував невеликий приклад без номера дороги:
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).
Іншими словами, ми вибираємо точку маршруту, яку ми не відвідали та продовжували.