Swi-prolog 双向子句/事实

Posted

技术标签:

【中文标题】Swi-prolog 双向子句/事实【英文标题】:Swi-prolog two-way clause/fact 【发布时间】:2017-02-14 11:15:11 【问题描述】:

我需要帮助在 Swi-Prolog 中描述以下事实:

克拉克和琼斯住在同一所房子里,一起下棋。

经理和建筑师住在同一栋房子里,没有其他员工住在那栋房子里。

我有这样的结构:

[person(_, _), person(_, _), ...]

person 描述如下:

person(Name, Occupation)

我正在解决的谜题包含更多事实,但我无法描述这些双向事实。

为了简单起见,我使解决方案非常类似于函数式编程,我将所有内容拆分为函数。我有一个名为fact1(List) 的方法,它接受前面描述的结构(person 结构列表)。

如何形容克拉克和琼斯住在同一所房子里?

name(clark).
name(jones).

name(person(Name, _), Name).
occupation(person(_, Occupation), Occupation).

fact1(List):-
   name(Clark, clark),
   name(Jones, jones),
   ???. % have references to Clark and Jones, but what now?

 

 

↓ 更新 ↓

整个拼图如下(我知道和上面的例子不符)。

Brown、Clark、Jones 和 Smith 是 Beartown 第一国民银行的会计师、出纳员、经理和行长,但不一定分别担任这些职务的人的名字。

    虽然收银员一直在打败他,但总裁会和别人下棋。

    经理和收银员都是比会计更好的棋手。

    琼斯和史密斯是隔壁邻居,晚上经常一起下棋。

    克拉克比琼斯下棋更好。

    会计师住在总裁附近,但不靠近任何其他人。

在朋友的帮助下,我设法通过预先执行一些逻辑任务来解决它。

我结合事实一、三和五,得到以下事实:

收银员只和总裁玩。

琼斯和史密斯住在一起,一起玩耍。

会计师与总裁同住。

结论:琼斯和史密斯既不能当总裁也不能当收银员,因为他们住在一起玩,但是总裁和会计住在一起,只和收银员一起玩。

然后我添加了以下限制,然后我得到了一个确定性的单一答案:

\+ member(person(jones, accountant), Persons)
\+ member(person(smith, accountant), Persons)
\+ member(person(jones, president), Persons)
\+ member(person(smith, president), Persons)

【问题讨论】:

这不是一个糟糕的开始,但可能有一种更 Prolog 式的方式来写下你的事实。如果您(在问题中)告诉我们您的最终目标是什么,那么建议一个可行的解决方案会更容易。 如果您搜索“爱因斯坦拼图”或“斑马拼图”,您可能会得到一些想法。这只是基于您的两个事实用英语表述的方式的猜测。 嘿鲍里斯!感谢您的建议。我设法解决了这个难题,如果您有兴趣,可以阅读更新后的原帖。 【参考方案1】:

不确定但是...如果您想选择一个普通的房子,我想您应该在您的个人结构中添加一个房子字段(您的示例仅包含姓名和职业)。

如果你的 person 结构是

 person(Name, Occupation, House)

如果您想检查名称为jonesclarke 的人是否共享同一所房子,并且假设您必须检查person 的列表,我建议创建一个子句getHouse/3 为关注

getHouse([person(Name, _, House) | _], Name, House).

getHouse([_ | T], Name, House) :-
  getHouse(T, Name, House).

从人员列表中提取给定名称的房屋(或给定房屋的名称)。

使用getHouse/3,我想你可以把你的fact1/1写成

fact1(L) :-
  getHouse(L, clarke, CommonHouse),
  getHouse(L, jones, CommonHouse).

【讨论】:

我真的不需要知道这个人的房子。目标是找出哪个名字与哪个职业相匹配。只有这样的事实,谁和谁住在一起,谁不和谁住在一起,以减少数据集。我想在那种情况下,没有必要添加 house 字段?

以上是关于Swi-prolog 双向子句/事实的主要内容,如果未能解决你的问题,请参考以下文章

Java双向链表删除节点

将 Spring Security(双向 SSL)配置为仅对 CORS 预检 OPTIONS 请求进行身份验证

Knockout.js如何与组件共享viewmodel observable以进行双向绑定

❤️数据结构入门❤️(1 - 4)- 双向链表

带头节点的双向链表

双向bfs和双向dfs