Prolog中事实和谓词的过程性和声明性阅读



我真的不知道如何进行事实和谓词的过程性和声明性阅读。我想知道是否有人能给我一些关于如何写它们的指导。

以下是我将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

告诉我,其中一个或多个需要解决:

  1. 需要为谓词定义模式
  2. 需要添加保护语句以避免错误
  3. 谓词名称需要从过程性更改为声明性
  4. 代码需要变得纯净
  5. 评估方法需要改变,例如使用约束编程或其他方法

因此,通过学习如何将模式添加到代码中,使其从过程性变为声明性,我们还可以反过来看待如何帮助用过程性语言编写更好的代码。

当我为没有代数数据类型作为第一类概念的编程语言(如Java(编写代码时,我必须使用许多ifswitch语句来覆盖数据结构的所有组合。现在,有些情况下,代码在没有elsedefault的情况下可以正确运行,但在编写ifswitch时,为了使代码更好,我总是将elsedefaultassert (false)一起添加,然后运行代码。如果断言失败,通常表明我对代码的推理是错误的,我要么重写代码,要么将断言更改为注释,解释为什么elsedefault情况可以发生,但不需要。

最新更新