Search code examples
prolog

Prolog: legal_time(between(S,E)) not showing solutions


My legal_time predicate should be outputting when entered legal_time(X).

 X = between(11, 12) ;
 X = between(11, 12.5) ;
 X = between(14, 15) ;
 X = between(14, 15.5) ;
 X = between(15, 16) ;
 X = between(15, 16.5) ;
false .

But it just says false and quits. Doesn't let me type anything more. Here are the predicates given to us, all I had to do was write the legal_time. But it's not working. any ideas?

is_member(X, [X|_]).
is_member(X, [_|L]) :- is_member(X, L).

/* legal duration */
legal_duration(1).
legal_duration(1.5).

/* legal start time of a class */
start_time_list([11, 12, 14, 15]).

/* legal end time of a class */
end_time_list( [12, 12.5, 14, 14.5, 15, 15.5, 16, 16.5]).

/* 
 *  implement a legal_time(between(S, E)) predicate to generate legal combinations
 *  of S and E such that 
 *  1. S is from the list of the legal start time 
 *  2. E is from the list of the legal end time
 *  3. S-E is a legal duration
 */
 legal_time(between(S,E)) :-
    start_time_list(SL),
    end_time_list(EL),
    is_member(S, SL), 
    is_member(E, EL), 
    legal_duration(E-S).

Solution

  • The goal legal_duration(E-S) has a structure (-)/2 as an argument. Use instead

       D is E-S,
       legal_duration(D).
    

    However, please note that you are working with floating points which cannot exactly represent base 10, or base 5 mantissa.

    Also note that this might not work if E-S is a float but D is an integer and vice versa. For this reason, although less efficiently you might say:

       legal_duration(D),
       D =:= E-S.
    

    This is because floats an integers are of different type and thus not unifiable, but arithmetic evaluation still permits the right conversions:

    ?- 1 = 1.0.
       false.
    ?- 1 =:= 1.0,
       true.