Функции Prolog (например, история владения автомобилем)

edit: Я разобрался с одноэлементными переменными. Пролог не любит заглавные слова для банков данных. Я также внес несколько серьезных изменений в код.

edit: edit: понял, что у меня нет рекурсивного вызова. Дерп

Я новичок в Prolog, хотя у меня есть некоторый опыт функционального программирования на Haskell.

Хотя у меня возникают проблемы с попыткой заставить функцию выводить все возможные значения, которые делают утверждение истинным. Я не думаю, что это логическая ошибка, поскольку я проходил через это последние несколько часов, но могу ошибаться.

В этой задаче я пытаюсь создать историю владения автомобилем.

- Я знаю, что человек владеет автомобилем, ЕСЛИ -Он / Она купила машину у Дилера -Он / Она купила ее у предыдущего владельца машины.

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

car(prius).
car(bmw).

owner(meg).
owner(nora).
dealer(d).

boughtFrom(meg,nora).
boughtFrom(nora,d).

Установил, что мег куплен у нора, который покупал у дилера. Когда вы покупаете у дилера, рекурсия, которую я планирую, останавливается, поскольку это конечная точка базового случая. поэтому логика такая:

ownCar(X,Y) :- boughtFrom(X,d), car(Y).
ownCar(X,Y) :- ownCar(boughtFrom(_,prevowner(X)), car(Y)).

Вы можете быть владельцем автомобиля, если вы являетесь дилером или купили автомобиль у предыдущего владельца. и этот предыдущий владелец является владельцем, если они купили его либо у дилера, либо у другого предыдущего владельца. и т.п.


person Mark    schedule 16.03.2013    source источник


Ответы (1)


Я думаю, что ваша база данных неполная, потому что отсутствует какая-то очевидная связь.

Это правило, например, ownCar(X,Y) :- boughtFrom(X,d), car(Y). будет истинным для всех Y, то есть любой, кто купил у дилера, будет «владеть» каждой машиной.

Представление также неточное. Продавец не должен больше быть владельцем после того, как она продала автомобиль.

В любом случае, в Prolog вы пишете joins (это реляционная модель данных), чтобы затем получить закрытие транзитивного свойства:

ownCar(X, Y) :- owner(O), boughtFrom(X, O), ownCar(O, Y).

Обратите внимание, что в Prolog мы должны избегать левой рекурсии, потому что это может привести к бесконечному циклу, тогда порядок соединения важен.

редактировать

чтобы получить историю (в виде списка), вы должны добавить аргумент в свой предикат или изменить «вывод» на список. Вы могли бы сделать что-то вроде

ownCar(X, Y, [X]) :- boughtFrom(X,d), car(Y).
ownCar(X, Y, [X|L]) :- owner(O), boughtFrom(X, O), ownCar(O, Y, L).

Примечание: обычно в Прологе мы помещаем «выходные» аргументы в последнюю позицию аргумента.

person CapelliC    schedule 17.03.2013
comment
Спасибо за ответ и за уделенное время. Хорошо, я лучше понимаю рекурсивные проблемы. Но я пытаюсь добиться с помощью этой функции, чтобы отображались имена предыдущих владельцев. Итак, когда я ввожу ?- ownCar(X, Prius)., он выводит X = meg. X = nora. И сейчас я получаю только Мэг, потому что она является текущим владельцем. На самом деле я думаю, что функцию следует переименовать в carOwnerHist. - person Mark; 18.03.2013