Reputation: 21
I'm getting 'Syntax error: Operator expected' and also the Warnings: 'Singleton variables: ... ".
Here's my code:
schwester_von(A,B) :-
weiblich(C),
mutter_von(C,A),
mutter_von(C,B),
A \== B.
grossvater_von(A,B) :-
maennlich(A),
(
vorfahr_von(A,C),
(
vater_von(C,B)
;
mutter_von(C,B).
vorfahr_von(A,B) :-
vater_von(A,B)
;
mutter_von(A,B)
;
(
(
vater_von(A,C)
;
mutter_von(A,C)
),
vorfahr_von(C,B)
).
einzelkind(A) :-
(
vater_von(B,A)
;
mutter_von(C,A)
),
not(
bruder_von(A,D)
;
schwester_von(A,E)
).
vater_von(Stefan,Barbara).
vater_von(Stefan,Anna-Lena).
mutter_von(Marianne,Barbara).
mutter_von(Marianne,Anna-Lena).
mutter_von(Barbara,Timo).
vater_von(Christopher,Timo).
mutter_von(Anna-Lena,Ursula).
mutter_von(Anna-Lena,Thomas).
vater_von(Christian,Ursula).
vater_von(Christian,Thomas).
mutter_von(Ursula,Uta).
vater_von(Ralf,Uta).
vater_von(Thomas,Sven).
mutter_von(Sabrina,Sven).
I tried to avoid the spaces after the opening bracket but the errors are still there.
Upvotes: 2
Views: 331
Reputation: 3805
I agree with the commenter who suggested you need a better editor. SWI-Prolog includes a version of emacs, which you can use right now. If you are on Windows, all it takes is probably File-open. Syntax and error highlighting will show you quickly what's wrong. As a beginner, you may be even better off with VSCode.
I would also suggest that you start to write you code in English, it's a good habit. For example, some reading this question will not understand what your predicates mean, which makes it harder to answer.
Now let's have a look at the code.
grossvater_von(A,B) :-
maennlich(A),
(
vorfahr_von(A,C),
(
vater_von(C,B)
;
mutter_von(C,B).
This causes the syntax error. You need closing parentheses:
grossvater_von(A,B) :-
maennlich(A),
(
vorfahr_von(A,C),
(
vater_von(C,B)
;
mutter_von(C,B)
)
).
But the logic is really muddled together. You define a grandfather as someone who's male (alright!), and also the ancestor of someone who is either the father or the mother of the grandchild. That's not right.
A
should not be some ancestor, but precisely the father of C
.father_of
(vater_von
) instead of ancestor
, you needn't even specify that he is male, but that's.parent_of
(elternteil_von
) predicate, so you don't need that many conjunctions. Try it!vorfahr_von(A,B) :-
vater_von(A,B)
;
mutter_von(A,B)
;
(
(
vater_von(A,C)
;
mutter_von(A,C)
),
vorfahr_von(C,B)
).
Again, this will be much clearer when you replace each instance of vater_von;mutter_von
with parent_of
(elternteil_von
). Same thing with brothers and sisters.
Now to:
vater_von(Stefan,Barbara).
That looks innocent, but will totally confuse you because it's absolutely wrong. Stefan
and Barbara
are free variables, and totally unrestricted. When you define it like that you can also ask
?- vater_von(pi, 3.14).
true
Because Prolog binds Stefan=pi
and Barbara=3.14
. That's also the reason for the "Singleton variable" warning. It means that these variables occur only once in the rule, which is often an indication for an error on your side, because they are not really useful like that.
Of course, you didn't mean to use variables in the first place, but atoms. Lowercase them or quote them, either is fine:
vater_von(stefan,barbara).
vater_von('Stefan','Barbara').
Even worse:
vater_von(Stefan,Anna-Lena).
Anna-Lena
is an application of the functor -
to two variables, Anna
and Lena
. Here, you just have to quote it:
vater_von('Stefan','Anna-Lena').
One more thing: You will also have noted the warnings about discontiguous predicates. As a rule, keep all the rules for a predicate together - first state all vater_von
facts, then all mutter_von
facts, don't mix them up.
It is possible to use a :- discontiguous
directive in cases where that is impractical.
Upvotes: 1