Same_length/2 更好的纯版本

2024-05-19

鉴于频繁的纯定义same_length/2 as

same_length([],[]).
same_length([_|As], [_|Bs]) :-
   same_length(As, Bs).

?- same_length(L, [_|L]).
   loops.

是否有一个纯粹的定义不会在这种情况下循环?类似于纯(但效率较低)版本的东西append/3 called append2u/3 https://stackoverflow.com/a/65361752/772868.

我知道如何手动捕获此类情况var/1等等,但理想情况下,需要一个与原始定义一样纯粹的版本。或者至少它应该很简单。

我尝试过的是上面的定义。

似乎有必要澄清一下:

请注意,某些查询本质上不能终止。考虑到:

?- same_length(Ls, Ks).
   Ls = [], Ks = []
;  Ls = [_A], Ks = [_B]
;  Ls = [_A,_B], Ks = [_C,_D]
;  Ls = [_A,_B,_C], Ks = [_D,_E,_F]
;  Ls = [_A,_B,_C,_D], Ks = [_E,_F,_G,_H]
;  ... .

没有其他方法可以使用语法答案替换的语言来枚举所有解决方案。

但对于给定的查询,实现仍然可能终止。


这个答案旨在最小化运行时间成本。

它建立在'$skip_max_list'/4并在 Scryer Prolog 上运行。

首先,一些辅助代码:

:- use_module(library(lists)).

'$skip_list'(N,Xs0,Xs) :-
   '$skip_max_list'(N,_,Xs0,Xs).

is_list([]).
is_list([_|Xs]) :-
   is_list(Xs).

sam_length_([],[]).
sam_length_([_|Xs],[_|Ys]) :-
   sam_length_(Xs,Ys).

现在是主菜:

sam_length(Ls1,Ls2) :-
   '$skip_list'(L1,Ls1,Rs1),
   (  Rs1 == []
   -> length(Ls2,L1)
   ;  var(Rs1),
      '$skip_max_list'(L2,L1,Ls2,Rs2),
      (  L2 < L1
      -> var(Rs2),
         Rs1 \== Rs2,
         '$skip_max_list'(_,L2,Ls1,Ps1),
         sam_length_(Ps1,Rs2)
      ;  '$skip_list'(N2,Rs2,Ts2),
         (  Ts2 == []
         -> M1 is N2-L1,
            length(Rs1,M1)
         ;  var(Ts2),
            (  N2 > 0
            -> Ts2 \== Rs1,
               sam_length_(Rs2,Rs1)     % switch argument order
            ;  Rs1 == Rs2
            -> is_list(Rs1)             % simpler enumeration
            ;  sam_length_(Rs1,Rs2)
            )
         )
      )
   ).

示例查询:



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

Same_length/2 更好的纯版本 的相关文章

  • 在 Prolog、尾递归中计算斐波那契数列

    我想在 Prolog 中以递归尾部模式计算斐波那契数列 fibonacci 0 0 fibonacci 1 1 fibonacci N Result fibonacci N 1 0 fibonacci N Result Count Coun
  • 在 prolog 中读取用户输入的字符串

    我是 Prolog 初学者 我正在使用 swi prolog 刚刚开始使用它 我需要将用户输入字符串拆分到列表中 我尝试了以下代码 但出现错误 指出 在子句正文中完全停止 无法重新定义 2 write Enter the String nl
  • 计算序言中列表的排列

    在 序言艺术 第二版中有一个问题 您应该定义一个谓词 Even permutation Xs Ys 和类似的奇数排列 当您查询时 例如 Even permutation 1 2 3 2 3 1 和 odd permutation 1 2 3
  • 以系统的方式报告 Prolog 中查询失败的“原因”

    我正在 Prolog 中寻找一种方法 模式或内置功能 我可以用它来返回why一组谓词失败 至少就数据库中的谓词而言 当用户在系统中提出查询时 我试图能够说的不仅仅是 那是错误的 例如 假设我有两个谓词 blue 1如果某物是蓝色的 则为真
  • F# 和模糊逻辑

    我知道这可能听起来很奇怪 但我想知道 Microsoft Visual F 正在进入的这个新世界中的一件事 这种语言有很多应用 我要学习 关于解析 函数式编程 结构化编程 但是人工智能呢 模糊逻辑有什么应用吗 F 是一种适合模糊逻辑应用程序
  • 根据一个值找到列表内列表的最小值

    我在序言中有这个列表 dublin london 1000 dublin moscow london 5000 我想计算列表的最小值 这样答案应该是 dublin london 1000 这个问题有一些类似的问题序言中列表列表中的最小值 h
  • Prolog 展平列表

    flatten A B R islist A gt flatten A R1 R R1 write A append A R1 R flatten B R1 flatten X X islist 这是我写的代码 但我有奇怪的问题 I get
  • 通过递归扩展 Prolog 目标?

    我 最终 实现了一些目标 这些目标将根据开始由 开始之后 and duration 然而 计划目标仅接受规定数量的任务 我想扩展计划目标的功能以接受单个列表并在计划时迭代该列表 不幸的是 我认为这将需要与can run and 冲突目标如下
  • Prolog中如何选择bagof、setof和findall

    如何在 bagof setof 和 findall 之间做出选择 有什么重要的区别吗 哪个最常用 哪个最安全 感谢您的评论 回答 我检查了SWI Prolog 手册页findall 3 http www swi prolog org pld
  • 查找相邻成员

    我必须找出列表中的两个成员是否相邻 限制是使用append 3谓词 到目前为止 我已经完成了下面的操作 如果它是真的 它就有效 否则我得不到答案 就像它永远运行一样 adjacent X Y L append L1 X Y T1 appen
  • SWI-Prolog 中的跨模块“接口”调用

    这可能是 SWI Prolog 模块系统特有的 假设我们有三个 Prolog 模块 在 SWI Prolog 模块系统中 robin 在文件中robin pl arthur 在文件中arthur pl helper 在文件中helper p
  • 将 SWI Prolog 代码编译为 Windows 可执行文件 - 解析器 Grails3 项目

    我正在尝试构建解析器 Grails3 项目https github com RichardMoot Grail https github com RichardMoot Grail谁的教程是http www labri fr perso m
  • 如何让 Prolog 解释你的结果超出真实的陈述

    我有以下事实和规则 flight sea msp flight msp jfk route A B flight A B route B A flight A B route A C flight A B flight B C 当查询rou
  • SWI Prolog 转义引号

    我需要在序言中将 放在字符串周围 我从另一个程序获取输入 看起来我无法转义该程序中的 因此我必须在序言中添加 否则序言语句将不起作用 感谢您的帮助 为了讨论strings https stackoverflow com a 39922411
  • 变量的多个值介于 0 和数字序言之间

    所以我一直在尝试自学序言 我认为我进展顺利 然而 我有点坚持我正在尝试的这一种方法 toN N A A 等于 0 到 N 1 之间的整数值 按升序生成 所以 toN 5 A 将是 A 0 A 1 A 2 A 3 A 4 我对序言还很陌生 所
  • Prolog:从哪里开始解决类似扫雷的难题?

    我需要在序言中写一些类似扫雷的东西 我能够用 正常 语言做到这一点 但是当我尝试用序言开始编码时 我完全不知道如何开始 我需要一些提示 输入规格 板尺寸 m n m n 1 16 三元组列表 i j k 在哪里i 1 m j 1 n k 1
  • SWI-Prolog 与 C++ 接口的问题

    我试图让 SWI Prolog 与 C 很好地配合 现在束手无策 现在 在我开始准确解释我的问题是什么之前 我想首先说明我的项目是关于什么的以及我选择了哪些工具来开发解决方案 我的教授分配给我的任务是开发一个 GUI 程序 作为 SWI p
  • WAM 中的扁平化形式

    WAM 教程重构指出查询 p Z h Z W f W 需要使用以下原则进行扁平化 话虽这么说 查询扁平化形式是 X3 h X2 X5 X4 f X5 X1 p X2 X3 X4 我对外部变量的定义感到困惑 请考虑以下内容 p Z h Y a
  • 替换 prolog 中的部分表达式

    我需要简化序言中的身份 例如x 0 x x x 0 ETC 为此 我需要替换表达式的部分内容 比如x 0 by x 您能帮我更换吗 Prolog 的一个巧妙之处在于您可以非常轻松地解构算术表达式 您的基本模板将如下所示 simplify X
  • check/3 谓词从列表中获取替代元素

    我有一个谓词check 3用作 例如 check A B C 所有三个参数都是列表 C是主列表 A包含具有奇数索引的项目 B包含具有偶数索引的项目 例如 check 1 3 2 4 1 2 3 4 is true check 1 2 3 4

随机推荐