Prolog query question

618 Views Asked by At

I am new to prolog, and I have to write a program about the water jugs. My problem is regarding the initial state of jugs and the query formation. The query will be of the form:

?- myPredicate(args), filled(j1,1)

Meaning j1 filled with 1 gallon of water. j1 represents one of the jugs; the other is j2. Initally, I have

filled(j1,0) 
filled(j2,5) 
capacity(j1,2) 
capacity(j2,5) 

I would really be grateful if you provide me with information regarding the following:

Question A: Do I have to declare initial state of the j1 inside my program? filled(j1,0)

Question B: I need to make my program find a solution for filled(j1,1). For that I have some ideas, but what I am not sure about, is how to update filled(J,Volume) from query and myPredicate.

I am very confused since I have the initial state filled(j1,0) and now I have to create a filled(j1,1) in myPredicate. So I should have some form of filled(J,Volume) in myPredicate, so the query returns true instead of false.

How do I incorporate filled(J,Voume) inside myPredicate so when the above query is run, I can show correct answer?

1

There are 1 best solutions below

0
On

Example program with a passed-in parameter, an initial fact and an iterative task to perform. Iteration is by means of recursion. Before each reentry the value related to certain a parameter can be effectively updated for the next pass.

my_loop(N) :- N > 10.

my_loop(N) :- N =< 10,
    write(N), nl,
    Nextin is N + 1,
    my_loop(Nextin).

:- my_loop(1).

A:
The given information (facts) are needed by the program. They can be made available from keyboard input, as initial arguments to some predicate, or as facts in the database as you suggested. Also, only suggested for special situations, the facts can be hard-coded into some predicate or rule.

Below and above are example of passing the initial information in as parameters: :- my_predicate(args...).

If there are a lot of facts, the database is best. A few facts that need to change every time is best gotten from the keyboard. Otherwise, it probably doesn't matter.

:- my_predicate([fill(j1,0),fill(j2,5)], Answer),
    write(Answer),
    nl.

B:

See the my_ loop example:

In my_loop, the task of counting [1..10] is solved iteratively. The givens: 1 is passed in as a parameter, mainly because the program does the same thing over-and-over:
1. take a number (N); quit if it is too big. Otherwise...
2. print it.
3. calculate the next number (N+1)
4. repeat

10 is hard-coded. It could have been a fact: stop_after(10).

Now the data to be manipulated, the variable N in my_loop, and { j1,j2 } in myPredicate doesn't actually need to be re-assigned over-and-over again: See my_loop. Just re-enter the computation when it's time to do the same thing again, but with different parameters:

cap(j1,2).
cap(j2,5).

my_predicate(Status, Answer) :-
    got_juice(Status,0),
    Answer=Status.

%%% Instead of changing values, rerun comp. with new values
%%% based on a computation made from the old ones.
my_predicate([filled(j1,J1), filled(j2,J2)], Answer) :-
    Used is J1 + J2,
    got_juice(Used, J), J \= 0,
    cap(j1,C1), cap(C2),
    %% Use cap and filled to add more to filled..
    NextJ1 is J1 + ...,
    NextJ2 is J2 + ...,
    my_predicate(filled(j1,NextJ1), filled(..., Answer).

NOTE:
The predicate above is just to demonstrate iteration in Prolog, using the parameters of "myProgaram". For an actual implementation see the program suggested in the comment from matcheek.