Идея состоит в том, что у меня есть несколько комнат в отеле, которые я могу связать с гостями.
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. Почему? это происходит? Спасибо.