Prolog:消除查询中的重复

2024-03-23

我一直在尝试编写一个简单的代码,其行为方式如下:

| ?- hasCoppiesOf(X,[a,b,a,b,a,b,a,b]).
X = [a,b] ? ;
X = [a,b,a,b] ? ;
X = [a,b,a,b,a,b,a,b] ? ;

And

| ?- hasCoppiesOf([a,b,a,b,a,b,a,b], X).    
X = [] ? ;    
X = [a,b,a,b,a,b,a,b] ? ;    
X = [a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b] ? ;    
X = ...

这个愿望导致了下一段代码:

hasCoppiesOf(A,[]).


hasCoppiesOf([H1|T1], [H1|T2]) :-
  append(T1, [H1], X),
  hasCoppiesOf([H1|T1], X, T2).


hasCoppiesOf(A, A, B) :-
  hasCoppiesOf(A, B).

hasCoppiesOf(A, [H1|T1], [H1|T2]) :-
  append(T1, [H1], X),
  hasCoppiesOf(A, X, T2).

它给了我第二个查询所需的内容,但是第一个查询的结果是:

?- hasCoppiesOf(X,[a,b,a,b,a,b,a,b]).
X = [a, b] ;
X = [a, b] ;
X = [a, b] ;
X = [a, b] ;
X = [a, b] ;
X = [a, b] ;
X = [a, b] ;
X = [a, b] ;
X = [a, b, a, b] ;
X = [a, b, a, b] ;
X = [a, b, a, b] ;
X = [a, b, a, b] ;
X = [a, b, a, b] ;
X = [a, b, a, b] ;
X = [a, b, a, b] ;
X = [a, b, a, b] ;
X = [a, b, a, b, a, b] ;
X = [a, b, a, b, a, b] ;
X = [a, b, a, b, a, b] ;
X = [a, b, a, b, a, b] ;
X = [a, b, a, b, a, b] ;

它似乎工作得很好,但重复相同的答案让我感到困扰。这可能是一个简单的错误,但是有没有办法让输出更漂亮呢? 老实说,这是一个谜,为什么 Prolog 将两个相同的数组视为不同的答案。 或者也许只是我的系统出了问题?

编辑: 评论中的人的温柔指导帮助我解决了这个问题。然而,如果这个问题的读者是想要解决完全相同问题的人——代码不能很好地工作,我很抱歉。


我认为你只是让你的谓词变得比需要的更复杂,可能只是想得太多了。给定的解决方案可能会在逻辑的多个路径上取得成功。

你可以做到这一点,无需append/3通过对齐列表的前端并使原始列表在重复时“重置”:

% Empty list base cases
dups_list([], []).
dups_list([_|_], []).

% Main predicate, calling aux predicate
dups_list(L, Ls) :-
    dups_list(L, L, Ls).

% Recursive auxiliary predicate
dups_list([], [_|_], []).
dups_list([], [X|Xs], [X|Ls]) :-
    dups_list(Xs, [X|Xs], Ls).
dups_list([X|Xs], L, [X|Ls]) :-
    dups_list(Xs, L, Ls).

以下是一些结果:

| ?- dups_list(X,[a,b,a,b,a,b,a,b]).

X = [a,b] ? a

X = [a,b,a,b]

X = [a,b,a,b,a,b,a,b]

no
| ?- dups_list([a,b,a,b,a,b,a,b], X).

X = [] ? ;

X = [a,b,a,b,a,b,a,b] ? ;

X = [a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b] ? ;

X = [a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b] ?
...
| ?- dups_list(A, B).

A = []
B = [] ? ;

A = [_|_]
B = [] ? ;

A = [C]
B = [C] ? ;

A = [C]
B = [C,C] ? ;

A = [C,D]
B = [C,D] ? ;

A = [C]
B = [C,C,C] ? ;

A = [C,D,E]
B = [C,D,E] ? ;
...

可能有一种方法可以进一步简化解决方案,但我还没有充分利用它来确定是否是这种情况。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Prolog:消除查询中的重复 的相关文章

  • 如何在 swi-prolog 的 prolog 文件中运行 prolog 查询?

    如果我有一个定义规则的 prolog 文件 并在 Windows 中的 prolog 终端中打开它 它会加载事实 然而 然后它显示 提示我手动输入一些内容 如何将代码添加到文件中 以便它实际上会评估这些特定的语句 就像我输入它们一样 像这样
  • 执行树元解释

    我有根据我之前的问题制作的跟踪元解释器here https stackoverflow com questions 27235148 implementing cut in tracing meta interpreter prolog 我
  • 如何实现 not_all_equal/1 谓词

    如何实施not all equal 1谓词 如果给定列表包含至少 2 个不同的元素 则该谓词成功 否则失败 这是我的尝试 不是很纯粹的尝试 not all equal L member H1 L member H2 L H1 H2 gt t
  • 如何在 Prolog 中为变量(如字符串)分配多个值?

    今天早些时候 我寻求帮助以在序言中构建数据库以及如何通过参数搜索 有人提出了这个 您还可以向每个处理器添加术语列表 例如 processor pentium g4400 brand intel family pentium series g
  • 为什么在具体化中将 clpfd 变量分配给实际值?

    我正在开发一个 SWI Prolog 程序 该程序使用 CLP FD 约束来找到特定问题的解决方案 为此 我碰巧需要两个列表的 未定位 重叠 那是 List La长度为A List Lb长度为 B A gt B 未定位的重叠列表是La Lb
  • 计算序言中列表的排列

    在 序言艺术 第二版中有一个问题 您应该定义一个谓词 Even permutation Xs Ys 和类似的奇数排列 当您查询时 例如 Even permutation 1 2 3 2 3 1 和 odd permutation 1 2 3
  • 如何在 Prolog 中解决这个算术表达式难题?

    我有一个编程问题 https blog svpino com 2015 05 08 solution to problem 5 and some other thoughts about this type of questions htt
  • Prolog内存问题

    我想找到一种方法来分析我在序言中编写的谓词 一个巨大的谓词 的内存使用情况 我目前正在运行它swi http www swi prolog org and yap http www dcc fc up pt vsc Yap document
  • Prolog中如何选择bagof、setof和findall

    如何在 bagof setof 和 findall 之间做出选择 有什么重要的区别吗 哪个最常用 哪个最安全 感谢您的评论 回答 我检查了SWI Prolog 手册页findall 3 http www swi prolog org pld
  • Prolog中计算数字是否为素数

    我正在尝试计算输入是否是素数 但出了问题 这是我的代码 primeNumber X prime prime A 1 prime prime A B R is A mod B R 1 R A prime prime X B B lt A Ne
  • 高阶“解决方案”谓词

    我正在使用一个更高阶的 Prolog 变体 它缺少findall 还有一个关于实现我们自己的问题findall here 获取 Prolog 中的解决方案列表 https stackoverflow com questions 419103
  • Prolog - 通过演绎减少知识库

    我需要创建一个规则来搜索与 my rule 匹配的事实 这些事实将用于改变知识库 my rule Conclusion Premise 我有这个知识库可以开始 dynamic is 2 is m1 house is m1 thing is
  • 判断第一个字母是否是元音序言

    我习惯了过程式编程语言 而且我在 prolog 上遇到了一些困难 缺乏在线资源也是一个遗憾 获取给定变量的第一个字符并检查它是否是元音的最 序言 方式是什么 我想 这样的东西就是我所追求的 这都是伪代码 但这是你解决问题的方法吗 isVow
  • 将行读取到序言中的原子列表

    我需要将任何行 来自 user input 读入原子列表 例如 Example line which contains any ASCII chars into Example line which contains any ASCII c
  • 这个版本的trace有什么问题?

    我有这个跟踪元解释器 它是为 swi prolog 编写的 trace Goal trace Goal 0 trace true Depth true trace fail Depth fail trace A gt B Depth A g
  • Prolog 在技术上是如何工作的?引擎盖下是什么?

    我想更多地了解 Prolog 的内部结构并了解它是如何工作的 我知道如何使用它 但不是它内部如何运作 Prolog 中使用的算法和概念的名称是什么 它可能会构建某种树结构或有向对象图 然后在查询时使用复杂的算法遍历该图 也许是深度优先搜索
  • 将“mod”运算符与“or”一起使用时是否强制具体化?

    我使用 CLP FD 和 SWI Prolog 编写了一个 CSP 程序 我认为当我使用时我需要改进我的约束写作mod操作员 和 一起 在我的谓词中 一个简短的例子 use module library clpfd constr X Y Z
  • 将人员分配到床位 - 自动化方法[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我每年都会帮助举办青年营 将与会者分配到卧室是一项艰巨的任务 有 92 个卧室 活动持续一周 与会者停留的时间长短不一 而且床需要重复
  • Prolog 谓词参数中实例化模式指示符的含义

    查看Prolog文档 谓词签名有时会写成如下 foo Bar Baz Qux Mop 什么是 and 我该如何解释它们 另外 这些是唯一存在的还是还有更多 在这种情况下 这些前缀运算符代表实例化模式 即它们告诉您哪些参数应该是变量或在调用谓
  • 下面代码中的修剪选择点如何使其更加高效(Prolog)?

    在下面给出的代码中 有 cut 修剪选择点以提高效率 我非常确定reverse谓词和agent do moves谓词是必不可少的 solve task Task Cost agent current position oscar P sol

随机推荐