Prolog - 从列表中删除具有相同第一个值的对

2024-04-18

我有这样的对象列表

list([obj(x,y),obj(x,z),obj(a,b),obj(b,c)]).

我想删除那些共享相同第一个值的元素,这样我就可以使用修改后的列表。在这种情况下,最终列表将如下所示

list([obj(a,b),obj(b,c)]

有人可以帮忙吗?我真的很挣扎这个问题。


对于初学者来说,有效地解决这个问题并非易事。假设列表的元素是地面的,我们可以首先注意到对列表进行排序会将共享列表中第一个参数的所有元素聚集在一起obj/2复合词。例如:

| ?- sort([obj(x,y),obj(x,z),obj(a,b),obj(b,c)], S).
S = [obj(a, b), obj(b, c), obj(x, y), obj(x, z)]
yes

The sort/2是一个标准的内置谓词。任何像样的 Prolog 系统都应该以 O(n*log(n)) 的复杂度来实现它。排序后,我们可以遍历列表,这样我们就可以在 O(n) 中对其进行过滤:

filter(List, Filtered) :-
    sort(List, Sorted),
    walk(Sorted, Filtered).

walk([], []).
walk([obj(X,Y)| Sorted], Filtered) :-
    walk(Sorted, X, obj(X,Y), Filtered).

walk([], _, Element, [Element]).
walk([obj(X,_)| Sorted], X, _, Filtered) :-
    !,
    delete(Sorted, X, Rest),
    walk(Rest, Filtered).
walk([obj(X,Y)| Sorted], _, Element, [Element| Filtered]) :-
    walk(Sorted, X, obj(X,Y), Filtered).

delete([], _, []).
delete([obj(X,_)| Sorted], X, Rest) :-
    !,
    delete(Sorted, X, Rest).
delete(Rest, _, Rest).

调用示例:

| ?- filter([obj(x,y),obj(x,z),obj(a,b),obj(b,c)], Filtered).
Filtered = [obj(a, b), obj(b, c)]
yes

看起来不错,但我们应该做更全面的测试。我们可以定义一个属性,所有filter/2谓词解必须满足:

property(List, Filtered) :-
    filter(List, Filtered),
    % all elements of the output list must
    % be in input list
    forall(
        member(X, Filtered),
        member(X, List)
    ),
    % no two elements in the output list
    % should share the first argument
    \+ (
        select(obj(X,_), Filtered, Rest),
        member(obj(X,_), Rest)
    ),
    % all elements in the input list whose
    % first argument is not repeated must
    % be in the output list
    \+ (
        select(obj(X,Y), List, Rest),
        \+ member(obj(X,_), Rest),
        \+ member(obj(X,Y), Filtered)
    ).

我们现在可以使用基于属性的测试实现例如 Logtalk 的lgtunit https://logtalk3.readthedocs.io/en/latest/devtools/lgtunit.html#quickcheck快速检查实施。但有一个问题。基于属性的测试要求我们能够生成列表obj/2元素。解决办法,我们作弊!首先我们做一个句法的转变自obj(X,Y) to X-Y。此转换不会更改正在测试的谓词的语义:

filter(List, Filtered) :-
    sort(List, Sorted),
    walk(Sorted, Filtered).

walk([], []).
walk([X-Y| Sorted], Filtered) :-
    walk(Sorted, X, X-Y, Filtered).

walk([], _, Element, [Element]).
walk([X-_| Sorted], X, _, Filtered) :-
    !,
    delete(Sorted, X, Rest),
    walk(Rest, Filtered).
walk([X-Y| Sorted], _, Element, [Element| Filtered]) :-
    walk(Sorted, X, X-Y, Filtered).

delete([], _, []).
delete([X-_| Sorted], X, Rest) :-
    !,
    delete(Sorted, X, Rest).
delete(Rest, _, Rest).

我们将相同的语法转换应用于property/2谓词:

property(List, Filtered) :-
    filter(List, Filtered),
    % all elements of the output list must
    % be in input list
    forall(
        member(X, Filtered),
        member(X, List)
    ),
    % no two elements in the output list
    % should share the first argument
    \+ (
        select(X-_, Filtered, Rest),
        member(X-_, Rest)
    ),
    % all elements in the input list whose
    % first argument is not repeated must
    % be in the output list
    \+ (
        select(X-Y, List, Rest),
        \+ member(X-_, Rest),
        \+ member(X-Y, Filtered)
    ).

我们现在可以使用目标进行测试:

| ?- lgtunit::quick_check(
         property(
             +list(pair(char,char)),
             -list(pair(char,char))
         )
     ).
% 100 random tests passed
% starting seed: seed(25256,26643,1563)
yes

注意:在定义中property/2谓词,我们假设事实上的标准member/2 and select/3列表谓词可用于user(即在顶级解释器处)。如果情况并非如此,请在呼叫前加上前缀list::.

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

Prolog - 从列表中删除具有相同第一个值的对 的相关文章

  • 根据 Mathematica 中的另一个列表值拆分列表

    在 Mathematica 中我有一个点坐标列表 size 50 points Table RandomInteger 0 size RandomInteger 0 size i 1 n 以及这些点所属的聚类索引列表 clusterIndi
  • 以特定方式填充列表

    我需要填充一个包含 5 个位置的列表 new list 我收到 2 个列表 并且有一个默认值来填充新列表 现在开始解决问题 好的方式是 我从列表中接收 2 个值 从列表中接收 2 个值并添加默认值 A1 A2 DEFAULT B1 B2 但
  • 如何在 C# 中使用窗口窗体创建动态下拉列表

    我正在尝试为朋友的手机商店构建一个简单的库存程序 我想使用C 并访问数据库来存储数据 DB 将有 2 个主要列表 devices 品牌 型号 颜色 价格 库存 最小库存 parts 品牌 型号 描述 库存 最小库存 GUI 将使用多个下拉列
  • 如何在 Haskell 中向右或向左移动列表的 1 个元素?

    嗨 我一直在寻找答案 但找不到 假设我们有一个像这样的列表 1 10 4 5 3 我怎样才能将 5 向左移动 使这个列表变成 1 10 5 4 3 我尝试过了swapElementsAt通过找到该元素的索引 但它看起来非常不足 swapEl
  • 如何在 switch 语句中将向量作为参数传递

    我对问题的谷歌搜索没有返回有用的结果和文档 switch没有告诉我如何做 所以我希望我能在这里得到答案 假设我有一个向量 cases lt c one two three 我想使用 switch 语句并将这些元素作为 switch 语句的参
  • Python range() 和 zip() 对象类型

    我了解功能如何range and zip 可以在 for 循环中使用 然而我期望range 输出一个列表 很像seq在 Unix shell 中 如果我运行以下代码 a range 10 print a 输出是range 10 表明它不是一
  • 如何将列表转换为元组列表?

    我想转换 z z a z z a a z to z 2 a 1 z 2 a 2 z 1 我该怎么做 所以 我需要累积以前的值 它的计数器和元组列表 我已创建记录 record acc previous counter tuples 重新定义
  • 如何从Python列表中的字符串中删除双引号?

    我正在尝试在字典列表中获取一些数据 数据来自 csv 文件 因此都是字符串 文件中的键都有双引号 但由于这些都是字符串 我想删除它们 这样它们在字典中看起来像这样 key value 而不是这个 key value 我尝试简单地使用 str
  • 分配列表的多个值

    我很想知道是否有一种 Pythonic 方式将列表中的值分配给元素 为了更清楚 我要求这样的事情 myList 3 5 7 2 a b c d something myList So that a 3 b 5 c 7 d 2 我正在寻找比手
  • C# 如何单击 IList 中的 IWebelement?

    所以我尝试单击 YouTube 上的按钮 但我无法通过 Xpath 找到该按钮 因为按钮太多 所以我尝试将它们保存在 IList 中 现在我想单击列表中的特定按钮 ChromeDriver chrome new ChromeDriver L
  • 如何找到排列的索引

    index List Idx Predicate will get List with permutation and I want to know index of permutation For example index 4 1 3
  • 使用 LINQ 洗牌

    我正在尝试编写一个简单的纸牌游戏 为了想出一个好的洗牌算法 我遇到了 Jeff Atwood 的post http www codinghorror com blog 2007 12 shuffling html关于恐怖编码 但是 当我在调
  • scala 返回列表中的第一个 Some

    我有一个清单l List T1 目前我正在执行以下操作 myfun T1 gt Option T2 val x Option T2 l map myfun l flatten find gt true The myfun函数返回 None
  • 将字符串连接到python列表中所有元素的末尾

    我想知道如何将字符串连接到列表中所有元素的末尾 例如 List1 1 2 3 string a output 1a 2a 3a 在列表理解和使用中重建列表str format在两个参数上 gt gt gt string a gt gt gt
  • 我应该在 Prolog 和一般情况下避免尾递归吗?

    我正在阅读 立即学习 Prolog 在线书籍 以获取乐趣 我正在尝试编写一个谓词 该谓词遍历列表的每个成员并向其添加一个 使用累加器 我已经在没有尾递归的情况下轻松完成了 addone addone X Xs Y Ys Y is X 1 a
  • 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
  • 在 R 中提取 data.frames 列表的名称以及 data.frame 中的值

    在下面的代码中 j是 data frames 的命名列表 我想知道是否有办法 a 提取变量的数值 即one short and one long 在 data frames 内并附加它们的相关名称 即 AAA or BBB or CCC 到
  • Python:如何在不先创建整个列表的情况下计算列表的总和?

    通常我们必须 1 声明一个列表 2 使用以下方法计算该列表的总和sum 但现在我希望指定一个以 1 开头 间隔为 4 100 个元素的列表 如下所示 1 5 9 13 17 21 25 29 33 37 我不想涉及数学公式 所以 1 如何在
  • 删除 HashMap 中包含的列表项

    我有一个Hashmap
  • 通过列表理解压平列表列表

    我正在尝试使用 python 中的列表理解来展平列表 我的清单有点像 1 2 3 4 5 6 7 8 只是为了打印这个列表列表中的单个项目 我编写了这个函数 def flat listoflist for item in listoflis

随机推荐

  • 限制特定组的 Firebase 数据库和存储写入访问权限

    我有一个带有内容管理端的 React Redux Firebase 应用程序 所有这些页面都以 admin 我需要将 Firebase 数据库和 Firebase 存储写入权限限制为这些用户的一小部分 并在未经身份验证 或未经管理员角色身份
  • 从.c调用MASM32过程

    我现在正在使用 Visual Studio 我需要构建一个 win32 应用程序并需要从 C 函数调用过程 但我总是收到构建错误 错误 3 错误 LNK1120 1 个未解析的外部 我已经通过一个过程将所有内容简化为一个简单的主函数和简单的
  • CodeIgniter - 删除文件,路径问题

    我的根目录中有 3 个文件夹 application system 和 uploads 在 application controllers mycontroller php 我有这行代码 delete files uploads file
  • 在 PowerShell 中显示 Unicode

    我想要实现的目标应该相当简单 尽管 PowerShell 试图让它变得困难 我想显示文件的完整路径 其中一些文件的名称中包含阿拉伯语 中文 日语和俄语字符 我总是得到一些无法解读的输出 如下所示 控制台中看到的输出正被另一个脚本使用 输出包
  • 如何在 Chrome DevTools 中查看元素上触发的事件?

    我在库的页面上有一个可自定义的表单元素 我想看看当我与它交互时会触发哪些 javascript 事件 因为我试图找出要使用的事件处理程序 如何使用 Chrome Web Developer 来做到这一点 您可以使用监控事件 http www
  • 如何告诉 JavaFX WebView 忽略“use strict”指令?

    我正在尝试使用以下代码将 mozilla 查看器集成到 JavaFx WebView 中 import javafx application Application import javafx scene Scene import java
  • 如何将这个数学方程写成c++

    我不知道如何编写C 中给出的公式 也不能使用捷径 我必须编写长版本的代码 这是我到目前为止所拥有的 4x 3 8x 2 9x 18 y 7 x 3 3x 2 18 表示绝对值 它需要采用这样的格式 这是我书中的一个示例 double y 4
  • Android的EditText在显示虚拟键盘并且涉及SurfaceView时隐藏

    我有一个简单的用户界面 EditText 应位于 SurfaceView 下方 我使用RelativeLayout 来排列这两个视图 现在 当我点击 EditText 打开虚拟键盘时 SurfaceView 会向上滑动 但 EditText
  • 同时维护多个emacs配置

    我想在同一台电脑上的同一用户帐户上同时维护多个 emacs 配置 例如 emacs prelude emacs starter kit 和我自己的自定义 emacs 配置 为此 我设置了 emacs1 d emacs2 d emacs3 d
  • Qt Signal/Slots 发送完整结构

    我正在尝试通过两个线程之间的信号 槽发送一个结构 我的信号 槽已正确连接 并且我已经能够发送包含部分数据的 QString 但现在我需要发送整个数据 而结构似乎是最明智的 但是 当我尝试时 信号未发送 接收 问题似乎仅与发送 接收结构 前后
  • 在android中通过cardview创建视图

    I want to create this layout 这是一个卡片视图 灰色视图 和图像视图 蓝色视图 我使用这个代码
  • 使用 Facebook 登录 注销后出现问题

    我正在使用 facebook sdk 和 facebook connect 使用 asp net 和 c 将 Facebook 集成到我的网站中 用户可以使用该代码成功登录 我面临的问题是 每当用户通过 fb 登录时 如果用户从 faceb
  • 是否可以更改AVPlayer的背景颜色?如果是,怎么办?

    我希望将默认背景颜色从黑色更改为我想要的颜色 可能是与视频形成对比的颜色 大多数时候是黑色 我已将这段代码添加到我的viewWillAppear 功能 let playerLayer AVPlayerLayer player player
  • 向上或向下滚动时的 JavaScript 事件

    是否可以编写 JavaScript 来在手动向上或向下滚动 DIV 层的滚动条时执行操作 如果是这样 请给我一个提示 以实现一个简单的警报框 表示您向上滚动并向下滚动 您可以简单地使用onscrolljava脚本的事件 OnScroll 事
  • 在heroku上部署django网站出错

    我正在heroku 中部署我的django 网站 并在django 的setting py 文件中使用DATABASE 我正在遵循以下所有步骤赫罗库帮助 https devcenter heroku com articles getting
  • Android - 禁用 HDMI

    我的一个 Android 项目需要时不时地在 2 个 HDMI 输入之间切换 可能是一分钟一次 一根 HDMI 输入来自 Android 设备的 HDMI 输出 一根来自外部不可控源 我发现了一个 HDMI 开关 当信号可用时 它可以自动在
  • 前向声明类型 - 这背后的原因是什么

    Forward declare a type point to be a struct typedef struct point point Declare the struct with integer members x y struc
  • 从动态内容提供者加载 html5 音频并进行身份验证

    假设我们这里有一个内容提供者端点myuri org api auth sources id 它返回由 id 标识的音乐文件 路线 api auth 需要身份验证 在本例中 这是通过在请求标头中传递 JWT 来完成的 如下所示Authenti
  • Symfony2 根据提交的数据形成验证组

    我有一些复杂的表单 带有多个子表单 并且我希望能够根据主表单中选择的单选按钮单独验证每个子表单 我想通过验证组来实现这一目标 注 我没有data class模型 我使用数组 这是我的简化表格 class MyType extends Abs
  • Prolog - 从列表中删除具有相同第一个值的对

    我有这样的对象列表 list obj x y obj x z obj a b obj b c 我想删除那些共享相同第一个值的元素 这样我就可以使用修改后的列表 在这种情况下 最终列表将如下所示 list obj a b obj b c 有人