Prolog中对事实和谓词的程序和声明性解读

问题描述 投票:1回答:1

我不确定如何进行事实和谓词的程序性和陈述性阅读。我想知道是否有人能给我一些如何写它们的指导。

这是我将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).
prolog
1个回答
2
投票

注意:二叉树的问题中存在OP代码的错误。问题是阅读Prolog代码而不是修复代码。

程序性阅读基于Bratko,第9.3节Insertion and deletion in a binary tree pg。 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).

Proceduralreading: 如果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 pg。 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或其他东西。

因此,通过学习如何将代码模式添加到从过程到声明的代码,人们也可以反过来看,这有助于在过程语言中编写更好的代码。

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

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.