Пролог тот же предикат с разными элементами? - PullRequest
0 голосов
/ 06 мая 2020

Идея состоит в том, что у меня есть несколько комнат в отеле, которые я могу связать с гостями.

guest(FamilySurname,RoomTaken) or guest(FamilySurname, [RoomsTaken])

Таким образом, у меня может быть два способа написать один и тот же предикат, первый с использованием одного элемента в RoomTaken, второй - с использованием списка. Я хочу знать, свободна ли общая c комната X или нет, поэтому я написал следующий код:

iterativefree(X,[]).
iterativefree(X,Y) :- Y=[H|T] , H \= X , iterativefree(X,T).
free(X) :- forall(guest(_,Y) , ( Y \= [_,_] , X \= Y) ) .             
free(X) :- forall(guest(_,Y) , (Y=[H|T] , H \= X) ) , iterativefree(X,T).

Я решил использовать ИЛИ, чтобы моя программа могла работать в в обоих случаях, поэтому третья строка работает в первом случае (RoomTaken - это единственный элемент), четвертая - во втором случае (RoomTaken - это список), но что-то не работает, и я действительно не могу понять, что потому что трассировка не дает мне никакой информации ... она просто вызывает предикат и дает мне ответ.

trace , guest(ciao, [room8 , room1] ), free(room7).

 Call:guest(ciao, [room8, room1])
false

Может ли кто-нибудь дать мне понять, в чем я ошибаюсь? Спасибо.

EDIT: Как кто-то предложил в комментариях, я определил свой гостевой предикат в программе, а не в запросе, поэтому трассировка теперь работает правильно, но я заметил, что там является проблемой в Y = [H | T]

guest(ciao,[room8,room1]).
iterativefree(_,[]).
iterativefree(X,Y) :- Y=[H|T] , H \= X , iterativefree(X,T).
free(X) :-  forall(guest(_,Y) , (Y \= [_|_] , Y \= X) ).
free(X) :-   forall(guest(_,Y) , (Y=[H|T] , H \= X) ) , iterativefree(X,T).

trace , free(room5)
 Call:free(room5)
 Call:guest(_16142, _16144)
 Exit:guest(amo, [room1, room17, room5])
 Call:[room1, room17, room5]\=[_16056|_16058]
 Fail:[room1, room17, room5]\=[_16056|_16058]
 Redo:free(room5)
 Call:guest(_16142, _16144)
 Exit:guest(amo, [room1, room17, room5])
 **Call:[room1, room17, room5]=[_16056|_16058]**
 Exit:[room1, room17, room5]=[room1, room17, room5]
 Call:room1\=room5
 Exit:room1\=room5
 Call:iterativefree(room5, _16144)
 Exit:iterativefree(room5, [])
 Exit:free(room5)
true

Таким образом, кажется, что в выделенном вызове программа не связывает [room17, room5] с T. Почему? это происходит? Спасибо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...