Факти в Прологу - пролог

Я пишу програму про дороги ...

Наприклад, у мене є 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).

Іншими словами, ми вибираємо точку маршруту, яку ми не відвідали та продовжували.