• Learn Prolog Now 翻译


    练习题3.1

     在之前的章节中,我们已经讨论了如下的谓词逻辑:

      descend(X, Y) :- child(X, Y).

      descend(X, Y) :- child(X, Z), descend(Z, Y).

     假设我们将谓词逻辑重构如下:

      descend(X, Y) :- child(X, Y).

      descend(X, Y) :- descend(X, Z), descend(Z, Y).

     这会导致问题吗?

     我的答案:

     1. 这个谓词逻辑是有问题的,因为规则2中存在左递归的情况,即规则2的主干部分的第一个目标,和规则2的头部是相同的函子;

     2. 但是由于规则1是一个非递归的谓词逻辑,所以在进行一些查询时,能够根据这个规则进行终止,从而得出结果,比如:

      ?- descend(anne, bridget).

      Prolog会回答true;

      ?- descend(anne, emily).

      Prolog会回答true;

     3. 但是在问一些不能由规则1终止的问题时,Prolog会报"Out of local stack"的错误,代表递归不能终止,比如:

      ?- descend(bridget, anne).

      ?- descend(anne, X); 一直使用“;”寻找下一个答案,也会报错

    练习题3.2 

     知道俄罗斯木偶(又称为俄罗斯套娃娃)吗?其中较大的娃娃会包含较小的娃娃,如下图所示:

      首先,写出一个使用谓词逻辑directlyIn/2的知识库,表示木偶直接被另外一个木偶包含。其次,定义一个递归的谓词逻辑in/2,告诉某个木偶是否被另外一个木偶包含

    (直接或者间接)。比如,如果查询in(katarina, natasha),应该回答true,但是in(olga, katarina)应该回答false。

     我的答案:

    directlyIn(katarina, olga).
    directlyIn(olga, natasha).
    directlyIn(natasha, irina).
    
    in(X, Y) :- directlyIn(X, Y).
    in(X, Y) :- directlyIn(X, Z), in(Z, Y).

    练习题3.3

     有如下的知识库:

    directTrain(saarbruecken, dudweiler).
    directTrain(forbach, saarbruecken).
    directTrain(freyming, forbach).
    directTrain(stAvold, freyming).
    directTrain(fahlquemont, stAvold).
    directTrain(metz, fahlquemont).
    directTrain(nancy, metz).

     即,这个知识库记录了可以直接连通到城镇。但是,我们可以通过连接不同的城镇去旅行到更远的地方。请写一个谓词逻辑travelFromTo/2,可以告诉我们如何在这些

    城镇之间通行。比如,如果查询:

     ?- travelFromTo(nancy, saarbruecken).

     Prolog会回答true。

     我的答案:

    travelFromTo(X, Y) :- directTrain(X, Y).
    travelFromTo(X, Y) :- directTrain(X, Z), travelFromTo(Z, Y).

    练习题3.4

     定义一个谓词逻辑greater_than/2,有两个参数,使用本章中的数字表示方法(比如,numeral(0), numeral(succ(0)), numeral(succ(succ(0)))等),然后判断第一

    个参数是否大于第二个参数,比如:

     ?- greater_than(numeral(succ(succ(succ(0)))), numeral(succ(0))).

     Prolog会回答true;

     ?- greater_than(numeral(succ(succ(0))), numeral(succ(succ(succ(0))))).

     Prolog会回答false;

     我的答案:

    numeral(0).
    numeral(succ(X)) :- numeral(X).
    
    greater_than(numeral(X), numeral(0)) :- X = 0.
    greater_than(numeral(succ(X)), numeral(succ(Y))) :- 
        greater_than(numeral(X), numeral(Y))

    练习题3.5

     二叉树是每个内部节点严格有两个子节点的树形结构。一颗最小的二叉树仅由一个叶子节点构成。我们使用leaf(Label)代表叶子节点。比如,leaf(3)和leaf(7)都是

    叶子节点。假设两颗二叉树B1和B2能够通过谓词tree/2,合并称为一颗二叉树,如下:tree(B1, B2)。那么,从叶子节点开始,我们能够构建二叉树:tree(leaf(1),leaf(2)),

    类似地,从一颗二叉树tree(leaf(1),leaf(2))和叶子节点leaf(4),能够构建出新的二叉树:tree(tree(leaf(1),leaf(2)), leaf(4))。

     现在,请定义一个谓词逻辑swap/2,能够根据第一个参数的二叉树,构建第二个参数成为其镜像二叉树,比如:

     ?- swap(tree(tree(leaf(1),leaf(2)), leaf(4)), T).

     T = tree(leaf(4), tree(leaf(2),leaf(1))).

     true

     我的答案和解释,测试结果如下:

    tree(leaf(X), leaf(Y)) :- integer(X), integer(Y).
    tree(tree(X1, X2), leaf(Y)) :- tree(X1, X2), integer(Y).
    tree(leaf(Y), tree(X1, X2)) :- integer(Y), tree(X1, X2).
    tree(tree(X1, X2), tree(Y1, Y2)) :- tree(X1, X2), tree(Y1, Y2).
    
    swap(tree(leaf(X1), leaf(X2)), tree(leaf(X2), leaf(X1))) :-
        integer(X1), integer(X2).
    swap(tree(Tree1, leaf(X1)), tree(leaf(X1), Tree2)) :- 
        integer(X1), swap(Tree1, Tree2).
    swap(tree(leaf(X1), Tree1), tree(Tree2, leaf(X1))) :-
        integer(X1), swap(Tree1, Tree2).
    swap(tree(Tree1, Tree2), tree(Tree3, Tree4)) :- 
        swap(Tree1, Tree4), swap(Tree2, Tree3).

     一些说明:

     1. integer/1谓词逻辑用于检查参数是否是一个整数;

     2. tree/2谓词逻辑定义了二叉树的逻辑,分为四个子句:子句1定义了两个节点都是叶子节点的基础逻辑;子句2定义了左节点是二叉树,右节点是叶子节点的递归逻辑;

       子句3定义了左节点是叶子节点,右节点是二叉树的递归逻辑;子句4定义了两个子节点都是二叉树的递归逻辑;

     3. swap/2谓词逻辑定义了二叉树镜像实现,方式类似于tree/2的定义。

     4. 下面是一些测试和结果: 

       ?- swap(tree(leaf(1), leaf(2)), T).

       T = tree(leaf(2), leaf(1)) .

       ?- swap(tree(tree(leaf(1), leaf(2)), leaf(4)), T).
       T = tree(leaf(4), tree(leaf(2), leaf(1))) .

       ?- swap(tree(leaf(4), tree(leaf(1), leaf(2))), T).
       T = tree(tree(leaf(2), leaf(1)), leaf(4)) .

       ?- swap(tree(tree(leaf(1), leaf(2)), tree(leaf(3), leaf(4))), T).
       T = tree(tree(leaf(4), leaf(3)), tree(leaf(2), leaf(1))) .

     

  • 相关阅读:
    MacOS上传文件到windows ftp时软链接文件不见了
    gerrit的使用以及问题总结_gerrit权限和配置
    解决txt乱码:将windows新建txt转换成utf-8格式
    error: exportArchive: The data couldn’t be read because it isn’t in the correct format.
    linux 环境下 apache tomcat 安装jenkins
    ln -s软链接文件算文件吗
    msbuild 编译指定工程时构建脚本的配置
    输入参数的默认值设定${3:-var_d}
    windows下复制文件报错“文件名对目标文件夹可能过长 。您可以缩短文件名并重试,或者......”
    怪物AI之发现玩家(视觉范围发现系列)
  • 原文地址:https://www.cnblogs.com/seaman-h-zhang/p/4627800.html
Copyright © 2020-2023  润新知