Prolog 时间重叠问题

2024-03-23

假设我有这个知识库:

free(ann,slot(time(8,0),time(9,0))).
free(ann,slot(time(10,0),time(11,0))).

free(bob,slot(time(7,0),time(8,30))).
free(bob,slot(time(10,0),time(11,0))).

free(carla,slot(time(8,0),time(9,0))).
free(carla,slot(time(10,0),time(10,15))).

因此,经过大量努力,我设法编写了一些内容,使用以下代码打印在特定时段内第一个有空的人:

meetone(Person, slot(time(BeginHour, BeginMinute), time(EndHour, EndMinute)))
:- free(Person, slot(time(BH, BM), time(EH, EM))),
   BH*60 + BM =< EndHour*60 + EndMinute,
   EH*60 + EM >= BeginHour*60 + BeginMinute.

main :- (meetone(Person,slot(time(7,15),time(7,20))); halt),
       write(Person),
       nl,
       halt.

:- initialization(main).

这将打印 bob,即预期结果。

这就是事情变得复杂的地方(至少对我来说)。假设我想找出知识库中每个人共有的所有时间段。下面的代码演示了我最终想要如何调用它:

people([ann,bob,carla]).

meet :- ???

main :- (setof(Slot,meet(Slot),Slots); halt),
        write(Slots),
        nl,
        halt.

:- initialization(main).

这是一些模糊的伪代码,我认为它们可能会实现我正在寻找的目标,但我没有足够的经验来让它工作。

  1. 从第一人的空闲槽位开始。
  2. 递归遍历人员列表的其余部分,找到重叠的时间。
  3. 可以使用类似于 meetone 的方法来验证插槽是否重叠;在此验证之后,两个时隙的开始时间的最大值和两个结束时间的最小值可用于找到确切的重叠周期。
  4. 打印最终的插槽列表。

最终输出将显示 8:00 - 8:30 和 10:00 - 10:15 的时段。任何帮助实现这一目标的帮助将不胜感激。


恕我直言,Prolog 有一些语法特征,确实有助于编写易于理解的代码。 那么这是你的问题,利用运算符来获得可读性:

free(ann, 08:00 > 09:00).
free(ann, 10:00 > 11:00).

free(bob, 07:00 > 08:30).
free(bob, 10:00 > 11:00).

free(carla, 08:00 > 09:00).
free(carla, 10:00 > 10:15).

meetone(Person, Slot) :- free(Person, SlotP), contains(SlotP, Slot).

contains(Slot1, Slot2) :-
   timepoints(Slot1, B1, E1),
   timepoints(Slot2, B2, E2),
   B1 =< E2, E1 >= B2.

timepoints(BH:BM > EH:EM, B, E) :-
   B is BH*60 + BM,
   E is EH*60 + EM.

main :- setof(Person, meetone(Person, 7:15 > 7:20), Available),
    maplist(writeln, Available).

我试图引入两个实用程序,一种可重用的代码:contains/2 和 timepoints/3。 拥有这样的片段可以帮助编写更复杂的逻辑......

运行这段代码,我得到

?- main.
bob
true.

现在回答你的主要问题:

假设我想找出知识库中每个人共有的所有时间段

我将开始编写一个 common_timeslot/3 ,解释(计算)预期的内容:

common_timeslot(S1, S2, Common) :-
   timepoints(S1, B1, E1),
   timepoints(S2, B2, E2), 
   % do you mean intersection by common ?
   ...

否则,只考虑身份

common_timeslot(S, S, S).

定义了这一点后,所有公共资源都可以通过以下方式找到:

main :-
    setof(Sc/P/Q, Sp^Sq^(
        free(P, Sp), free(Q, Sq), Q \= P,
        common_timeslot(Sp, Sq, Sc)
    ), Commons),
    maplist(writeln, Commons).

产生

?- main.
(8:0>9:0)/ann/carla
(8:0>9:0)/carla/ann
(10:0>11:0)/ann/bob
(10:0>11:0)/bob/ann
true.

edit考虑到垫子评论,现在我发布整个程序

free(ann, 08:00 < 09:00).
free(ann, 10:00 < 11:00).

free(bob, 07:00 < 08:30).
free(bob, 10:00 < 11:00).

free(carla, 08:00 < 09:00).
free(carla, 10:00 < 10:15).

meetone(Person, Slot) :- free(Person, SlotP), contains(SlotP, Slot).

contains(Slot1, Slot2) :-
   timepoints(Slot1, B1, E1),
   timepoints(Slot2, B2, E2),
   B1 =< E2, E1 >= B2.

timepoints(BH:BM < EH:EM, B, E) :-
    (   ( var(B), var(E) )
    ->  B is BH * 60 + BM,
        E is EH * 60 + EM
    ;   BH is B // 60,
        BM is floor(B mod 60),
        EH is E // 60,
        EM is floor(E mod 60)
    ).

% common_timeslot(S, S, S).
common_timeslot(S1,S2,S) :-
    timepoints(S1,B1,E1),
    timepoints(S2,B2,E2),
    B is max(B1,B2),
    E is min(E1,E2),
    B < E,
    timepoints(S,B,E).

% base case: C passed all commonality test
check_common(C, [], C).

% S is the current common, to be checked for availability on person P
check_common(S, [P|Ps], C) :-
    free(P, Sp),
    common_timeslot(S, Sp, Ct),
    check_common(Ct, Ps, C).

main :- setof(P, S^free(P,S), [FirstP|Others]),
    forall(free(FirstP, S), (
        check_common(S, Others, C),
        writeln(FirstP:C)
    )).

产生

?- main.
ann: (8:0<8:30)
ann: (10:0<10:15)
true.

主要变化是 timepoints/3 现在是“双向”的。然后我按照您在评论中的解释介绍了 common_timeslot/3 。

我想你会明白这些小的句法抽象有助于拥有一个干净的“应用”逻辑。当然,forall http://www.swi-prolog.org/pldoc/doc_for?object=forall/2/2, or setof http://www.swi-prolog.org/pldoc/man?section=allsolutions/3 是您需要了解的内置函数,以便更熟练地使用 Prolog。

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

Prolog 时间重叠问题 的相关文章

  • 使用 Prolog 中的累加器计算多项式的计算问题

    背景 我需要编写一个谓词 eval P A R 其中 P表示多项式系数列表 即1 2x 3x 2表示为 1 2 3 A 代表 X 的值 R 是 X A 处多项式的结果 Example eval 3 1 2 3 R 产生 R 24 编辑 之前
  • 序言排列函数

    我是 Prolog 的新手 我知道排列的递归函数 即 per per L X P del X L L1 per L1 P 我想知道当我们收到时这个函数在最后一次迭代中的逻辑树per 它返回哪个元素 Sonia 您还没有给我们 del 谓词
  • 如何在 Prolog 中修复这个循环谓词?

    为什么这不能在 Prolog 中定义 已婚 married X Y married Y X 这些类型的循环谓词不允许吗 我该如何解决它 Thanks 如果我的语法错误请原谅我 我已经有一段时间没有使用 Prolog 了 典型的解决方案是在子
  • 在 dll 中嵌入 prolog 引擎

    我最近一直在开发一个嵌入 prolog 推理引擎的 C 应用程序 正如标题中所述 我现在尝试生成一个 DLL 而不是可执行文件 以便我可以在另一个项目中使用它 由于我是 DLL 开发的新手 我想我可以从一个小例子开始 我有3个文件 like
  • 如何提高词法分析效率?

    在解析一个 3 GB 的大文件时DCG https www metalevel at prolog dcg 效率很重要 我的词法分析器的当前版本主要使用 or 谓词 2 http www swi prolog org pldoc doc f
  • 获取 Prolog 中的解决方案列表

    我正在学习 Prolog 并且正在阅读一本名为 人工智能 Prolog 编程 的书 作为练习 我想学习如何扩展本书中的示例之一 有人可以帮忙吗 假设您有以下事实 parent pam bob pam is a parent of bob p
  • Prolog 变量查询中的“\+”问题

    我正在读 七周七种语言 atm 我对一些 Prolog 查询感到困惑 我不明白对 否 的回答 The friends pl文件看起来像这样 likes wallace cheese likes grommit cheese likes we
  • Prolog 中的聊天机器人

    我一直在尝试在序言中创建一个聊天机器人 作为作业 到目前为止 我已经在 pl 文件中创建了一个数据库 并且列出了很多可能的对话 我知道序言是这样工作的 例如如果我们有 Chatbot good 然后我们输入 Chatbot good 它会回
  • YAP Prolog 中的正向链接?

    我需要在某些 Prolog 问题中使用前向链接器 我想避免使用普通元解释器从头开始实现它 但如果没有其他选项可用 这就是我必须要做的 因为使用元解释器执行此操作会很慢 而且我我确信应该有一些好的实现 有人知道 YAP 或 SWI Prolo
  • 如何在 Prolog 中为变量(如字符串)分配多个值?

    今天早些时候 我寻求帮助以在序言中构建数据库以及如何通过参数搜索 有人提出了这个 您还可以向每个处理器添加术语列表 例如 processor pentium g4400 brand intel family pentium series g
  • Prolog 中的匹配元组

    为什么Prolog匹配 X Xs 包含更多元素的元组 一个例子 test2 X Xs write X nl test2 Xs test2 X write X nl test
  • 为什么在具体化中将 clpfd 变量分配给实际值?

    我正在开发一个 SWI Prolog 程序 该程序使用 CLP FD 约束来找到特定问题的解决方案 为此 我碰巧需要两个列表的 未定位 重叠 那是 List La长度为A List Lb长度为 B A gt B 未定位的重叠列表是La Lb
  • 非成员规则在 Prolog 中无法按预期工作

    我正在尝试在 Prolog 中创建一个迷宫程序 其目的是找到一条从迷宫起点到迷宫中心点 m 的路线 迷宫由使用四种颜色之一连接的正方形组成 蓝色 绿色 紫色或橙色 从起点到中心的路线遵循四种颜色的重复图案 我创建了以下代码 link2 A
  • Prolog 匹配 vs miniKanren 统一

    在 Prolog 人工智能编程中 Bratko 在第 58 页说了以下内容 Prolog 中的匹配对应于逻辑中所谓的统一 但是 我们避免使用 统一 这个词 因为出于效率原因 在大多数 Prolog 系统中 匹配的实现方式并不完全对应于统一
  • 如何在 Prolog 中计算数字序列的和

    任务是计算从0到M的自然数之和 我使用SWI Prolog编写了以下代码 my sum From To From gt To my sum From To S From 0 Next is 1 S is 1 my sum Next To S
  • 控制 Prolog 变量值选择

    灵感来自之前的一个问题 https stackoverflow com questions 41595786 using operator to save variables in a list我尝试实现一些可以枚举布尔表达式可能性的东西
  • Prolog 罗马数字(属性语法)

    我正在做一项作业prolog questions tagged prolog扫描数字列表并应返回该列表是否是有效的罗马数字以及数字的十进制值 前任 1 roman N I N 1 true 2 当我运行我认为应该工作的程序时 十进制值总是正
  • 如何为有效号码指定 DCG?

    我正在尝试为有效数字指定 DCG 如下所示 value Number gt valid number Number 基本上检查指定的值是否是数字 它也可能是变量 因此有必要检查 我不知道如何构建这个valid number不过 DCG 谓词
  • 如何找到排列的索引

    index List Idx Predicate will get List with permutation and I want to know index of permutation For example index 4 1 3
  • 谓词对于列表中的所有元素都必须为 true

    我有一组事实 likes john mary likes mary robert likes robert kate likes alan george likes alan mary likes george mary likes har

随机推荐

  • Android:标题栏和 ActionBar 有什么区别

    我无法判断它们是否是同一件事 而且它们似乎有不同的方法来删除它们 但我不确定这些是否只是做同一件事的多种方法 那么有区别吗 如果有区别的话是什么 Ref https developer android com reference andro
  • 捕获粘贴输入

    我正在寻找一种方法来清理粘贴到浏览器中的输入 这可以用 jQuery 实现吗 到目前为止我已经想出了这个 this live pasteEventName function e this is where i would like to s
  • Go:JSON 封送错误

    我正在 Go 中构建 JSON API 我想以 json 形式返回错误响应 响应示例 error Invalid request syntax 我认为我可以创建一个实现错误接口的包装结构 然后使用 Go 的 json 封送拆收器作为获取错误
  • Express 和 Redis 会话的过期时间

    我正在使用express和redis来使会话在我的系统上保持活动状态 我在设置 sessionCookie 上的 maxAge 时遇到一些问题 默认情况下 我读到的时间是 24 小时 但这对于保持其存活来说是很长的时间 我想设置大约 30
  • WordPress 按标题中的最后一个单词排序

    我有一个自定义帖子类型 员工 我需要让它在页面上按姓氏字母顺序显示员工 我知道解决方法是使用自定义元框并将名字和姓氏分成两个字段 但我试图避免这种情况 因为这看起来很黑客 不像仅使用标题字段那么干净 我有一个短代码 它将显示带有请求的员工
  • 使用 CSplitterWnd 在 CChildFrame 中创建多个视图

    我正在使用 MFC MDI 我需要创建如下视图 我的 ChildWnd 分为两部分 它们是LeftView CView 和RightView CScrollView LeftView 分为两部分 TreeView 和 FormView 我怎
  • Asp .NET 按钮 - OnClientClick="return function()" 与 OnClientClick="function()"

    在 asp net 用户控件中 我有一个按钮
  • 如何获取德威远程的 URL

    我希望能够获得像这样的 URLhttps github com user repo git给定一个远程名称 例如origin 到目前为止 我只设法获取提交哈希 gt gt gt from dulwich import porcelain g
  • 在 Python 中临时更改变量的值

    Python 3 4 提供了这个简洁的工具来临时重定向 stdout From https docs python org 3 4 library contextlib html contextlib redirect stdout wit
  • 通过 Rest c# httpClient 创建 jira 问题

    我读过 atlassian 上的一个答案https answers atlassian com questions 79902 using httpclient c to create a jira issue via rest gener
  • C# - 为什么在实现 IEnumerable 接口时要实现两个版本的 Current?

    我假设以下示例提供了我们在实现 IEnumerable 接口时应遵循的最佳实践 https learn microsoft com en us dotnet api system collections ienumerator movene
  • Plon 和 Asp.Net 集成

    How to 制作一个 Asp Net 应用程序来识别经过身份验证的克隆用户 他 她的 ID 角色和任何其他可用数据 反之亦然 在我的 asp net 应用程序中显示 plone 内容或在 plone 中显示一些特定于应用程序的数据 从 A
  • ColdFusion:在 CFC 中省略变量关键字是否安全?

    在 ColdFusion 组件 CFC 中 是否有必要对变量范围的变量使用完全限定名称 如果我改变这个 我会给自己带来麻烦吗
  • 如何在 TypeScript 中迭代通用对象的键?

    我需要迭代一个仅键入为 对象 的大对象 它包含未知数量的相同类型的对象 在较早的帖子中 我找到了在自定义 Symbol iterator 函数中使用生成器来使大对象可通过 for of 循环进行迭代的解决方案 但在我看来 现在已经是 201
  • numpy `arange` 超过最终值

    我原以为 numpy 的arange start end 生成 start end 范围内的值 下面的示例表明这并不总是正确的 最终值大于end import numpy as np start 2e9 end start 321 step
  • 导入文件时如何跳过第一行

    我正在尝试导入一个 xlsx文件输入Laravel5 7版本使用Maatwebsite excel版本 3 1 我想要实现的是跳过文件的第一行 以避免在数据库中导入列标题 我尝试使用版本 2 语法 调用skip method public
  • 强制从 US-ASCII 编码为 UTF-8 (iconv)

    我正在尝试将一堆文件从 US ASCII 转码为 UTF 8 为此 我使用 iconv iconv f US ASCII t UTF 8 file php gt file utf8 php 我的原始文件是 US ASCII 编码的 这使得转
  • WiX:旧版本不会在“添加/删除程序”列表中消失

    我有一个使用 WiX 安装和升级的 Windows 服务 效果很好 非常快 唯一的问题是 如果我从 1 0 升级到 1 1 两个副本在 添加 删除程序 列表中仍然有条目 那么 当我执行更新时 如何确保 WiX 删除 添加 删除程序 列表中旧
  • 使用 Chrome 开发者工具调试 onFocus 事件?断点后无法返回焦点

    我正在尝试调试 JavaScriptonFocus附加到页面上一堆文本框的事件 选择一个文本框然后按 Tab 键切换到下一个文本框时会出现此错误 我试图通过在其中放置一个断点来调试它onFocus使用 Chrome 开发者工具的事件 我面临
  • Prolog 时间重叠问题

    假设我有这个知识库 free ann slot time 8 0 time 9 0 free ann slot time 10 0 time 11 0 free bob slot time 7 0 time 8 30 free bob sl