【问题标题】:Unification(?) in Prolog [duplicate]Prolog中的统一(?)
【发布时间】:2013-05-16 23:27:43
【问题描述】:

我有一个学校项目,我必须与 Prolog 一起工作。这对我来说是全新的,所以我遇到了一些问题。

我有一个这样的列表:

List = [(_,_,_),(_,_,_),(_,_,_)]

我应该通过我必须创建的几个谓词从输入中接收有关每个成员的信息。

其中一个是以下类型:

predicate(M1,M2,M3, List)

它说 M1 是 M2 或 M3,但不是两者兼而有之。例如,

predicate((_,a,_),(2,_,_),(3,_,_),List)

表示带有“a”的成员在第一个字段中有 2 或 3。

我整晚都在尝试,但无法提出解决方案。我相信我必须使用统一,但不知道该怎么做。

我试过了:

predicate(M1,M2,M3,[_]) :- (M1=M2), not(M1=M3).
predicate(M1,M2,M3,[_]) :- (M1=M3), not(M1=M2).

这可能看起来很荒谬,但正如我所说,Prolog 对我来说是全新的,我无法完全掌握它的功能。

感谢任何提示。谢谢!

编辑:

例子:

person(name,age,job).
List = [(einstein,_,_),_,_].

所以现在我有一个 3 个人的列表,其中爱因斯坦排在第一位。

predicate = ((einstein,_,_),(_,87,_),(_,23,_), List).

List = [(einstein,87,_),_,_)];
List = [(einstein,23,_),_,_)].

以上是应用谓词后的 2 个可接受的列表。

这应该是一个简单的问题,但我想不通。

谢谢!

【问题讨论】:

  • 好吧,我试图在问题中解释它。不知道还要添加什么。谓词应该接收大约 3 个列表成员的属性,这意味着第一个将与其他两个成员中的一个相同。 (hifen 是下划线,这里不能写) predicate((einstein,-,-),(-,32,-),(-,45,-),List) 表示爱因斯坦要么是32要么是45例如,岁。
  • 已编辑 :) 希望现在更清楚了。
  • 很抱歉我没有看到这个问题。我搜索但没有注意到它。我相信它适用于我的问题。我会尽量充分利用它。谢谢!
  • 没问题,这里很标准……

标签: prolog unification


【解决方案1】:

我猜你应该在 List 中绑定元素:

predicate(M1, M2, M3, [M1, M2, M3]) :-
    M1 = M2, M1 \= M3
  ; M1 = M3, M1 \= M2.

编辑:在 cmets 之后

predicate(M1, M2, M3, List) :-
    member(M1, List),
    ( M1 = M2, M1 \= M3 ; M1 = M3, M1 \= M2 ).

Member/2 它是 Prolog 中列表与其元素之间最基本的关系。在这里它显示了底层引擎在搜索解决方案时绑定变量的能力。

您的数据产生

?- predicate((einstein,_,_),(_,87,_),(_,23,_), [E]).
E = (einstein, 87, _G3908) ;
E = (einstein, 23, _G3908).

【讨论】:

  • 感谢您的帮助,但我认为我没有正确解释自己。对不起。 M2 和 M3 应该在 M1 所在的列表之外。我已经编辑了这个问题,我认为现在可以理解了:D
  • 再次感谢。我已经测试了这段代码,但输出仍然不完美,但它已经接近了。我得到了这个:E = [(爱因斯坦,87,_G824),_G832,_G835]; E = [(爱因斯坦,23,_G824),_G832,_G835]; E = [(爱因斯坦,_G823,_G824),(爱因斯坦,87,_G842),_G835]; E = [(爱因斯坦,_G823,_G824),(爱因斯坦,23,_G842),_G835]; E = [(爱因斯坦,_G823,_G824),_G832,(爱因斯坦,87,_G842)]; E = [(爱因斯坦,_G823,_G824),_G832,(爱因斯坦,23,_G842)];
  • 抱歉,我不知道如何在此处正确格式化文本 :( 问题是它将爱因斯坦传播到列表的其余部分。有什么办法可以避免这种情况吗?
  • 在您的解决方案之后放置一个剪辑,这将提交完成的选择。或者使用一次/1,可以更清晰。但通常你不应该关心这一点,以从 Prolog 的声明性中获益。当然,如果适用,这取决于上下文。
【解决方案2】:

我会这样写:

predicate(M1,M2,M3,L):- member(M1,L),member(M1,[M2,M3]).

您说“它说 M1 是 M2 或 M3,但不是两者”,但我认为这是您的责任,作为该谓词的调用者。如果您提供了相等的 M2M3,显然您希望它们相等。如果你给它们提供了不同的东西,那么它们就是这样。

【讨论】:

  • 您好,感谢您的反馈。虽然我不太明白你的意思。假设我得到这个输入:谓词((爱因斯坦,-,-),(-,32,-),(-,-,游泳者),L)。它指出爱因斯坦不是 32 岁就是游泳者,但不是两者兼而有之。让 M1=M2, M1=M3 为真,这对我的谓词不起作用。
  • @bex 您没有解释/显示示例用法调用。也许我误解了你。
【解决方案3】:

Prolog 与其他编程语言非常不同。您的尝试并非不合理,但最好理解为:

predicate(M1,M1,M3,[_]) :- M1 \= M3.
predicate(M1,M2,M1,[_]) :- M1 \= M2.

这确实是说同样的事情,但是这个版本提请注意我们没有对第四个参数做任何事情,在这个公式中它可以是任何单元素列表。赔率很好,这不是你的意思。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-20
    相关资源
    最近更新 更多