prolog 推导如何在此查询中工作?

如何解决prolog 推导如何在此查询中工作?

我尝试使用以下规则集编写一个简单的 Prolog 程序。

conc([],L,L).
conc([X|L1],L2,[X|L3]):- conc(L1,L3).

然后我将其加载到 SWI-Prolog shell 中并在跟踪模式下执行以下查询。

 ?-conc([2,3],[p,q],[2,3,p,q]).

输出如下。

[trace]  ?- conc([2,q]).
   Call: (8) conc([2,q]) ? creep
   Call: (9) conc([3],[3,q]) ? creep
   Call: (10) conc([],q]) ? creep
   Exit: (10) conc([],q]) ? creep
   Exit: (9) conc([3],q]) ? creep
   Exit: (8) conc([2,q]) ? creep
true.

现在的问题是绘制这个目标的派生树,但我无法完全理解 prolog 是如何做到这一点的,即使查看上面的 trace 输出也是如此。

有人能解释一下关于上述规则集的上述查询的派生树吗?非常感谢有用的答案。

解决方法

派生树如下(考虑带有重命名变量的子句):

enter image description here

,
?- conc([2,3],[p,q],[2,3,p,q]).

Call: (8) conc([2,q]) ? creep

当前的目标就是问题。

由于 [2,3][] 不匹配,规则 1 无选项,因此尝试规则 2。 为了匹配规则 2 的头部,进行了以下替换:X/2,L1/[3],L2/[p,L3/[3,q].

我们的新目标现在是规则 2 的主体 conc(L1,L2,L3),在上述替换之后,即 conc([3],[3,q])

Call: (9) conc([3],q]) ? creep

由于 [3][] 不匹配,规则 1 无选项,因此尝试规则 2。 替换:X/3,L1/[],L3/[p,q] 我们的新目标现在是在适当的解决方案之后 conc(L1,L3),相当于 conc([],q])

Call: (10) conc([],q]) ? creep

匹配规则 1 => 证明成功

因此,证明了目标 10 的待办事项列表,从而证明了目标 10:

Exit: (10) conc([],q]) ? creep

因此,证明了目标 9 的待办事项列表,从而证明了目标 9:

Exit: (9) conc([3],q]) ? creep

因此,证明了目标 8 的待办事项列表,从而证明了目标 8:

Exit: (8) conc([2,q]) ? creep

由于目标 8 是问题,我们已经完成,证明已经完成:

true.
,

我觉得使用跟踪器通常没有帮助,除非您已经知道自己在做什么并且知道在精确位置存在问题,即使这样也难以解开 混乱

最好仔细查看程序,并将其视为递归调用的定义(或者,作为归纳定义):

  1. 一个列表[]和其他一些列表L的串联是同一个列表L
    conc( [],L,L ).
  1. 第一个元素是 X非空 列表和其他一些列表 L2 的串联是一个以相同的 X 开头并继续的列表带有一个列表 L3 使得:
    • L3 是列表 L1L2 的串联:
    conc( [X | L1],[X | L3] ) :- 
        conc(  L1,L3 ).

这是一个非常好的串联定义:

  • 每当 conc(A1,A2,R) 成功时,我们肯定有 A1 的所有元素后跟 A2 的所有元素形成 R(因此定义是有意义的作为“串联”)。
  • 每当 conc “引用自身”(递归地)第一个列表参数小一,所以我们有一个“变体”,它单调递减并到达某个地方(我们也会自动停止,因为列表长度总是 >= 0)。
  • 当第一个列表参数的长度为 0 时,“基本情况”有一个非递归定义,所以当我们停止时,我们可以成功地完成(如果第一个子句 conc([],L). 是缺少我们会停止但由于缺少空列表的匹配子句而失败)。

“派生树”是相当线性的(与您在函数式语言中找到的派生没有什么不同),即递归地应用第二个子句直到它不再适用,然后应用第一个子句。

因此我们看到:

Call: (8) conc([2,q])
   Call: (9) conc([3],q])
      Call: (10) conc([],q])
      Exit: (10) conc([],q])
   Exit: (9) conc([3],q])
Exit: (8) conc([2,q])

注意“出口端口”的传统名称。正确的名称是并且应该一直是“成功”,即使在 1980 年代也是如此。它从未改变。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 <select id="xxx"> SELECT di.id, di.name, di.work_type, di.updated... <where> <if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 <property name="dynamic.classpath" value="tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams['font.sans-serif'] = ['SimHei'] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -> systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping("/hires") public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate<String
使用vite构建项目报错 C:\Users\ychen\work>npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-