gpt4 book ai didi

prolog - 事实、谓词和规则

转载 作者:行者123 更新时间:2023-12-02 05:56:56 27 4
gpt4 key购买 nike

我决定学习 prolog 只是为了好玩,我正在看一些视频教程。我也在互联网上搜索了一些问题试图解决,但找不到解决方法。
我能够在纸上解决这个难题,但无法将其传递到代码中。

问题:

I have 8 candidates (Lia, Mel, Nanda, Olga, Rute, Sara, Tina, Pilar).
They will all be tested from Monday to Friday on the time 8:00 and 9:00.

我有一些规则,例如:

Sara HAS TO be tested on Wednesday at 9.
No girl will be tested on Wednesday at 8.
Pilar HAS TO tested BEFORE Nanda.
Olga HAS TO be tested in same day of Mel.
IF Lia is tested at 8 of any day, so Rute HAS TO be tested at 8 in a different day.

不想要完整的解决方案,我只是想要一些帮助来开始这个。

我想写点东西,但没有成功。

%   Facts   %
candidate(lia).
candidate(mel).
candidate(nanda).
candidate(olga).
candidate(pilar).
candidate(rute).
candidate(sara).
candidate(tina).

day(monday).
day(tuesday).
day(wednesday).
day(thursday).
day(friday).

time(8).
time(9).

/*Sara HAS TO be tested on Wednesday at 9*/
tested_on(sara, wednesday, 9).

/*No test will happen on Wednesday at 8*/
no_test(X, wednesday, 8) :- X == none.

我什至试图构建一个struct

cand(
sara,
date(wednesday, 9)
).

之后我的程序必须回答一些问题,例如:

Which would be the right list of candidates to be tested on 8:00 from monday to friday ?

我的主要想法是开始编写规则和事实,然后我会遍历所有规则来测试每一项。但我什至无法正确地写出事实规则...

最佳答案

Prolog 是一种声明性语言。重点关注对每个解决方案的内容的清晰描述。 Prolog 系统将为您完成剩下的工作。不要说:“我会遍历所有规则并测试每一条”。更好的说法是:“我陈述了适用于每个解决方案的属性。”这是因为,当您完成后,您的谓词可以在多个方向上使用:是的,您可以使用它来测试给定的解决方案。但您也可以使用它生成解决方案,并在可能的情况下完成部分填写的计划。

开头:

时间表(S):- ...

这可以读作:S 是一个时间表if ... 。现在,填写这些点:哪些属性包含在任何有效的时间表中?这些是任务中给出的约束,在 Prolog 中表示为目标

如您所愿,我不会为您提供完整的解决方案,而是提供一些入门提示。我使用 CLP(FD) 约束来声明性地说明所有要求。该代码最多只需稍作修改即可在 SICStus、SWI、YAP、GNU Prolog 和其他几个系统中运行。

首先,为了表示可用时隙,我使用整数 0..9。具体来说,我使用:

       Monday  Tuesday  Wednesday Thursday Friday
8:00: 0 2 4 6 8
9:00: 1 3 5 7 9

例如,星期四 9:00 用整数 7 表示。

每个候选者都是一个有限域变量,表示分配给候选者的时隙。

我将时间表表示为一个时间段列表,每个候选人一个,按照任务描述中的顺序排列。

只需使用 CLP(FD) 谓词对指定的约束进行编码即可。查看 Prolog 系统的文档以了解这些谓词的含义。例如,对于 SICStus Prolog,请查看 membership constraintsarithmetic constraints 。对于其他系统也是如此。

这是一个开始:

:- use_module(library(clpfd)).

schedule(Vars) :-
Vars = [Lia,Mel,Nanda,Olga,Rute,Sara,_Tina,Pilar],
all_different(Vars),
Vars ins 0..9,
Sara #= 5,
maplist(#\=(4), Vars),
Pilar #< Nanda.

如您所见,这与任务描述中出现的约束密切对应。例如,Sara 只能安排在周三 9:00,根据上表,这个特定时间段对应的是整数 5,变量 Sara 表示 Sara 被安排在哪个时间段。因此,我们声明约束Sara #= 5。同样,没有人可以安排在星期三 8:00。这个时隙对应于整数4,因此我们声明约束maplist(#\=(4), Vars),当且仅当每个变量Vars等于 ((#\=)/2) 到 4

我将最后两个约束的编码作为练习留给您。尝试对它们进行良好而紧凑的编码。

具有编码约束的示例解决方案:

?- Vs = [Lia,Mel,Nanda,Olga,Rute,Sara,Tina,Pilar], schedule(Vs), label(Vs).
Vs = [0, 1, 3, 7, 6, 5, 8, 2],
Lia = 0,
Mel = 1,
Nanda = 3,
Olga = 7,
Rute = 6,
Sara = 5,
Tina = 8,
Pilar = 2 .

请注意,巧合的是,这甚至满足了我们尚未显式编码的最后一个约束。

关于prolog - 事实、谓词和规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33084206/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com