• prolog 内部谓词


    内部谓词

    和其他语言一样,prolog也提供一些基本的输入输出函数。

    内部谓词是指已经在prolog中事先定义好的谓词,在内存中的动态数据库中是没有内部谓词子句的。(当我们运行某个.pl 文件的时候,该文件的内容会加载到内存中。所以内存中会有文件中的谓词子句),当解释器遇到内部谓词的目标,它就直接调用事先定义好的程序。

    内部谓词一般所完成的工作和逻辑无关,所以这些文词也叫做非逻辑谓词。虽然如此,但这些谓词也可以所谓prolog的目标,所以他们也有四个端口:call exit redo  fail

    常用的输出谓词

    write/1   %谓词名为 ‘write’  参数数量为 1 个
    
    1 ?- write('hello world').
    hello world
    true.

    此谓词被调用是永远成功,它把它的参数作为字符串输出到屏幕上

    当回溯时,它永远失败,所以,回溯不会吧已经输出到屏幕上的字符删掉

    nl/0
    
    
    ?- nl
    .
    true.

    此谓词没有参数,它的作用的在屏幕上输出一个回车符。

    和write一样,从call端口嗲用时永远成功,但是回溯时总是失败。

    tab/1
    
    
    ?- write('hello'),tab(10),write('world').
    hello          world
    true.

    此谓词有一个参数,该谓词的作用是在屏幕上输出n个空格 n=参数值

    其控制流程和write nl一样

    fail/0
    
    ?- fail.
    false.

    该谓词没有参数,他的调用永远失败,从而引起回溯。

    以前我们靠“;”来释放已经绑定的变量,进入目标的redo端口,变量的输出靠解释器完成,现在我们可以使用I/O谓词来显示变量。靠fail来引起自动回溯。

    1 ?- location(X,kitchen),write(X),nl,fail.
    apple
    broccoli
    crackers
    false.

     该目标的运行流程如下:

     SWI-Prolog的debug信息如下:

    ?- location(X,kitchen),write(X),nl,fail.
     T Call: (8) location(_G263, kitchen)
     T Exit: (8) location(apple, kitchen)
     T Call: (8) write(apple)
    apple
     T Exit: (8) write(apple)
     T Call: (8) nl
    
     T Exit: (8) nl
     T Call: (8) fail
     T Fail: (8) fail
     T Redo: (8) location(_G263, kitchen)
     T Exit: (8) location(broccoli, kitchen)
     T Call: (8) write(broccoli)
    broccoli
     T Exit: (8) write(broccoli)
     T Call: (8) nl
    
     T Exit: (8) nl
     T Call: (8) fail
     T Fail: (8) fail
     T Redo: (8) location(_G263, kitchen)
     T Exit: (8) location(crackers, kitchen)
     T Call: (8) write(crackers)
    crackers
     T Exit: (8) write(crackers)
     T Call: (8) nl
    
     T Exit: (8) nl
     T Call: (8) fail
     T Fail: (8) fail
    false.

     我觉得教程中的debug信息更好,摘录如下:

    localtion(X,kitchen),write(X),nl,fail.
    
    call location(X,kitchen)
    exit(2) location(apple,kitchen)
    call write(apple)
    apple
    exit write(apple)
    call nl   %调用内部谓词  nl,会在屏幕上输出空格
    
    exit nl
    call fail
    fail fail   %fail 失败会引起自动回溯
    redo nl     %回溯到上一次成功匹配的子句,重新开始在该子句后面查找。I/O谓词应该就是重新运行
    fail nl
    redo write(apple)
    fail write(apple)
    redo location(X,kitchen)
    exit(6) location(broccoli,kitchen)
    call  write(broccoli)
    broccoli
    exit  write(broccoli)
    call nl
    
    exit nl
    call fail
    fail fail
    redo nl
    fail nl
    redo write(broccoli)
    fail write(broccoli)
    redo kitchen(X,kitchen)
    exit(7) kitchen(crackers,kitchen)
    call write(crackers)
    crackers
    exit write(crackers)
    call nl
    
    exit nl
    call fail
    fail fail
    redo nl
    fail nl
    redo write(crackers)
    fail write(crackers)
    redo location(X,kitchen)
    fail location(X,kitchen)
    no

    那么如下子句执行的结果是什么呢?以及它的流程是如何进行的呢?

    ?- door(kitchen,R),write(R),nl,location(T,R),tab(3),write(T),nl,fail.
    ?- door(kitchen,R),write(R),nl,location(T,R),tab(3),write(T),nl,fail.
    office
       desk
       computer
    cellar
       washing mechine
    
    
    %该结果中没有体现出 nl 这个内置谓词运行的结果——即没有回车符,但是在下面的debug信息中,却显示着,nl确实执行过。

    如下为使用SWI-prolog的debug信息

    2 ?- door(kitchen,R),write(R),nl,location(T,R),tab(3),write(T),nl,fail.
     T Call: (8) door(kitchen, _G438)
     T Exit: (8) door(kitchen, office)
     T Call: (8) write(office)
    office
     T Exit: (8) write(office)
     T Call: (8) nl
    
     T Exit: (8) nl
     T Call: (8) location(_G442, office)
     T Exit: (8) location(desk, office)
     T Call: (8) tab(3)
       
     T Exit: (8) tab(3)
     T Call: (8) write(desk)
    desk
     T Exit: (8) write(desk)
     T Call: (8) nl
    
     T Exit: (8) nl
     T Call: (8) fail
     T Fail: (8) fail
     T Redo: (8) location(_G442, office)
     T Exit: (8) location(computer, office)
     T Call: (8) tab(3)
       
     T Exit: (8) tab(3)
     T Call: (8) write(computer)
    computer
     T Exit: (8) write(computer)
     T Call: (8) nl
    
     T Exit: (8) nl
     T Call: (8) fail
     T Fail: (8) fail
     T Redo: (8) door(kitchen, _G438)
     T Exit: (8) door(kitchen, cellar)
     T Call: (8) write(cellar)
    cellar
     T Exit: (8) write(cellar)
     T Call: (8) nl
    
     T Exit: (8) nl
     T Call: (8) location(_G442, cellar)
     T Exit: (8) location('washing mechine', cellar)
     T Call: (8) tab(3)
       
     T Exit: (8) tab(3)
     T Call: (8) write('washing mechine')
    washing mechine
     T Exit: (8) write('washing mechine')
     T Call: (8) nl
    
     T Exit: (8) nl
     T Call: (8) fail
     T Fail: (8) fail
    false.

    同样,我觉得SWI-prolog的debug信息不是很好,所以我就按照前几次的逻辑,自己写了下面这个debug信息(如有错误,请指出)

    goal  door(kitchen,R),write(R),nl,location(T,R),tab(3),write(T),nl,fail.
    
    call door(kitchen,R)
    exit(3) door(kitchen,office)
    call write(office)
    office
    exit write(office)
    call nl
    
    exit nl
    call location(T,office)
    exit(2) location(desk,office)
    call tab(3)
        exit tab(3)
    call write(desk)
       desk
    exit write(desk)
    call nl
       
    exit nl
    call fail
    fail fail
    redo nl
    fail nl
    redo write(desk)
    fail write(desk)
    redo tab(3)
    fail tab(3)
    redo location(T,office)
    exit(5) location(computer,office)
    call tab(3)
        exit tab(3)
    call write(computer)
        computer
    exit write(computer)
    call nl
    
    exit nl
    call fail
    fail fail
    redo nl
    fail nl
    redo write(computer)
    fail write(computer)
    redo tab(3)
    fail tab(3)
    redo location(T,office)
    fail location(T,office)
    redo nl
    fail nl
    redo write(office)
    fail write(office)
    redo door(kitchen,R)
    exit(6) door(kitchen,cellar)
    call write(cellar)
    cellar
    exit write(cellar)
    call nl
    
    exit nl
    call location(T,cellar)
    exit(9) location('washing mechine',cellar)
    call tab(3)
       exit tab(3)
    call write('washing mechine')
        washing mechine
    exit write('washing mechine')
    call nl
    
    exit nl
    call fail
    fail fail
    redo nl
    fail nl
    redo write('washing meching')
    fail write('washing meching')
    redo tab(3)
    fail tab(3)
    redo location(T,cellar)
    fail location(T,cellar)
    redo nl
    fail nl
    redo write(cellar)
    fail write(cellar)
    redo door(kitchen,R)
    fail door(kitchen,R)
    no
      

     其他内部谓词:

    比较类:

    1、 = 
       等于    绑定变量
    2、  = 
        不等于
    3、 >, <
        大于,小于
    4、>= ,=< 
        大于等于, 小于等于
    5、 ==
        强等于
    1 ?- 1 = 1.
    true.
    
    2 ?- X = 1.
    X = 1.
    
    3 ?- 1>1.
    false.
    
    4 ?- 1<2.
    true.
    
    5 ?- 1>=1.
    true.
    
    6 ?- 1 == 1.
    true.

    表达式类

    1is
        X is Y , Y可以被实例化为表达式,该谓词先对Y 求值,得到一个整数,如X未实例化,
      则X 实例化为这一结果,且目标成功,否则,如X 已经实例化,那么 is 退化为 = 来判断成功与否 2 、+ 加法运算 3、 — 减法运算 4、* 乘法运算 5、/ 除法运算 6. mod 取模运算 优先级: +—(正负号),mod,*/, +—(加、减)
    ?- X is 4.
    X = 4.
    
    ?- S is 4+1.
    S = 5.
  • 相关阅读:
    js实现element中可清空的输入框(1)
    vue中v-model的学习
    Oracle触发器和MySQL触发器的简单应用
    Java中的多线程你只要看这一篇就够了()
    HTML 随笔记之 刷新页面
    HTML CSS 随笔记之 cursor
    float到底是干什么的?
    Spring Boot 事物的快速应用
    java web 中文乱码
    LVM 创建实例
  • 原文地址:https://www.cnblogs.com/jijizhazha/p/6204333.html
Copyright © 2020-2023  润新知