Seeming* inconsistency between ground/1 and nonvar/2 predicates?

If this is intentional then so be it but I’d be curious why this is.

So with ground/1 you can pass in multiple variables like ground((X,Y)) and it works, like

?- when(ground((X,Y)),Z=3).
when(ground((X, Y)), Z=3).

?- when(ground((X,Y)),Z=3),X=1.
X = 1,
when(ground((1, Y)), Z=3).

?- when(ground((X,Y)),Z=3),X=1,Y=2.
X = 1,
Y = 2,
Z = 3.

However this doesn’t work with nonvar/1

?- when(nonvar((X,Y)),Z=3).
Z = 3.

Both docs show the same expected argument ground(@Term) and nonvar(@Term)

Because these are structures, rather than completely var/1, and that use of brackets is particularly unintuitive to newcomers, creating a “comma list” rather than a tuple: Surprising result with equals dot dot

?- (X,Y) == ','(X,Y).
true.

?- nonvar((X,Y)).
true.

?- nonvar([_]).
true.

var/1 means completely uninstantiated. A term or a list is not completely uninstantiated - check the variables within the term/list instead.

1 Like

Ahh ok that makes sense. Thanks Brebs!! ps. “equals dot dot” is called the “univ” operator :slight_smile:

So would I be correct in thinking that nonvar/1 will really only be true for a single un-instantiated variable or are there other cases?

@brebs reviewing the thread you linked some more, I guess my remaining question is, if ',' is an operator, what is the operation that it actually implements?

For example, '+'(2,3) makes sense to me as an operator because it actually implements an operation, ie.

?- X = '+'(2,3).
X = 2+3.

?- X is '+'(2,3).
X = 5.

How about ','? What is the use case for a construct like (2,3) (besides my original example with ground/1 — ?- when(ground([X,Y]),Z=3),X=1,Y=2. works for that as well)?

, is the functor, weird as that seems. Is not an operator. Can see with:

?- Term = (X,Y), Term =.. L.
Term = (X, Y),
L = [',', X, Y].

But I’m seeing in the other thread

"
As you can see, there is no distinction between a term that’s specified with an operator and one that’s given in “prefix” form:

?- (a,b) = ','(a,b)
true

Perhaps this is clearer:

?- (a+b) = '+'(a,b).
true.

"

so we’re comparing ‘,’ as an operator to ‘+’ as an operator. I understand the latter but not the former then…

X is 2+3 (or, equivalently, X is +(2,3)) is “meaningful” to you because it’s an interpretation of the structure +(2,3).

Instead of +(2,3), I could write foo(2,3) … what does that “mean”? The answer is – nothing; and neither does +(2,3) “mean” anything by itself.
In the context of the is/2 predicate, +(2,3) is _interpreted to mean arithmetic addition. But, by itself, the term +(2,3) is just a container with two items (2 and 3) and a name (+) - it’s an uninterpreted term.

(If you come from Lisp, you cann think of Prolog terms as implicitly quoted whereas in Lisp, they’re implicitly interpreted.)

1 Like

Alright, that makes sense, thank you, but I think my question remains; what is the use case for (X,Y) besides simply holding values? My ground/1 use case works with [X,Y] instead, and this other thread is recommending other constructs to group arbitrary values, such as v(…) and - tuples, with variations.

Is there a context in which ‘,’(X,Y) operates on its values like ‘+’ operates on its values in the context of is/2? Or when do we actually use this?

That’s the entire use case. And, for keeping a pair, the convention is to use -, e.g. X-Y.
Also, there are predicates that are designed to work with lists of pairs, e.g. keysort/2 and group_pairs_by_key/2.
For example:

?- setof(X-Y, (between(1,5,X), Y is X**2), Pairs), pairs_values(Pairs, Squares).
Pairs = [1-1,2-4,3-9,4-16,5-25],
Squares = [1,4,9,16,25].

BTW, this might help you understand how the “syntactic sugar” of operators is defined:

?- current_op(A,B,+).
A = 200,
B = fy ;
A = 500,
B = yfx.

?- op(500, yfx, foo). % define `foo` as an operator, same as `+`.
true.

?- X = 2 foo 3 .
X = 2 foo 3.

?- 2 foo 3 = foo(2,3).
true.

?- 2 foo 3 + 4 = +(foo(2,3),4).
true.

And if you want to see how operators have been processed syntactically, use write_canonical/1:

?- write_canonical(2 foo 3 + 4).
+(foo(2,3),4)
true.
2 Likes

An example:

?- U = 1+1, S is U.
U = 1+1,
S = 2.
1 Like

Thanks @brebs , thanks @peter.ludemann . Appreciate your time!