zoukankan      html  css  js  c++  java
  • Visual Prolog 的 Web 专家系统 (6)

    保存用户响应询价。作为进一步推理的条件

    或GOAL段开始。最初的一句是write_startform()

    write_startform():-
            write("<form action="cgi-bingeni.exe"method="post">
    ").
    

    注意!上一句应为write("<form action="geni.exe"method="post"> ").

    GENI虚拟主机没有“cgi-bin”这个子文件夹。

    在GOAL中,紧跟上一句的是assert_conditions(ParmList1)

      assert_conditions([]):-!.
      assert_conditions([parm(Name,Val)|Rest]):-
    	concat("cond_",CondNumberStr,Name),
    	str_int(CondNumberStr,COND),
                   !,
    	assert_cond(COND,Val),
    	assert_conditions(Rest).
      assert_conditions([_Parm|Rest]):-!,
    	assert_conditions(Rest).
      assert_conditions(_):-
    	errorexit.
    

    Prolog没有C语言的for,while等处理循环的机制。

    本例,Prolog是用递归来实现“循环”。

    谓词assert_conditions的4个子句,表现了典型的、标准的递归应用。

    子句1,设置递归终止条件。
    终止条件是要处理的列表为空。

    子句2,处理列表头,即列表第1个成员。

    子句3。忽略要处理的列表头,继续处理剩余表尾。

    子句4,准备出错后的处理。


    子句4运行的前提条件是:

    1、子句1头部匹配不成功,或者。“截断”! 之前的语句失败。
    2、而且,子句2头部匹配不成功。

    详细是哪个语句失败,以及失败的原因。待以下分析。

    子句2和子句3,末尾的语句都是自身的递归调用。
    这就是尾递归。


    尾递归的优点。是能够无限递归下去,不会耗尽内存。

    看看子句1中的语句吧。

    concat("cond_",CondNumberStr,Name)

    它是内建谓词,流模式是(i, i, o), (o, i, i), (i, o, i), (i, i, i)
    用于连接2个字符串

    本例的流模式是 (i, o, i)。从变量名上看,CondNumberStr应该是数字

    所以。若Name="cond_3" ,则CondNumberStr=3

    这时,能够试试上一节的小伎俩:

    在VDE中。菜单File|New,出现一空白文件noname.pro。写入:

    goal
    concat("cond_",A,"cond_1").
    

    菜单Project|Test Goal。目标编译运行。结果:

    A=1
    1 Solution
    

    再看下一条语句

    str_int(CondNumberStr,COND)

    这是个内建谓词:str_int (STRING StringArg, INTEGER IntArg)
    流模式是(i, o), (o, i), (i, i) 
    用于字符串与整数的相互转换
    建议用上述小伎俩试一试
    

    这一句之后,便是截断"!"。由此可见,引起子句2回溯到子句3的条件是:

    1、变量Name不是以“Cond_”开头的字符串,或者,
    2、变量CondNumberStr不是数字字符串。

    这一回溯引起子句3的运行,结果是忽略当前处理对象,開始新的递归,
    处理列表中的后序对象。

    继续往下看:

    assert_cond(COND,Val)

      assert_cond(CNO,"yes"):-!,assert(yes(CNO)).
      assert_cond(CNO,"no"):-!,assert(no(CNO)).
      assert_cond(_CNO,"why"):-!,assert(whymeet).
      assert_cond(_,_):-errorexit.
    

    CNO是知识库里“条件”的标识号

    yes(CNO),no(CNO),保存在事实库tmp里。

    意思是:对第CNO号条件,回答了yes/no

    whymeet,也是保存在事实库tmp里,

    意思是:用户要求系统答复。为什么询问这一问题。

    最后一句,assert_conditions(Rest).

    递归处理列表的尾巴Rest。

    今天的重点是尾递归,也是Prolog一个主要特征。

    版权声明:本文博客原创文章。博客,未经同意,不得转载。

  • 相关阅读:
    九.Spring Boot JPAHibernateSpring Data
    JIRA安装过程中链接mysql的问题!
    五、案例-指令参考-freemarker指令、表达式
    四、模版指令操作
    三、freemarker数据、模版指令
    二、freemarker.controller半自动静态化+Tomcat虚拟资源映射
    一、springMVC、freemarker页面半自动静态化
    window窗口-button(按钮)-dialog(对话框,带按钮)
    panel面板
    python 给定年份、月份,返回当月对应天数
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/4656415.html
Copyright © 2011-2022 走看看