prolog - SWI-Prolog 检查不同列表中的两个元素是否在同一位置
问题描述
我得到了一个任务,我需要编写一个谓词“same_position(L1,L2,E1,E2)”,其中 L1 和 L2 是列表,E1 是 L1 中的元素,E2 是 L2 中的元素。当 E1 和 E2 在其列表中的相同位置时,谓词为真。我需要使用递归来解决这个问题
这是我对问题的解决方案:
same_position([L1|_],[L2|_],E1,E2) :- L1==E1,L2==E2.
same_position([_|L1],[_|L2],E1,E2) :- same_position(L1,L2,E1,E2).
这可行,但并不完全符合预期,伴随着分配而来的是一个示例输出,其中以下部分是问题所在。预期的输出在打印 false 之前给出 L 的值,而我的解决方案只是打印 false。我究竟做错了什么?
预期输出:
?- same_position(L, [a,a,c], 3, a).
L = [3|_G1667] ;
L = [_G1769, 3|_G1772] ;
false.
矿井输出:
?- same_position(L,[a,a,c],3,a).
false.
解决方案
罪魁祸首是:
same_position([L1|_],[L2|_],E1,E2) :- L1==E1, L2==E2.
same_position([_|L1],[_|L2],E1,E2) :- same_position(L1,L2,E1,E2).
[ (==)/2
swi-doc]谓词定义为:
@Term1 == @Term2
True
如果Term1
相当于Term2
. 变量仅与共享变量相同。
所以这意味着对于一个变量X
,只X == X
成立,而不是X == Y
(除非X = Y
),并且X == 3
总是失败(除非X
已经接地)3
。
但是,根据您的示例输出,您不想检查相等性,而是要unify,这就是(=)/2
:
same_position([L1|_],[L2|_],E1,E2) :- L1 = E1, L2 = E2.
same_position([_|L1],[_|L2],E1,E2) :- same_position(L1,L2,E1,E2).
然而,在 Prolog 中,我们也可以在 head 中进行 inify,方法是在head中使用相同的变量两次(或更多):
same_position([L1|_],[L2|_], L1, L2).
same_position([_|L1],[_|L2],E1,E2) :- same_position(L1,L2,E1,E2).
推荐阅读
- asp.net-mvc - Asp.net core 3.1 选项模式不调用我的委托
- ubuntu - 如何重新启动 buildkite 代理
- windows - PS1 脚本出错
- java - 自定义用户存储管理器类未显示
- mysql - PHP 7.2 OCI8 Oracle 9i PL/SQL 代码错误:ORA-06550:第 1 行,第 7 列:PLS-00103:遇到符号“”
- c - 调用 fork() 时父进程未运行,函数不返回
- kotlin - 如何从 Kotlin 引用 java.awt.Dimension 的公共字段
- sql - 按分组行选择空值 SQL Server
- javascript - Heroku 上未知的代币传播运营商,在本地工作
- angularjs - 将单选更改为多选 Google Map API