Зеркальное двоичное дерево в Прологе - PullRequest
0 голосов
/ 28 ноября 2018

Что у меня есть ...

tree(nil).
tree(b(Left,_,Right)) :-
    tree(Left),
    tree(Right).

mirror(b(Left,Head,Right), NewTree) :-
    mirror(Left,NewLeft),
    mirror(Right,NewRight),
    NewTree = b(NewRight,Head,NewLeft).

Что я запрашиваю ...

mirror(b(nil,a,b(nil,b,nil)), Result).

Ожидаемый результат

Result = b(b(nil,b,nil),a,nil).

Дерево b (Слева, справа, голова) является первым аргументом зеркала, цель - NewTree.mirror (Left, NewLeft) проходит через левую сторону и дает цель NewLeft, то же самое для Right.NewTree - это дерево b (NewRight, Head, NewLeft).

Я не уверен, почему это не работает, может кто-нибудь помочь.

1 Ответ

0 голосов
/ 28 ноября 2018

Исходя из вашего текущего кода

tree(nil).
tree(b(Left,_,Right)) :-
    tree(Left),
    tree(Right).

mirror(b(Left,Head,Right), NewTree) :-
    mirror(Left,NewLeft),
    mirror(Right,NewRight),
    NewTree = b(NewRight,Head,NewLeft).

вы очень близки.

Как отмечено в комментарии Стивена

Вам не хватает базычехол для зеркала / 2.Каким должен быть NewTree, когда дерево ввода равно nil?

очень полезно.

Прежде чем перейти к полному рабочему предикату, давайте разберемся с другими вещами.
Предикат длядерево не нужно.

tree(nil).
tree(b(Left,_,Right)) :-
    tree(Left),
    tree(Right).

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

Это оставляет только

mirror(b(Left,Head,Right), NewTree) :-
    mirror(Left,NewLeft),
    mirror(Right,NewRight),
    NewTree = b(NewRight,Head,NewLeft).

Стандартный стиль с использованием переменной, которая работает как ввод и вывод с несколькими использованиями, - для начального, добавьте 0, затем для каждого последующего использования.увеличьте добавленное число и ничего не добавьте к результату.

mirror(b(Left0,Head,Right0), NewTree) :-
    mirror(Left0,Left),
    mirror(Right0,Right),
    NewTree = b(Right,Head,Left).

Далее = / 2 просто выполняет объединение.Это может быть изменено как таковое

mirror(b(Left0,Head,Right0), b(Right,Head,Left)) :-
    mirror(Left0,Left),
    mirror(Right0,Right).

Теперь вернемся к вашей проблеме

Поскольку дерево является рекурсивной структурой, его можно обрабатывать с помощью рекурсии.Предикаты, которые работают с рекурсивными структурами данных, нуждаются в базовом предложении и предложении для выполнения рекурсии.У вас уже есть предложение для выполнения рекурсии, но вам просто нужно базовое предложение.

Если вы используете графический интерфейс SWI-Prolog в своем коде для запроса

mirror(b(nil,a,b(nil,b,nil)), Result).

, вы увидите

enter image description here

, что когда одна из ветвей просто nil, то нет никакого правила зеркала / 2 для обработки этого случая.

Добавление

mirror(nil,nil).

решит вашу проблему.

?- mirror(b(nil,a,b(nil,b,nil)), Result).
Result = b(b(nil, b, nil), a, nil).

Весь предикат.

mirror(nil,nil).

mirror(b(Left0,Head,Right0), b(Right,Head,Left)) :-
    mirror(Left0,Left),
    mirror(Right0,Right).
...