Пролог - объяснение шагов трассировки на английском языке
plays(alice, leadguitar).
plays(noah, drums).
plays(mike, leadguitar).
plays(mike, drums).
plays(katie, baseguitar).
plays(drew, leadguitar).
plays(drew, baseguitar).
duetwith(Person1,Person2):-
plays(Person1,L),
plays(Person2,L),
Person1 \= Person2.
Я пишу новое правило, называемое комбо, которое определяет, могут ли три человека сделать комбо с барабанщиком, базовой гитарой и ведущей гитарой.
combo(Person1,Person2,Person3):-
plays(Person1,X),
plays(Person2,Y),
plays(Person3,Z),
X \= Y,
Y \= Z,
X\=Z.
Может Дрю, Алиса и Майк сделать комбо?
combo(mike,alice,drew).
так что ответ да, они могут сделать комбо.
Мне нужна помощь в понимании шагов, которые программа выполняет для ответа на вышеуказанный запрос в прологе. Любая помощь со списком шагов очень ценится, так что я могу получить более глубокое понимание каждого шага, который делает Пролог.
Вот пример списка шагов, которые Пролог предпринимает для другого примера, просто чтобы дать представление о том, что я ищу.
В случае talkswith(bob,allen)
Двигатель предпринял следующие шаги:
В
разговаривает с (Person1,Person2):- говорит (Person1,L), говорит (Person2,L), Person1 \= Person2.
заменить каждое вхождение Person1
с bob
а также Person2
с allen
получить
talkswith(bob,allen) :-
speaks(bob,L),
speaks(allen,L),
bob \= allen.
Давайте посмотрим, сможем ли мы найти значение для L, которое делает правую часть истинной. Начать с
speaks(bob,L).
Что может быть L? Вот наши факты:- говорит (аллен, русский).
- говорит (боб, английский).
- говорит (Мария, русский).
- говорит (мэри, английский).
На самом деле 1, первый слот не боб, так что это не сработает. На самом деле 2, первый слот это Боб, так что давайте попробуем
L = english
вspeaks(allen,L), bob \= allen.
Теперь мы спрашиваемspeaks(allen,english), bob\= allen.
- Вернуться к базе знаний. Есть ли
speaks(allen,english)
соответствовать факту? Не факт 1, не факт 2, не факт 3, не факт 4. Это терпит неудачу. - Теперь вернемся к шагу 2. Факт 2 не сработал, поэтому давайте попробуем факт 3. Нет, это не Боб. Факт 4 тоже не боб. Мы не можем найти значение для L, которое работает, поэтому поиск не удался.
1 ответ
заменить каждый случай Person1 с Бобом
Пролог использует синтаксическое объединение, которое никогда не делает замену. Свободная переменная может быть привязана только один раз к значению. Если похоже, что переменная изменяется несколько раз, это не так. Может быть много стековых фреймов, и для каждого стекового фрейма может быть создан новый набор переменных.
Трассировка несколько полезна, но мне нужно перевести это в форму примера выше с шагами, написанными и объясненными на простом английском языке.
За эти факты
plays(alice, leadguitar).
plays(noah, drums).
plays(mike, leadguitar).
plays(mike, drums).
plays(katie, baseguitar).
plays(drew, leadguitar).
plays(drew, baseguitar).
и этот предикат
combo(Person1,Person2,Person3):-
plays(Person1,X),
plays(Person2,Y),
plays(Person3,Z),
X \= Y,
Y \= Z,
X\=Z.
и этот запрос
combo(mike,alice,drew).
Сначала прочтите программы отладки и трассировки SWI-Prolog
Запустите запрос с трассировкой, включите унифицированный порт и отключите его.
?- visible(+unify).
true.
?- leash(-all).
true.
?- trace.
true.
[trace] ?- combo(mike,alice,drew).
Call: (8) combo(mike, alice, drew)
Unify: (8) combo(mike, alice, drew)
Call: (9) plays(mike, _7040)
Unify: (9) plays(mike, leadguitar)
Exit: (9) plays(mike, leadguitar)
Call: (9) plays(alice, _7040)
Unify: (9) plays(alice, leadguitar)
Exit: (9) plays(alice, leadguitar)
Call: (9) plays(drew, _7040)
Unify: (9) plays(drew, leadguitar)
Exit: (9) plays(drew, leadguitar)
Call: (9) leadguitar\=leadguitar
Fail: (9) leadguitar\=leadguitar
Redo: (9) plays(drew, _7040)
Unify: (9) plays(drew, baseguitar)
Exit: (9) plays(drew, baseguitar)
Call: (9) leadguitar\=leadguitar
Fail: (9) leadguitar\=leadguitar
Redo: (9) plays(mike, _7040)
Unify: (9) plays(mike, drums)
Exit: (9) plays(mike, drums)
Call: (9) plays(alice, _7040)
Unify: (9) plays(alice, leadguitar)
Exit: (9) plays(alice, leadguitar)
Call: (9) plays(drew, _7040)
Unify: (9) plays(drew, leadguitar)
Exit: (9) plays(drew, leadguitar)
Call: (9) drums\=leadguitar
Exit: (9) drums\=leadguitar
Call: (9) leadguitar\=leadguitar
Fail: (9) leadguitar\=leadguitar
Redo: (9) plays(drew, _7040)
Unify: (9) plays(drew, baseguitar)
Exit: (9) plays(drew, baseguitar)
Call: (9) drums\=leadguitar
Exit: (9) drums\=leadguitar
Call: (9) leadguitar\=baseguitar
Exit: (9) leadguitar\=baseguitar
Call: (9) drums\=baseguitar
Exit: (9) drums\=baseguitar
Exit: (8) combo(mike, alice, drew)
true.
Call: (8) combo(mike, alice, drew)
Пролог ищет предикат, соответствующий запросу. Когда Пролог ищет предикат, он ищет по имени предиката, в данном случае combo
и arity, в этом случае 3
и находит только один предикат с одним предложением. Пролог также ищет предикаты в порядке их появления в исходном коде. Это еще не все (индексация), но этот уровень детализации не нужен для объяснения этого простого запроса.
Unify: (8) combo(mike, alice, drew)
Как только Prolog обнаружил предложение / факт на основе имени и арности предиката, он проверяет, можно ли объединить запрос и заголовок предложения или факта.
mike
объединяется с Person1
, Person1
теперь обязан mike
,alice
объединяется с Person2
, Person2
теперь обязан alice
,drew
объединяется с Person3
, Person3
теперь обязан drew
,
Call: (9) plays(mike, _7040)
Если предыдущий оператор объединяется, то вызывается следующий оператор. Каждое утверждение представляет собой запрос сам по себе. Итак, запустив запрос plays(mike,X).
как отдельный запрос такой же, как этот оператор в предложении. Есть много фактов для plays/2
и два из них совпадают plays(mike,X).
Пролог использует первое, что находит, однако, поскольку их больше одного, делается выбор. Мы назовем эту конкретную точку выбора plays(mike,X) - cp1
и возвращать конкретную точку выбора, когда встречается соответствующий REDO.
Unify: (9) plays(mike, leadguitar)
Как только Prolog обнаружил предложение / факт, основанный на имени и арности предиката, он проверяет, что запрос и заголовок предложения могут быть объединены.
plays
объединяется с plays
mike
объединяется с mike
_7040
объединяется с leadguitar
, _7040
связан с leadguitar
,
Exit: (9) plays(mike, leadguitar)
Это только завершение портов модели коробки Пролог. Это показывает результат Call: (9) plays(mike, _7040)
, Никакого объединения не происходит для этого утверждения.
Call: (9) plays(alice, _7040)
Unify: (9) plays(alice, leadguitar)
Exit: (9) plays(alice, leadguitar)
Тот же шаблон для alice
, У Алисы есть только один факт, поэтому для нее не созданы очки выбора.
Call: (9) plays(drew, _7040)
Unify: (9) plays(drew, leadguitar)
Exit: (9) plays(drew, leadguitar)
Тот же шаблон для drew
, Так как у Дрю есть два факта для plays(drew,X).
точка выбора генерируется. plays(drew,X) - cp1
Call: (9) leadguitar\=leadguitar
Это четвертое утверждение X \= Y
с X
связан с leadguitar
а также Y
связан с leadguitar
Fail: (9) leadguitar\=leadguitar
поскольку leadguitar
не отличается от leadguitar
этот запрос не выполняется В случае неудачи Пролог возвращается к последней точке выбора (Повторить) и пытается найти другое решение.
Redo: (9) plays(drew, _7040)
Помните последнюю созданную точку выбора, plays(drew,X) - cp1
, Так как что-то не удалось, запрос пытается найти другое возможное решение. Так как первая точка выбора для plays(drew,X)
не удалось с X
являющийся leadguitar
, второй факт используется, plays(drew,baseguitar).
Unify: (9) plays(drew, baseguitar)
Просто показывает, что второй факт для plays(drew,X)
используется.
Exit: (9) plays(drew, baseguitar)
Это показывает результат Redo: (9) plays(drew, _7040)
,
Остальная часть - это просто копирование / вставка того, что уже сделано, и изменение операторов, переменных, связанных значений и т. Д.
Этот ответ похож, но имеет больше деталей.
Следует отметить этот вопрос
Я пишу новое правило, называемое комбо, которое определяет, могут ли три человека сделать комбо с барабанщиком, базовой гитарой и ведущей гитарой.
не отвечает на этот запрос
combo(Person1,Person2,Person3):-
plays(Person1,X),
plays(Person2,Y),
plays(Person3,Z),
X \= Y,
Y \= Z,
X\=Z.
потому что, если эти факты добавляются
plays(alice, flute).
plays(noah, cello).
plays(mike, trumpet).
этот запрос
?- combo(alice,noah,mike).
true ;
true .
говорит правда, но alice
, noah
а также mike
не играют на свинцовой гитаре, барабанах и базовой гитаре.