I decided to start playing with Prolog (SWI-Prolog). I wrote a program, and now I'm trying to write a simple main predicate so that I can create a .exe and run the program from the command line. That way, I can find true/false relationships from the command line rather than from the prolog GUI. However, I am having trouble understanding what actually goes in the main predicate. Here is the program so far:
mother(tim, anna).
mother(anna, fanny).
mother(daniel, fanny).
mother(celine, gertrude).
father(tim, bernd).
father(anna, ephraim).
father(daniel, ephraim).
father(celine, daniel).
parent(X,Y) :- mother(X,Y).
parent(X,Y) :- father(X,Y).
ancestor(X, Y) :- parent(X, Y).
ancestor(X, Y) :- parent(X, Z), ancestor(Z, Y).
First Try:
I put all of the relationship definitions in a predicate called family_func().Then, I tried to call that function from main by typing main. into the command line. I expected to be able to start finding relationships like I did before I created the predicates, but instead, the program started with this error:
ERROR: c:/.../ancestor.pl:18:0: Syntax error: Operator expected
Here is the code:
family_func():-
mother(tim, anna).
...
parent(X,Y) :- mother(X,Y).
...
main:-
family_func().
Second Try:
I tried putting all of the definitions in the main predicate. I expected to be able to type main. and then have the program pause and wait for me to start entering clauses (almost like in Java where you run a program and it waits for user input). Instead, when I typed main., it returned false.
Question 1:
I am used to writing code in Java. So, in my mind, The first thing I tried should work. I basically defined local variables in family_func() and then I called smaller "methods" (i.e. parent(X,Y) :- mother(X,Y).) that should find the relationships between those variables. When I call main, at the very least, I would have expected the program to wait for me to enter the relationship, return the result, and then close. Why doesn't this work?
Question 2:
How would I actually write a main predicate? Are there any good examples for a program like this? I've tried the example here, but couldn't get it to work.
Thanks for any help.
Edit:
New Attempt - main. returns false, and running parent(tim, anna). right after running main. returns false even though it should be true.
:- dynamic mother/2.
:- dynamic father/2.
family_func:-
assert(mother(tim, anna)).
assert(father(tim, bernd)).
parent(X,Y) :- mother(X,Y).
parent(X,Y) :- father(X,Y).
ancestor(X, Y) :- parent(X, Y).
ancestor(X, Y) :- parent(X, Z), ancestor(Z, Y).
main:-
family_func.
Edit:
Just in case anyone else needs to know, as @CapelliC states in the comments under the answer, there needs to be a comma between calls. For example:
family_func:-
assert(mother(tim, anna)),
assert(mother(anna, fanny)),
assert(mother(daniel, fanny)),
assert(mother(celine, gertrude)),
assert(father(tim, bernd)),
assert(father(anna, ephraim)),
assert(father(daniel, ephraim)),
assert(father(celine, daniel)).
mother_child/2,father_child/2andparent_of/2to clearly denote what each argument means. This will make your code a lot more readable and easier to think about for you and others. Thes syntax error stems from trying to embed the definition of one predicate within another, which is not possible. - mat