在Prolog中对事实和谓语进行程序和声明式阅读

时间:2018-12-15 22:32:39

标签: 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).

1 个答案:

答案 0 :(得分:2)

注意:二叉树问题中存在OP代码错误。问题是为了读取Prolog代码,而不是代码的固定。

基于Bratko,第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的右子树中。


基于The Art of Prolog,第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.

在尝试理解声明性含义时,对我来说,它解释了代码在其他modes中如何工作,其中给出了结果并且一个或多个参数是变量,或者所有参数都是变量(可以我不记得这叫什么,我认为这是最普遍的问题。

在这种情况下,编写声明性含义并尝试查询

?- 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. 需要添加Guard语句以避免错误
  3. 谓词名称需要从过程性更改为声明性。
  4. 代码必须为pure
  5. 需要更改评估方式,例如使用constraint programming或其他方式。

因此,通过学习如何在代码中添加从程序性到声明性的模式,人们也可以从相反的角度看这如何帮助用程序语言编写更好的代码。

当我为Java等不具有algebraic data types作为first class notion的编程语言编写代码时,必须使用许多ifswitch语句来覆盖所有数据结构的组合。现在,有些情况下代码可以正确运行而没有elsedefault,但是为了使代码更好,当我编写ifswitch时,我总是添加{ {1}}或elsedefault并运行代码。如果断言失败,则通常表明我对代码的推论是错误的,并且我重写代码或将断言更改为注释,以说明为什么会发生assert (false)else情况,但并不需要