Utility Predicates

The following predicates are used in the puzzle solutions.

single_solution( +Goal ) holds when Goal has one ground solution. Operationally, Goal may produce several solutions but they must all be identical (==).

single_solution( Goal ) :-
    findall( Goal, Goal, [Solution|Solutions] ),
    same_solution( Solutions, Solution ),
    Solution = Goal.

same_solution( [], _Solution ).
same_solution( [Solution0|Solutions], Solution ) :-
    Solution0 == Solution,
    same_solution( Solutions, Solution ).

forall( +Enumerator, +Test ) is true if Enumerator and Test are goals and Test holds everywhere that Enumerator does. NB: forall/2 does not instantiate arguments further.

forall( Enumerator, Test ) :-
    \+ (call(Enumerator), \+ call(Test)).

member( ?Element, ?List ) holds when Element is a member of List.

member( H, [H|_] ).
member( H, [_|T] ) :-
    member( H, T ).

select( ?Element, ?List0, ?List1 ) is true if List1 is equal to List0 with Element removed.

select( H, [H|T], T ).
select( Element, [H|T0], [H|T1] ) :-
    select( Element, T0, T1 ).

memberchk( +Element, +List ) succeeds (once) if Element is a member of List.

memberchk( Element, List ) :-
    member( Element, List ),
    !.

between( +Lower, +Upper, ?Index ) is true if LowerIndexUpper. Two valid cases are possible:

between( Lower, Upper, Index ) :-
    integer( Lower ),
    integer( Upper ),
    Lower =< Upper,
    ( integer( Index ) ->    % Case 1: "test"
        Index >= Lower,
        Index =< Upper
    ; var( Index ) ->        % Case 2: "generate".
        generate_between( Lower, Upper, Index )
    ).

generate_between( Lower, Upper, Index ) :-
    ( Lower =:= Upper ->
        Index = Lower
    ;   Index = Lower
    ;   Next is Lower + 1,
        Next =< Upper,
        generate_between( Next, Upper, Index )
    ).

sum( +List, ?Sum ) holds when the List of numbers sum to Sum.

sum( [H|T], Sum ) :-
    sum1( T, H, Sum ).

sum1( [], Sum, Sum ).
sum1( [H|T], Sum0, Sum ):-
    Sum1 is Sum0 + H,
    sum1( T, Sum1, Sum ).

put_chars( +Chars ) if Chars is a (possibly empty) list of character codes and the corresponding characters are written to the current output stream.

put_chars( [] ).
put_chars( [Char|Chars] ) :-
    put( Char ),
    put_chars( Chars ).

get_chars( ?Chars ) if Chars is a (possibly empty) list of character codes read from the current input stream.

get_chars( Input ) :-
    get0( Char ),
    ( Char > -1 ->
        Input = [Char|Chars],
        get_chars( Chars )
    ; otherwise ->
        Input = []
    ).
The code is available as plain text here.
Home
Valid XHTML Basic 1.0!