I am not able to use a dict directly with bagof

Hi,

I cannot write:

?- bagof( (D.a + D.b) , D = d{ a : 1, b : 2}, L).
ERROR: Arguments are not sufficiently instantiated
ERROR: In:
ERROR:   [15] throw(error(instantiation_error,_2682))
ERROR:   [12] '<meta-call>'(user:user: ...) <foreign>
ERROR:   [11] toplevel_call(user:user: ...) at /usr/local/lib/swipl/boot/toplevel.pl:1317
ERROR: 
ERROR: Note: some frames are missing due to last-call optimization.
ERROR: Re-run your program in debug mode (:- debug.) to get more detail.

To get this working I introduced this TERM variable.

?- bagof( TERM , ( D = d{ a : 1, b : 2}, TERM = D.a + D.b), L).
D = d{a:1, b:2},
L = [1+2].

I guess this is a bug.

I am using SWI-Prolog (threaded, 64 bits, version 9.2.2).

Thanks in Advance,
Frank Schwidom

No. Dict.key appearing in a non-meta argument is always rewritten as

 Var is Dict.key,
 p(Var, ...)

I see no sensible rule why dict evaluation would have to happen after each result of the bagof goal as you write it explicitly. You might be able to do something with a notion of input and output arguments, but these have no formal status in standard Prolog and I fear the rules would get really complicated.

As a general rule of thumb, only use Dict.key in normal (non-meta) arguments in the body of clauses. Anything else is a can of worms. Only strict modes and types could (possibly) resolve that.

You can also take the dict out of the bagof:

?- D = d{a:1, b:2}, bagof(D.a+D.b, true, L).
D = d{a:1, b:2},
L = [1+2].

Not clear what is the intention.

This is just a simplified example. If you reduce it much more you can also just write


?- D = d{a:1, b:2}, L = [ D.a+D.b].
D = d{a:1, b:2},
L = [1+2].

% or

?- L = [1+2].
L = [1+2].

Normally in bagof you process a Goal which has multiple results:


(ins)?- L1 = [d{a:1, b:2},d{a:3, b:4}], bagof(D.a+D.b, member( D, L1), L).
ERROR: Arguments are not sufficiently instantiated
ERROR: In:
ERROR:   [15] throw(error(instantiation_error,_6714))
ERROR:   [12] '<meta-call>'(user:user: ...) <foreign>
ERROR:   [11] toplevel_call(user:user: ...) at /usr/local/lib/swipl/boot/toplevel.pl:1317
ERROR: 


Here it is possible to reformulate:


(ins)?- L1 = [d{a:1, b:2},d{a:3, b:4}], bagof(TERM, D^( member( D, L1), TERM=D.a+D.b), L).
L1 = [d{a:1, b:2}, d{a:3, b:4}],
L = [1+2, 3+4].


But I don’t like the additional TERM Variable.

With your idea I can fix the original problem:


?- L1 = [d{a:1, b:2},d{a:3, b:4}], D=_{a:_,b:_}, bagof(  D.a+D.b, member( D, L1), L).
L1 = [d{a:1, b:2}, d{a:3, b:4}],
D = d{a:_, b:_},
L = [1+2, 3+4].


I just need to define a skeleton by writing “D={a:,b:_}” before the bagof call.

Maybe it can be derived from L1.

Regards,
Frank Schwidom