I'm trying to completely remove the choice points of my logical or/3 predicate that relates two logical variables and associates it with a third that can be either true or 'u' (unknown) (and when it's false, the predicate should fail).
Edit: adequated descriptions of the logical predicates to my own needs.
The simple predicate works:
or(A,B,true) :-
A = true, B = true ; A = true, B = false ; A = false, B = true.
or(A,B,u) :-
A = u, B = u; A = u, B = false ; A = false, B = u.
but yields multiple unnecessary choice points like:
?- or(A,false,C).
A = C, C = true ;
A = C, C = u ;
false.
I tried using if_/3 and reif package but i always end up with a choice point somewhere. This is one of the iterations I managed to make, but it still has a useless choice point in the end:
or3(A, B, C) :-
if_( C = u
, if_( A = u
, ( B = u ; B = false)
, ( A = false, B = u )
),
if_( C = true
, if_( A = true
, ( B = true ; B = false)
, ( A = false, B = true )
)
, false
)
).
?- or3(A,false,C).
Correct to: "tri_logic:or3(A,false,C)"? yes
A = C, C = u ;
A = C, C = true ;
false.
I also tried directly using =/3 and ;/3 to implement a version that only works for true values, but the results were even pretty much the same:
or3(A,B,C) :-
=( C, true, T),
;( ( A = true, B = true ), ( A = true, B = false ), T1 ),
;( T1=true, ( A = false, B = true), T).
?- or3(A,false,C).
Correct to: "tri_logic:or3(A,false,C)"? yes
A = C, C = u ;
A = C, C = true ;
false.
What am I missing here?
To prevent unwanted choicepoints, both parameters must be considered simultaneously. Whereas if_
considers a single value.
Can use the relational aspect of Prolog - list the possibilities:
% Using table to improve determinism
:- table and_or/4.
% Bool (or u), Bool (or u), AND, OR
and_or(true, true, true, true).
and_or(false, true, false, true).
and_or(u, true, u, true).
and_or(true, false, false, true).
and_or(false, false, false, false).
and_or(u, false, false, u).
and_or(true, u, u, true).
and_or(false, u, false, u).
and_or(u, u, u, u).
The table directive in swi-prolog is being used here to prevent unwanted choicepoints by indexing the and_or
lookup.
Then, it's simply a case of performing the lookup:
andt(A, B, T) :-
and_or(A, B, T, _).
ort(A, B, T) :-
and_or(A, B, _, T).
Examples:
?- andt(true, u, T).
T = u. % No unwanted choicepoint
?- ort(true, u, T).
T = true. % No unwanted choicepoint