Re: How to get a set response interactively

"Richard A. O'Keefe" <[email protected]> Thu, 10 Apr 2014 16:00:53 +1200
Newsgroups gmane.comp.ai.prolog.swi
Message-ID <[email protected]>
On 10/04/2014, at 11:52 AM, Ross Boylan wrote:Thanks.  That works like a charm.
> I thought from the manual it was supposed to be something with a + since
> the manual says
> "The construct +Var^Goal tells bagof/3 not to bind Var in Goal. bagof/3
> fails if Goal has no solutions."
> 
> Taking + to be a meta-notation doesn't seem to fit either, since in that
> role it usually means ground.

No, "+" never means "ground", it just means "not a variable".
Since the string "+Var^Goal" is not in an argument position
of a predicate being defined, it is somewhat confusing to have
the "+" there at all.

However, there *is* an example there.

4 ?- bagof(C, A^foo(A, B, C), Cs).

That clearly shows _^_ being used without a +.

The important thing is that bagof/3 and setof/3 
*will* report bindings for every variable that
occurs in the generator (either by including
instances in the result if the variable occurs
in the template, or by backtracking over bindings
if it is free in the generator) UNLESS YOU EXPLICITLY
SAY NOT TO.
	
There are some slightly wonky bits in the manual.
For example, the "control predicates" section has
something called "send_arrow/2", which points to
the documentation for (_ -> _), and _that_ says
	Please note that (If -> Then) acts as
	(If -> Then ; fail), making the construct
	fail if the condition fails.  This unusual
	semantics is part of the ISO and all
	de-facto Prolog standards.
If it is standard, how can it be "unusual"?  It
isn't even a Prolog innovation, but was copied from
previous languages, notably

	"The idea that if->then; represents a failed
         or undefined situation comes from the early
	 days of AI computing:  Prolog's syntax is
	 adapted from the <a>Lisp 1.5 progammer's
	 manual</a> which says
		A conditional expression has the
		following form:
		[p₁➞e₁;p₂➞e₂;…;p₁➞en]
		... 
		If none of the pi are true, then
		the value of the entire expression
		is undefined.
	Prolog's list syntax is also ultimately derived
	from that seminal work."

But I digress.  This bit is slightly wonky, but the
example should have made all clear.  Perhaps examples
of setof/3 would have been good.

> I must say I don't understand why setof and findall behave differently.

If they didn't, there'd be no point in having both of them,
would there?

findall/3 came first.  It finds all the solutions.
That's all it does.  It is just amazingly dumb about
what it does.  And that is precisely why it is
sometimes useful.

But one horrible consequence of being dumb is that
FINDALL QUERIES DO NOT NEST in any useful way.

Consider the example in the manual.

foo(a, b, c).
foo(a, b, d).
foo(b, c, e).
foo(b, c, f).
foo(c, c, g).

?- setof(X-Ys, setof(Y, Z^foo(X,Y,Z), Ys), L).

L = [a-[b], b-[c], c-[c]] 

Yes

This works.  For every X having at least one Y and Z (but
we don't care about the Z) such that foo(X, Y, Z), it
gives us a pair X-Ys, where Ys is the set of all fitting Y.

But

?- findall(X-Ys, findall(Y, foo(X,Y,_), Ys), L).

L = [_G343-[b, b, c, c, c]] 

Yes

This didn't tell us about _any_ particular X,
and it mashed up the Ys for all the Xs into a single list.
Not good.

Basically, _all_ the differences between findall/3 and
setof/3 are there so that nested queries make useful sense.

This should be explained in any Prolog textbook that
says anything about setof/3 at all.


>> Jan, SWI Prolog has made so many changes lately to make life
>> easier for some programmers; is there any chance of making it
>> complain loudly about single-occurrence variables in setof/3
>> or bagof/3 generators?
> I doubt that would have helped me.

It might not have helped you with the solution,
but it would certainly have told you what kind of problem you had.

_______________________________________________
SWI-Prolog mailing list
[email protected]
https://lists.iai.uni-bonn.de/mailman/listinfo.cgi/swi-prolog