最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

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

programmeradmin1浏览0评论

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.
发布评论

评论列表(0)

  1. 暂无评论