Frage

Ich muß Stammbaum in Prolog simulieren. Und ich habe Problem der symetrical Prädikate. Daten:

parent(x,y).
male(x).
female(y).
age(x, number).

Regeln:

blood_relation gibt mir Kopfschmerzen. das ist, was ich getan habe:

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

, und ich bin immer ich denke, befriedigende Ergebnisse (ich habe Doppeldruck - kann ich dieses Problem beheben), Problem ist, dass ich möchte, dass diese Beziehung symmetrisch sein. Es ist jetzt nicht mehr.

blood_relation(johns_father, joh):yes 
blood_relation(john,johns_father): no

so..is es eine Möglichkeit, dies zu beheben. Und ich brauche Abfrage: Alle Paare, die nicht in blood_relation sind ..

Update:

  

Welche Arten von Beziehungen ist die erste Aussage sollte zufrieden zu stellen?   blood_relation (X, Y): - blood_relation (X, Y)

.

sorry..it ist eine schlechte Kopie / paste..it

blood_relation(X,Y):-ancestor(X,Y).

Jetzt oben festgelegt.

hier sind andere Regeln:

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

Mutter Bruder ist in Onkel Definition. Es ist irgendwie seltsam. Ich habe Regeln, die ich umsetzen müssen, und ich weiß nicht, wie ich Regeln außer dass umsetzen kann. Ich bin nur verwirrt.

Jede Idee, wie blood_relation symmetrisch zu machen? Und not_blood_relation ist eine neue Regel. Und ich brauche Abfrage. Dies gibt mir wirklich Kopfschmerzen. Vielleicht, weil Beziehung ist wie Mist geschrieben.

Und es gibt keine mehr Fakten. Das ist alles. Alle Regeln und alle Fakten.

query .. not(blood_relation(X,Y)) nicht funktioniert, und ich weiß wirklich nicht, warum. Zum Beispiel Abfrage:

age(X,Y), Y>18,  
not(parent(X,Z)),write(X),nl,fail.

funktioniert gut

War es hilfreich?

Lösung

Ein bisschen sieht aus wie ein Hausaufgaben, nicht wahr ...

Ein Trick, der die meisten Anfänger von Prolog nicht denkt, ist die Liste Pattern-Matching. Denken Sie an einem Baum wie [a1, [[a2], [b2, [[e3], [F3]]], [c2]]] wie in <tree> = [root [<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]).

Ich glaube, Sie auf diese wie weiter verbessern können, Paare als Wurzeln mit und fügte hinzu, Geschlechter, Namen zu spezifischen Beziehungen der Mitglieder des Baumes geben ...

Andere Tipps

Die naive Lösung eines bestimmtes Prädikat symmetrisch zu machen, ist nicht so weit von einem anständigen ein. Aus Gründen der Allgemeinheit, lassen Sie sich bei einer Freundschaft Beziehung suchen, damit die Menschen auf Onkel werden nicht gestolpert und dergleichen.

Hier sind einige Fakten eine Freundschaft Beziehung Detaillierung (wo, sagen, die Zahlen sind Benutzer-IDs und die bestimmte Reihenfolge der Argumente kamen aus, die die Freundschaft initiiert).

friends(1,2).
friends(5,2).
friends(7,4).

Sie würden denken, dass zunächst eine Regel wie „friends(A,B) :- friends(B,A).“ Dinge reparieren rechts würde, aber dies führt zu Endlosschleife, weil es Prolog sagt, dass, wenn es nur das Argument tauscht man mehr Zeit, es könnte funktionieren. Es ist ein Prädikat „@</2“ genannt, der Ihnen sagt, ob ein Begriff (auch eine Variable), bevor ein anderer kommt in der „Standard Reihenfolge der Begriffe“. Die technische Bedeutung ist gar nicht so wichtig, hier, aber was wir kümmern uns um ist, dass für zwei verschiedene Begriffe für eine Bestellung von ihnen nur wahr ist. Damit können wir die unendliche Rekursion brechen!

Die einzige Regel kümmern „friend/2“ symmetrisch zu machen.

friends(A,B) :- A @< B, friends(B,A).

Wie ordentlich wie das ist, gibt es einen Ansatz, wie Sie sollte nehmen für große Projekte. Es sei daran erinnert, dass die Reihenfolge der Argumente in meiner Liste der Fakten eine tatsächliche Bedeutung hatte (der die Freundschaft initiiert). Das Hinzufügen der letzte Regel zerstört zukünftigen Zugang zu diesen Informationen und für andere Leute den Code zu lesen, versteckt die symmetrische Eigenschaft in einer einzigen Codezeile, die im Gesicht ignorieren eines Blocks von hartcodierte Daten einfach ist.

Condsider der industrietauglichen Lösung:

friended(1,2).
friended(5,2).
friended(7,4).

friends(A,B) :- friended(A,B).
friends(A,B) :- friended(B,A).

Es ist sperriger, aber es liest sauber ohne obskure Prädikate zu verwenden und behält die ursprüngliche Information (die Sie einen Tag wieder in einer realen Anwendung wollen könnten).

-

Wie für Paare zu finden, die nicht hat eine bestimmte Eigenschaft, stellen Sie sicher, dass Sie immer etwas Prädikat enthalten in der Regel bietet Kontext, wenn Sie Negation verwenden für tatsächliche Personen zu suchen.

potential_enemies(A,B) :- user(A), user(B), \+ friends(A,B).

Welche Arten von Beziehungen ist die erste Aussage sollte zufrieden zu stellen?

blood_relation(X,Y):-blood_relation(X,Y).

Das sagt Ihnen nichts, was Sie „wissen“ nicht bereits und wird Ihnen Kopfschmerzen Rekursion verursachen. Wie für die ‚Nein‘ Antwort aussieht, ist wie Sie bereits alle Antworten aus der Abfrage bekommen haben, dass Sie sich erhalten, und der Dolmetscher sagen Ihnen, nur, dass es nicht mehr ist.

Sie sollten wirklich mehr Fakten zu veröffentlichen, und die Definition von Onkel / 2, und gibt es einen Grund, warum Sie nicht eine Mutter Bruder, nur ihre Schwester passend? Sie haben viele andere Themen zu arbeiten: -).

Für alles, was nicht blutsverwandt ist, versuchen Sie dies:

not_blood_relation(X, Y) :- blood_relation(X, Y), !, fail.
not_blood_relation(X, Y).

Und fragen Sie sich, warum es funktioniert!

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top