prolog - Eliminating three-valued logic predicates choice points with if_3 - Stack Overflow

I'm trying to completely remove the choice points of my logical or3 predicate that relates two lo

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?

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?

Share Improve this question edited Mar 16 at 15:06 Luiz asked Mar 14 at 17:39 LuizLuiz 1497 bronze badges 10
  • What do you mean by "unnecessary" or "useless" choice point? In each example, of the 2 distinct instantiations of the unbound variables that satisfy the query that you get, which would be unnecessary/useless, and how did you choose? – Scott Hunter Commented Mar 14 at 17:47
  • @ScottHunter the false at the end means Prolog is meaninglessly searching for answers and not finding any, i would like to remove this behaviour as it's pointless. – Luiz Commented Mar 14 at 21:15
  • There's no point in receiving no answer in a Prolog query, it should just give me all the valid answer, and only if my query does not find any answer it should report false, as in, 'invalid query'. – Luiz Commented Mar 14 at 21:16
  • 1 For clarification: the first sentence of this question ends in "that can be either true, false or 'u' (unknown)". These are all successes, from a constraint perspective, rather than failure. If "false" meant constraint failure then "false" could not possibly be a value. – brebs Commented Mar 16 at 12:49
  • 1 @Luiz false should be a value, for the normal usage of reification in which the result is a variable. If false is constraint failure, then the code must now additionally check for constraint failure, which is pointlessly awkward when it can just be a value (as in e.g. memberd_t). – brebs Commented Mar 16 at 15:18
 |  Show 5 more comments

2 Answers 2

Reset to default 3

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

The unwanted choice point can also be removed with the ISO built-in setof/3.

% @brebs' table
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).

andt(A, B, T) :-
    setof(t, X^and_or(A, B, T, X), _).
    
ort(A, B, T) :-
    setof(t, X^and_or(A, B, X, T), _).

?- andt(true, u, T).
   T = u.
?- ort(true, u, T).
   T = true.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744639342a4585345.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信