题
我要模拟家谱在序言。 我有对称的谓词的问题。 的事实:强>
parent(x,y).
male(x).
female(y).
age(x, number).
<强>规则:强>
blood_relation
是给我头痛。这是我做了什么:
blood_relation(X,Y):-ancestor(X,Y).
blood_relation(X,Y):-uncle(X,Y);brother(X,Y);sister(X,Y);(mother(Z,Y),sister(X,Z));(father(Z,Y),sister(X,Z));(father(Z,Y),brother(X,Z)).
blood_relation(X,Y):-uncle(X,Z),blood_relation(Z,Y).
和我得到我认为满意的结果(我有双重版画 - 我能解决这个问题),问题是,我想这种关系是对称的。这是不是现在。
blood_relation(johns_father, joh):yes
blood_relation(john,johns_father): no
so..is有办法解决这个问题。 我需要查询:所有对不在blood_relation ..
更新
什么样的关系,要满足第一条语句? blood_relation(X,Y): - blood_relation(X,Y)
。
sorry..it是一个坏的复制/ paste..it
blood_relation(X,Y):-ancestor(X,Y).
现在上面固定的。
这里有其他的规则:
father(X,Y):-parent(X,Y),male(X).
mother(X,Y):-parent(X,Y),female(X).
brother(X,Y):-parent(Z,X),parent(Z,Y),male(X).
sister(X,Y):-parent(Z,X),parent(Z,Y),female(X).
grandFather(X,Y):-parent(Z,Y),parent(X,Z),male(X).
grandMother(X,Y):-parent(Z,Y),parent(X,Z),female(X).
uncle(X,Y):-mother(Z,Y),brother(X,Z).
ancestor(X,Y):-ancestor(X,Y).
ancestor(X,Y):-parent(X,Z),ancestor(Z,Y).
母亲的兄弟是在叔叔的定义。这是一种奇怪的。我已经得到了我需要执行规则,我不知道我怎么能实现除此之外规则。我只是困惑。
不知道如何让blood_relation
对称?而not_blood_relation
是一个新的规则。我需要查询。这一次真的让我头疼。也许是因为关系是这样写垃圾。
和没有更多的事实。就这样。所有的规则,所有的事实。
查询.. not(blood_relation(X,Y))
不工作,我真的不知道为什么。
例如查询:
age(X,Y), Y>18,
not(parent(X,Z)),write(X),nl,fail.
工作得很好
解决方案
一个位看起来像一个家庭作业,是不是...
其中大部分序言的初学者不认为一个技巧就是列表模式匹配。认为就像一棵树的〔A1,[A2],[B2,[[E3],[F]]],[C2]]]如<tree
> = [根,[<tree1
>,<tree2
>,... ]]:
%Y is immediate child of X?
child(X,Y,[X|S]) :- member([Y|_],S).
%pick one tree in S and check
child(X,Y,[X|S]) :- member([Z|SS],S),child(Z,Y,[Z|SS]).
%X and Y end up with same root?
sib(X,Y,[R|T]) :- child(R,X,[R|T]), child(R,Y,[R|T]).
我认为你可以在这个像提高,采用双根,增加性别,给名树的成员的特定关系......
其他提示
在幼稚溶液以使一个特定的谓词对称不是来自一个体面一个那么远。对于一般性的缘故,让我们来看看一个友好关系,以人不会得到对叔伯之类绊倒了。
下面是一些事实细节友谊关系(其中,说,数字是用户ID和自变量的特定顺序从谁发起的友谊来了)。
friends(1,2).
friends(5,2).
friends(7,4).
您会开始觉得像“friends(A,B) :- friends(B,A).
”的规则会解决的事情正确的,但因为它告诉了序言,如果它只是交换的说法再一次它可能只是工作,这将导致你无限递归。有一个名为“@</2
”谓词,告诉你一个短期(甚至是一个变量)是否到来之前陆续在“术语的标准顺序”。技术含义是不是所有的重要位置,但我们关心的是,对于两个不同的方面,它是只对其中的一个排序正确的。我们可以用它来打破无限递归!
此单一的规则将使得“friend/2
”对称的照顾。
friends(A,B) :- A @< B, friends(B,A).
整齐,因为这是,有一个方法方式,您的应的承担大型项目。回想一下,在我的事实列表中的args来排序有一些实际意义(谁发起的友谊)。添加最后的规则毁将来此信息的访问,并且对于其他人阅读的代码,隐藏在一个单一的代码行,其易于在硬编码的数据的块的面忽略对称性。
Condsider的工业强度溶液:
friended(1,2).
friended(5,2).
friended(7,4).
friends(A,B) :- friended(A,B).
friends(A,B) :- friended(B,A).
这是笨重,但它不使用晦涩的谓词干净读取,并保留原始信息(你可能会再次有一天要在实际应用中)。
-
对于发现的对不的有特定的属性,确保你总是有一些谓词当您使用否定寻找实际个人提供上下文您的规则。
potential_enemies(A,B) :- user(A), user(B), \+ friends(A,B).
什么样的关系,要满足第一条语句?
blood_relation(X,Y):-blood_relation(X,Y).
这是不是告诉你任何东西,你不已经“知道”,打算给你带来递归头痛。至于“不”的答案,是看起来你已经得到了所有从查询,你会得到答案的,并解释只是告诉你,没有任何更多。
您真的应该张贴更多的事实,和叔叔/ 2的定义,是有一个原因你不匹配母亲的弟弟,只是她的姐姐?你有很多其他问题上下工夫: - )
有关的一切,是不是一个血液关系,尝试:
not_blood_relation(X, Y) :- blood_relation(X, Y), !, fail.
not_blood_relation(X, Y).
和问自己,为什么它的作品!