Примечание. В вопросе о бинарном дереве есть ошибки с кодом OP.Вопрос заключался в том, чтобы прочитать код Пролога, а не исправить код.
Процедурное чтение на основе Братко , Раздел 9.3 Insertion and deletion in a binary tree
стр.231
T
- это двоичное дерево.Дерево может быть пустым, иметь только корень, один лист или два листа.
insert(Key, null, tree(key, null, null)).
Процедурное чтение:
Результат вставки Key
в пустое дерево null
- это дерево tree(key,null,null)
.
insert(Key, tree(Root, LST, RST), tree(Root, NewLST, RST)) :-
Key < Root,
insert(Key, LST, NewLST).
Процедурное чтение:
Если корень T
больше Key
, вставьте Key
в левое поддерево T
.
insert(Key, tree(Root, LST, RST), tree(Root, LST, NewRST)) :-
Key > Root,
insert(Key, RST, NewRST).
Процедурное чтение:
Если корень T
меньше Key
, вставьте Key
в правое поддерево T
.
Декларативное чтение на основе Искусство Пролога , Раздел 3.4 Binary Trees
стр.72
Декларативное чтение:
Key
может быть вставлено в нулевое дерево - или если его можно вставить в левое поддерево, если
Key
меньше значения в узле - или если его можно вставить в правое поддерево, если
Key
больше значения в узле.
Персональныйпримечание о том, почему написание декларативного значения важно.
При попытке понять процедурное значение, для меня это объясняет, как код работает в процедурном режиме, где устанавливаются входные параметры и возвращается значение.
?- insert(5,null,Tree).
Tree = tree(5, null, null) ;
false.
Примечание: я исправил ошибку с кодом OP, чтобы этот запрос работал как показано.
или
?- insert(3,tree(5,null,null),Tree).
Tree = tree(5, tree(3, null, null), null) ;
false.
При попытке понять декларативное значение,для меня это объясняет, как код работает в других режимах , где дается результат, и один или несколько параметров являются переменными, или все параметры являются переменными (не могу вспомнить, как это называется, ядумаю, что этосамый общий вопрос).
В этом случае при написании декларативного значения и при попытках запросов типа
?- insert(Key,X,tree(5,null,null)).
Key = 5,
X = null ;
ERROR: Arguments are not sufficiently instantiated
ERROR: In:
ERROR: [9] _8894<5
ERROR: [8] insert(_8920,tree(5,_8930,null),tree(5,null,null)) at c:/users/eric/documents/projects/prolog/so_question_101.pl:6
ERROR: [7] <user>
Exception: (8) insert(_8238, _8240, tree(5, null, null)) ? creep
и
?- insert(Key,Tree,tree(Root,Left,Right)).
Key = Root,
Tree = Left, Left = Right, Right = null ;
ERROR: Arguments are not sufficiently instantiated
ERROR: In:
ERROR: [9] _12488<_12490
ERROR: [8] insert(_12514,tree(_12522,_12524,_12526),tree(_12530,_12532,_12534)) at c:/users/eric/documents/projects/prolog/so_question_101.pl:6
ERROR: [7] <user>
% Execution Aborted
мне сообщают, что один или несколько изк ним необходимо обратиться:
- Для предиката необходимо определить режимы
- Необходимо добавить операторы Guard, чтобы избежать ошибок
- Требуется имя предикатадолжно быть изменено с процедурного на декларативное.
- Необходимо сделать код pure
- Необходимо изменить средства оценки, например, используя программирование ограничений или что-то еще.
Таким образом, изучая, как добавлять режимы в код для перехода от процедурного к декларативному, можно также посмотреть, как это может помочь в написаниилучший код на процедурных языках.
Когда я пишу код для языков программирования, которые не имеют алгебраических типов данных как понятие первого класса , такое как Java, я должен использоватьмного if
или switch
операторы для охвата всех комбинаций структуры данных.Теперь есть случаи, когда код работает правильно без else
или default
, но чтобы сделать код лучше, когда я пишу if
или switch
, я всегда добавляю else
или default
с помощью assert (false)
и запустите код.Если утверждение не выполняется, это, как правило, указывает на то, что мои рассуждения о коде были неверными, и я либо переписываю код, либо заменяю утверждение комментарием, объясняющим, почему может возникнуть случай else
или default
, но он не нужен.