4

This is my prolog file.

male(bob).
male(john).

female(betty).
female(dana).

father(bob, john).
father(bob, dana).
mother(betty, john).
mother(betty, dana).

husband(X, Y) :- male(X), mother(Y, Z), father(X, Z).
wife(X, Y) :- female(X), father(Y, Z), mother(X, Z).
son(X, Y) :- male(X), mother(Y, X);female(X), father(Y, X).
daughter(X, Y) :- female(X), mother(Y, X);female(X), father(Y, X).
sister(X, Y) :- female(X), mother(Z, X), mother(Z, Y), X \= Y.
brother(X, Y) :- male(X), mother(Z, X), mother(Z, Y), X \= Y.

I want a name of rule if it returns true for any value x or y. Let's say x = betty and y = john.

mother(betty, john). <- this will meet so my rule should return 'mother'. Similarly if any other rule or fact meets true for some value x, y it should return that rule name.

How can I achieve something like that?

repeat
  • 18,496
  • 4
  • 54
  • 166
Pranav
  • 447
  • 5
  • 18
  • I'm not a Prolog expert but I don't think it's possible to do this kind of things. Prolog is very particular and dificult to understand when you come form the imperative or object oriented world. Take time to read more about Prolog and how it works. "Prolog, now!" Is a very good book to start. – Emrys Myrooin Sep 24 '15 at 21:29
  • @EmrysMyrooin There's [this](http://stackoverflow.com/questions/4518040/query-the-relation-between-two-people-in-a-prolog-family-tree) here. But the code is pretty obstructive. For me at least. – Pranav Sep 24 '15 at 21:38

2 Answers2

5

could be easy as

query_family(P1, P2, P) :-
    % current_predicate(P/2),
    member(P, [father, mother, husband, wife, son, daughter, sister, brother]),
    call(P, P1, P2).

that gives

?- query_family(betty, john, R).
R = mother ;
false.

?- query_family(betty, X, R).
X = john,
R = mother ;
X = dana,
R = mother ;
X = bob,
R = wife ;
X = bob,
R = wife ;
false.

the semicolon after the answer means 'gimme next'

CapelliC
  • 59,646
  • 5
  • 47
  • 90
1
$ swipl
?- ['facts'].
?- setof( Functor,
          Term^(member(Functor, [father, mother, husband, wife, son, daughter, sister, brother]),
           Term =.. [Functor, betty, john],
           once(Term)),
          Answer).

Answer = [mother].
?- 

If you want to avoid having to specify the list of functors of interest, you could use current_predicate(F/2).

peak
  • 105,803
  • 17
  • 152
  • 177
  • You can use `?- [facts].` as well, and having the query arguments `betty, john` deeply buried in such complex query doesn't sound very useful. What happens if some argument is a variable ? – CapelliC Sep 25 '15 at 07:22