0

I have this prolog file:

daughter(anna, vera).
daughter(vera, oleg).
daughter(olga, pavel).
daughter(olga, alla).
daughter(alla, lidia).
man(oleg).
man(victor).
man(pavel).
not(P) :- (call(P) -> fail ; true).
woman(X) :- not(man(X)).

?- woman(X). always returns false. ?- man(X). returns all three male entries though. I also tried woman(X) :- \+man(X). but certain syntax is not the problem it seems.

If I try to check a certain person it works: ?- woman(anna). returns true.

I'm quite new to prolog and can't even suggest what is wrong here.

UPD. I want all people who are not men to be classified as men. The question is - why can't I do woman(X) and get all non-men?

?- woman(anna).
true.

?- woman(X).
false.

?- man(X).
X = oleg ;
X = victor ;
X = pavel.

UPD2. Solution

The problem was caused by floundering as was pointed out in the comments. I needed woman(X) rule to implement this rule: mothers_names(X, Y) :- not(man(X)), daughter(Y,X).

In a nutshell, inverting the query works: mothers_names(X, Y) :- daughter(Y,X), not(man(X)). because first predicate makes X in not(man(X)) limited to several values.

Will Ness
  • 70,110
  • 9
  • 98
  • 181
mishkamashka
  • 73
  • 1
  • 6
  • `woman(peter)` also succeeds. check out "closed world assumption" and "negation as failure". – Will Ness Mar 01 '21 at 13:22
  • yep, it's correct behavior because ```peter``` is not listed as a man. The way this code works is "woman is everyone who is not a man". For example, ```woman(oleg)``` returns false. – mishkamashka Mar 01 '21 at 13:25
  • if you know the answer, what is the question? :) do you want `woman(lidia)` to succeed? what about `woman(maria)`? – Will Ness Mar 01 '21 at 13:27
  • In particular, **never call a predicate behind the `not` operator (better written as `\+`) when an unbound variable is involved**. As in `woman(X)`: _"Are there any women"?_ But Prolog will test "`\+ man(X)` _"There are women ... if there are no men"_ (a very contemporary stance I might add). This is not what you want. See: [floundering](https://github.com/dtonhofer/prolog_notes/blob/master/other_notes/about_negation/floundering.md). This Prolog finesse should have been "fixed" a couple of decades ago, but progress in logic pgr is not the fastest at this point in the history of computing. – David Tonhofer Mar 01 '21 at 13:39
  • @DavidTonhofer thanks a lot, floundering was the problem indeed – mishkamashka Mar 02 '21 at 09:05
  • @DavidTonhofer: Why don't you just offer `not(G_0) :- when(ground(G_0), \+ man(G_0))` instead of complaining? And yes, that definition does flounder from time to time, but the answers are correct (at least in systems that do show all involved constraints like SICStus or Scryer). – false Mar 02 '21 at 09:05
  • "I needed `woman(X)` rule to implement this rule: `mothers_names(X, Y) :- not(man(X)), daughter(Y,X).`" so why did you not include this crucial tidbit in the question from the start? – Will Ness Mar 02 '21 at 18:27

0 Answers0