Distinguish undefined from true or false

How to determine if a predicate is undefined under WFS?

With this program:

a :- undefined.

If we run

11 ?- call_delays(a,R).
R = system:undefined,
undefined.

So we see that R gets instantiated with system:undefined if the predicate is undefined.

But the following doesn’t work, because the conjunction of undefined and true results in undefined.

a :- undefined.

is_undefined(Pred) :-
   call_delays(Pred,R), 
   R == system:undefined
    -> true
   ; false.
12 ?- is_undefined(a).
undefined.

How then could we write is_undefined/1?

EDIT: Above I used ->, but I would like a version that doesn’t cut the search tree (like *->), but one thing at a time.

1 Like

Yes, I had it like that in the code, but pasted the wrong version. Fixed in the post (results are the same).

First of all, a predicate is not undefined (disregarding the old discussion about what is a predicate). Only answers (solutions) can be undefined. A query can thus return both normal and undefined answers. See https://swish.swi-prolog.org/p/russels%20paradox.swinb

Next, system:undefined is only one version of undefined. To decide that an answer is undefined use Delays \== true. Typically, programs will not return undefined unless they call undefined explicitly.

Hope this helps …

1 Like

This kind of clarification really helps, thanks!

That still doesn’t work:

a :- undefined.

is_undefined(Pred) :-
   call_delays(Pred,R),
   R \== true
   -> true
   ; false.
1 ?- is_undefined(a).
undefined.

What I would like to have is the following:

1 ?- is_undefined(a).
true.

Your definition is the same as below. Why cut the choice points?

is_undefined(Pred) :-
   call_delays(Pred,R),
   R \== true,
   !.

I think there are only two ways to get rid of the pending delay list which carries the undefined status:

  • Backtrack, i.e., use findall/3 or double negation if you only want a semidet answer.
  • Fill the table (by calling forall(Pred,true)) and use get_returns_and_tvs/3 (after get_calls/3) to read the table answers and their true/undefined status.

I’ve been coding in a procedural language for a couple of weeks (rust) and it has messed up my prolog mind, I hope I can get it back :grin:

I am at a loss here, need some help. Should not the following return some answers?

a :- undefined.
18 ?- forall(a,true), get_calls(a,T,R).
false. % Should I not get some answers here?

Success :slight_smile:

get_calls/2 returns tables for instances of its first argument. As a/0 is not tabled no such tables exist. If you want this to work on an arbitrary goal, findall/3 is your only hope.

I have no clue what you are really trying to achieve. A more high level view on your problem might give more accurate answers. Considering that XSB (from which all this is derived) does (AFAIK) not have what you want and these people have decades of experience using this in the real world, my suspicion is that you want something that you should not have wanted in the first place.

Ahh…I see why now.

I was just trying to learn WFS; in looking at the barber problem with findall(X,shaves(barber,X),Xs); I noticed that the result was [barber,mayor]; so the information about the barber answer being conditional was lost.

I surmised that there would be problems with findall, but that set me on a quest to see if I could reason when the answer of a predicate would be conditional (undefined), and that is why I tried to code is_undefined(...).

What do people do when they have a nondet WFS predicate and they want to get all the backtracking answers that are undefined? (or all true for that matter?) I can certainly see many real world problems when you would want to reason differently (programmatically) if the answer was conditional (e.g. the toplevel, reacts differently if the answer is conditional).

EDIT: I am thinking about WFS principally as a three-valued logic, but perhaps this is the wrong way to think about it.

Don’t ask me :slight_smile: I implemented this stuff with the help of Theresa Swift and David S. Warren, but so far I did little with it except for playing …

Anyway, to get the true answers I’d guess this will do:

?- findall(X,call_delays(shaves(barber,X),true), Xs).

And to get the undefined ones

?- findall(X,(call_delays(shaves(barber,X),Delays), Delays \== true), Xs).

In most cases you probably better refrain from using all solution predicates in the context of tabling. Quite often it is not a particularly good idea to represent solutions to a predicate as a list anyway. Just leave the set implicit, possibly except for preparing the final answer.

Hehehehe you are funny :grin:

This gives me a good idea; I wasn’t so off track as I thought.

This is what I was thinking about.