0

Just started to learn Prolog, and cannot figure out how to get the result which involves "all true", for example:

preAction(4, 3).
preAction(4, 2).
preAction(2, 1).

action(4).
action(2).
action(1).

takeAction(X) :-
   action(X),
   preAction(X, Y),
   action(Y).

The expected result is 2, because action(2) and action(1) all true. But current result is 4 and 2. However the preAction of 4 is (3,2) and there is no action(3). This is not what I want.

If I tried to use negation, since 4's preAction is provable, still cannot figure out how to do it. Do you know how to do it?

false
  • 10,264
  • 13
  • 101
  • 209
lMolly
  • 19
  • 2

2 Answers2

0

You add another condition to your takeAction/1 predicate which uses negation:

takeAction(X) :-
    action(X),
    preAction(X, Y),
    action(Y),
    \+ (preAction(X, Z), \+ action(Z)).

The last line indicates that you want to exclude cases where X is a pre-action of Z, but Z is not an action (action(3) is false).

lurker
  • 56,987
  • 9
  • 69
  • 103
0

You test that every preAction(X, Y) has an action(X) :

takeAction(X) :- 
   action(X), 
   forall(preAction(X, Y), action(Y)).
joel76
  • 5,565
  • 1
  • 18
  • 22
  • thank you! although we are required not to use any "high level function", still very helpful to correct my logical thinking. – lMolly Feb 28 '15 at 02:42
  • @lMolly It is a very strange requirement, not to use "high level function" in Prolog. Either way, keep in mind that `forall(preAction(X, Y), action(Y))` by definition behaves as `\+ (preAction(X, Y), \+ action(Y))`, which basically is the other solution you got. –  Feb 28 '15 at 07:50