First of all the behaviour happens with assoc and dict. So it is either a bagof issue or normal because the same behaviour I have also on scryer prolog. But when it is normal then I would like it to have an explanation.
I have the following code:
:- use_module(library( assoc)).
:- use_module(library( lists)).
rule1( _{v1:[A]}, (A=1)).
rule1( _{v2:A}, (A=2)).
rule2( _{v1:A}, (A=1)).
rule2( _{v2:A}, (A=2)).
solve1( RULE, DICT_OUT, L_OUT) :- true
, DICT_OUT = _{v1:_, v2:_}
, bagof( S, ( D, RULE, C)^( C=..[RULE, D, S], C, D >:< DICT_OUT), L_OUT)
.
When I call it then I get the following results:
?- solve1( rule1, D, L).
D = _{v1:_, v2:_A},
L = [_A=2] ;
D = _{v1:[_A], v2:_},
L = [_A=1].
?- solve1( rule2, D, L).
D = _{v1:_A, v2:_B},
L = [_A=1, _B=2].
I don’t understand where the difference comes from. What I want is the second, so I used as a solution this:
solve1_2( RULE, DICT_OUT, L_OUT) :- true
, DICT_OUT = _{v1:_, v2:_}
, bagof( EL, ( D, RULE, C,S)^( C=..[RULE, D, S], C, EL = ( D >:< DICT_OUT, S)), L_OUT0)
, maplist( [(C,S),S]>>(C), L_OUT0, L_OUT)
.
The output I want to have is:
(ins)?- solve1_2( rule1, D, L).
D = _{v1:[_A], v2:_B},
L = [_A=1, _B=2].
The assoc version looks like this:
rule3( AS, (A=1)) :- list_to_assoc([v1-[A]], AS).
rule3( AS, (A=2)) :- list_to_assoc([v2-A], AS).
rule4( AS, (A=1)) :- list_to_assoc([v1-A], AS).
rule4( AS, (A=2)) :- list_to_assoc([v2-A], AS).
assoc_unify( A1, A2) :- true
, bagof(V1=V2, K^( gen_assoc( K, A1, V1), gen_assoc( K, A2, V2)), L)
, maplist(call, L)
.
solve2( RULE, DICT_OUT, L_OUT) :- true
, list_to_assoc( [v1-_, v2-_], DICT_OUT)
, bagof( S, ( D, RULE, C)^( C=..[RULE, D, S], C, assoc_unify( D , DICT_OUT) ), L_OUT)
.
And the output is:
?- solve2( rule3, DICT_OUT, L_OUT).
DICT_OUT = t(v2, _A, <, t(v1, _, -, t, t), t),
L_OUT = [_A=2] ;
DICT_OUT = t(v2, _, <, t(v1, [_A], -, t, t), t),
L_OUT = [_A=1].
?- solve2( rule4, DICT_OUT, L_OUT).
DICT_OUT = t(v2, _A, <, t(v1, _B, -, t, t), t),
L_OUT = [_B=1, _A=2].
In the second variation DICT_OUT changes 2 times and bagof does not backtrack. I have no idea which of both outputs are actually considered wrong. When I take the bagof docs word by word then the backtracking version should be ok.
Is this a bug?
And is there an easier was to say bagof that DICT_OUT should be modified inplace?
Thanks in Advance,
Frank Schwidom