Postica Ðenis
Postica Ðenis

Reputation: 13

Prolog: If one of the rules of a rule failed, then stop the program , else work as usually

It is interesting for me if there is any built-in tool, in Prolog, that would work for the following example:

parentRole(X,Y,Z):- parent(X,Y), male(X), !, Z=='father', !.
parentRole(X,Y,Z):- parent(X,Y), Z=='mother'.

I want the rule parent(X,Y) to stop the program (+return false) if parent(X,Y) failed, in rule #1, else go on as usually.

This way I'd be able to write:

parentRole(X,Y,Z):- parent(X,Y), male(X), !, Z=='father', !.
parentRole(X,Y,Z):- Z=='mother'.

Suppose facts are:

parent(myMom, i) male(i)

I expect for the scope:

parentRole(notMyMom, i, 'mother')

the program to stop and return false, but in the real, it fails at parent(X,Y) in the 1st rule, and tries to satisfy the 2nd, and it return true as Z=='mother'

Thanks.

Upvotes: 0

Views: 1119

Answers (2)

Tomas By
Tomas By

Reputation: 1394

So you want

parentRole(X,Y,Z) :-
  ( parent(X,Y) ->
    ( male(X) -> Z == 'father'
    ; Z == 'mother' ).
  ; fail ).

which is the same as

parentRole(X,Y,Z) :-
  parent(X,Y),
  ( male(X) -> Z == 'father' ; Z == 'mother' ).

Now your example fails, as expected.

Your comment: try this formatting

parentRole(X,Y,Z) :-
  ( parent(X,Y) ->
    ( male(X) ->
      ( Z == 'father' ->
        write('father')
      ; fail )
    ; ( Z == 'mother' ->
        write('mother')
      ; fail ) )
  ; fail ).

Upvotes: 1

Ruud Helderman
Ruud Helderman

Reputation: 11018

It makes sense to define a separate rule that verifies the gender.

parentRole(X, Y, Z) :- parent(X, Y), parentGender(X, Z).

parentGender(X, 'father') :- male(X).
parentGender(X, 'mother') :- \+ male(X).

parentRole now only has one rule, so it will fail immediately if parent fails.

Upvotes: 0

Related Questions