Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Prolog中的统一(?)_Prolog_Unification - Fatal编程技术网

Prolog中的统一(?)

Prolog中的统一(?),prolog,unification,Prolog,Unification,我有一个学校项目,我必须与Prolog一起工作。这对我来说都是新鲜事,所以我有一些问题 我有这样一份清单: List = [(_,_,_),(_,_,_),(_,_,_)] 我应该通过我必须创建的几个谓词从每个成员的输入信息中接收信息 其中一个属于以下类型: predicate(M1,M2,M3, List) 它说M1是M2或M3,但不是两者都是。比如说, predicate((_,a,_),(2,_,_),(3,_,_),List) 声明带有“a”的成员在第一个字段中有2或3 我整晚都在

我有一个学校项目,我必须与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,_,_),_,_].
现在我有一份三个人的名单,爱因斯坦排在第一位

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

List = [(einstein,87,_),_,_)];
List = [(einstein,23,_),_,_)].
以上是应用谓词后可接受的两个列表

这应该是个简单的问题,但我想不出来


谢谢

我想您应该绑定列表中的元素:

predicate(M1, M2, M3, [M1, M2, M3]) :-
    M1 = M2, M1 \= M3
  ; M1 = M3, M1 \= M2.
编辑:在评论之后

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).

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

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

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

我会这样写:

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

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

嗯,我试着在问题中解释一下。不知道还有什么要补充的。谓词应该接收关于列表中3个成员的属性,这意味着第一个成员将与其他两个成员中的一个相同。(hifen是下划线,不能写在这里)谓词((爱因斯坦,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,列表)意味着爱因斯坦要么32岁,要么45岁。我搜索了一下,但没有注意到。我相信这适用于我的问题。我会尽量从中得到最大的收获。谢谢没问题,这里很标准……谢谢你的帮助,但我觉得我没有解释清楚。很抱歉M2和M3应该在M1所在的列表之外。我编辑了这个问题,我认为现在可以理解了:再次感谢。我已经测试了这段代码,输出仍然不完美,但已经接近完美了。我得到了这个:E=[(爱因斯坦,87,"G824),"G832,"G835];E=[(爱因斯坦,23,——G824),——G832,——G835];E=[(爱因斯坦,G823,G824),(爱因斯坦,87,G842),(G835];E=[(爱因斯坦,23岁,835岁];E=[(爱因斯坦,G823,G824),G832,(爱因斯坦,87,G842)];E=[(爱因斯坦,G823,G824),G832,(爱因斯坦,23,G842)];对不起,我不知道如何在此处正确设置文本格式:(问题是,它正在将einstein扩展到列表的其他部分。有什么办法可以避免这种情况吗?在解决方案后放一个cut,这将有助于完成选择。或者使用once/1,可能更清楚。但一般来说,为了从Prolog的声明性中获益,你不应该在意这一点。如果适用,当然,这取决于上下文。嘿,谢谢你的反馈。不过我不太明白你的意思。假设我得到这个输入:谓词((爱因斯坦,-),(,32,-),(,游泳运动员),L)。它说明爱因斯坦要么是32岁,要么是游泳运动员,但不是两者都是。M1=M2,M1=M3是真的,这与我的谓词不符。@bex您没有解释/显示示例用法调用。可能我误解了您。