Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Facts, Predicates and Rules

I decided to study prolog just for fun, I'm watching some video tutorials. Also I searched on the internet some problems to try to solve, but Can't find a way to solve this.
I was able to solve this puzzle on paper, but I can't pass it into code.

The problem:

I have 8 candidates (Lia, Mel, Nanda, Olga, Rute, Sara, Tina, Pilar).
They will all be tested from Monday to Friday on the time 8:00 and 9:00.

And I have some rules like:

Sara HAS TO be tested on Wednesday at 9.
No girl will be tested on Wednesday at 8.
Pilar HAS TO tested BEFORE Nanda.
Olga HAS TO be tested in same day of Mel.
IF Lia is tested at 8 of any day, so Rute HAS TO be tested at 8 in a different day.

I don't want full solution, I just want some help to start with this.

I was trying to write something but without success.

%   Facts   %
candidate(lia).
candidate(mel).
candidate(nanda).
candidate(olga).
candidate(pilar).
candidate(rute).
candidate(sara).
candidate(tina).

day(monday).
day(tuesday).
day(wednesday).
day(thursday).
day(friday).

time(8).
time(9).  

/*Sara HAS TO be tested on Wednesday at 9*/
tested_on(sara, wednesday, 9).  

/*No test will happen on Wednesday at 8*/
no_test(X, wednesday, 8) :- X == none.  

I was even trying to build a struct

cand(
    sara,
    date(wednesday, 9)
    ).  

After that my program would have to answer some questions like:

Which would be the right list of candidates to be tested on 8:00 from monday to friday ?

My main idea was to start writing the rules and facts then I'd go through all the rules testing each one. But I can't even write the facts and rules right...

like image 661
Jupirao Bolado Avatar asked Mar 15 '26 07:03

Jupirao Bolado


1 Answers

Prolog is a declarative language. Focus on a clear description of what holds about every solution. The Prolog system will do the rest for you. Do not say: "I'd go through all the rules testing each one". Better say: "I state the properties that hold for every solution." This is because, when you are done, your predicate can be used in several directions: Yes, you can use it for testing a given solution. But you can also use it to generate solutions, and to complete partially filled schedules, if possible.

Begin with:

schedule(S) :- ...

This is read as: S is a schedule if ... . Now, fill in the dots: Which properties hold in any valid schedule? These are the constraints that are given in your task, stated in Prolog as goals.

As you wish, I do not give you a full solution, but a few hints to get you started. I am using CLP(FD) constraints to declaratively state all requirements. The code runs, with at most minor modifications, in SICStus, SWI, YAP, GNU Prolog and several other systems.

First, to represent the available time slots, I use integers 0..9. Specifically, I use:

       Monday  Tuesday  Wednesday Thursday Friday
8:00:    0        2         4        6       8
9:00:    1        3         5        7       9

For example, Thursday 9:00 is denoted by the integer 7.

Each candidate is a finite domain variable that denotes the time slot the candidate is assigned.

I represent a schedule as a list of time slots, one for each candidate, in the order they are stated in the task description.

It only remains to encode the specified constraints, using CLP(FD) predicates. Check out your Prolog system's documentation to see what these predicates mean. For example, for SICStus Prolog, check out membership constraints and arithmetic constraints. Likewise for other systems.

Here is a start:

:- use_module(library(clpfd)).

schedule(Vars) :-
        Vars = [Lia,Mel,Nanda,Olga,Rute,Sara,_Tina,Pilar],
        all_different(Vars),
        Vars ins 0..9,
        Sara #= 5,
        maplist(#\=(4), Vars),
        Pilar #< Nanda.

As you see, this closely corresponds to the constraints that appear in the task description. For example, Sara can only be scheduled on Wednesday at 9:00, and, according to the above table, this specific time slot corresponds to the integer 5, and the variable Sara denotes at which time slot Sara is scheduled. Therefore, we state the constraint Sara #= 5. Similarly, no one can be scheduled on Wednesday at 8:00. This time slot corresponds to the integer 4, and so we state the constraint maplist(#\=(4), Vars), which is true if and only if each variable in Vars is not equal ((#\=)/2) to 4.

I leave encoding the final two constraints as an exercise for you. Try to encode them nicely and compactly.

Sample solution with the encoded constraints:

?- Vs = [Lia,Mel,Nanda,Olga,Rute,Sara,Tina,Pilar], schedule(Vs), label(Vs).
Vs = [0, 1, 3, 7, 6, 5, 8, 2],
Lia = 0,
Mel = 1,
Nanda = 3,
Olga = 7,
Rute = 6,
Sara = 5,
Tina = 8,
Pilar = 2 .

Note that, coincidentally, this satisfies even the last constraint, which we did not yet encode explicitly.

like image 186
mat Avatar answered Mar 17 '26 04:03

mat



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!