我真的不知道如何进行事实和谓词的过程性和声明性阅读。我想知道是否有人能给我一些关于如何写它们的指导。
以下是我将Key
插入二进制树的代码:
insert(Key, null, tree(key, null, null)).
insert(Key, tree(Root, LST, RST), tree(Root, NewLST, RST)) :-
Key < Root,
insert(Key, LST, NewLST).
insert(Key, tree(Root, LST, RST), tree(Root, LST, NewRST)) :-
Key > Root,
insert(Key, RST, NewRST).
注意:关于二进制树的问题中存在OP代码错误。问题是阅读Prolog代码,而不是修复代码。
基于Bratko的程序性阅读,第9.3节Insertion and deletion in a binary tree
第231页
CCD_ 3是一个二叉树。一棵树可以是空的,只有一个根,有一片叶子,或者有两片叶子。
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
的右子树中。
基于Prolog艺术的声明性阅读,第3.4节Binary Trees
第72页
声明性读数:
Key
可以插入到空树中- 或者如果CCD_ 17小于节点处的值,则它是否可以插入到左子树中
- 或者如果CCD_ 18大于节点处的值
关于为什么写陈述意义很重要的个人说明。
在试图理解过程意义时,对我来说,它解释了代码如何在过程模式下工作,在该模式下设置输入参数并返回值。
?- insert(5,null,Tree).
Tree = tree(5, null, null) ;
false.
注意:我修复了OP代码中的一个错误,使该查询以demonstarted的方式工作。
或
?- 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
告诉我,其中一个或多个需要解决:
- 需要为谓词定义模式
- 需要添加保护语句以避免错误
- 谓词名称需要从过程性更改为声明性
- 代码需要变得纯净
- 评估方法需要改变,例如使用约束编程或其他方法
因此,通过学习如何将模式添加到代码中,使其从过程性变为声明性,我们还可以反过来看待如何帮助用过程性语言编写更好的代码。
当我为没有代数数据类型作为第一类概念的编程语言(如Java(编写代码时,我必须使用许多if
或switch
语句来覆盖数据结构的所有组合。现在,有些情况下,代码在没有else
或default
的情况下可以正确运行,但在编写if
或switch
时,为了使代码更好,我总是将else
或default
与assert (false)
一起添加,然后运行代码。如果断言失败,通常表明我对代码的推理是错误的,我要么重写代码,要么将断言更改为注释,解释为什么else
或default
情况可以发生,但不需要。