From 2af08b31d2d9dd7c0374ef075ef4e500d52a9c47 Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Tue, 12 Mar 2019 18:45:42 -0600 Subject: [PATCH] change the semantics of put_atts/2 to better reflect those of SICSTus --- src/prolog/lib/atts.pl | 6 +++-- src/prolog/lib/dif.pl | 55 +++++++++++++++++----------------------- src/prolog/lib/freeze.pl | 7 +++-- src/tests.rs | 29 ++++++++++----------- 4 files changed, 44 insertions(+), 53 deletions(-) diff --git a/src/prolog/lib/atts.pl b/src/prolog/lib/atts.pl index 58555a27..6f3b109b 100644 --- a/src/prolog/lib/atts.pl +++ b/src/prolog/lib/atts.pl @@ -106,8 +106,10 @@ put_attr(Name, Arity) --> { functor(Attr, Name, Arity), numbervars(Attr, 0, Arity), V = '$VAR'(Arity) }, - [(put_atts(V, +Attr) :- !, functor(Attr, _, _), '$put_attr'(V, Attr)), - (put_atts(V, Attr) :- !, functor(Attr, _, _), '$put_attr'(V, Attr)), + [(put_atts(V, +Attr) :- !, functor(Attr, Head, Arity), functor(AttrForm, Head, Arity), + '$get_attr_list'(V, Ls), '$del_attr'(Ls, V, AttrForm), '$put_attr'(V, Attr)), + (put_atts(V, Attr) :- !, functor(Attr, Head, Arity), functor(AttrForm, Head, Arity), + '$get_attr_list'(V, Ls), '$del_attr'(Ls, V, AttrForm), '$put_attr'(V, Attr)), (put_atts(V, -Attr) :- !, functor(Attr, _, _), '$get_attr_list'(V, Ls), '$del_attr'(Ls, V, Attr))]. get_attr(Name, Arity) --> diff --git a/src/prolog/lib/dif.pl b/src/prolog/lib/dif.pl index e830a206..8153a38c 100644 --- a/src/prolog/lib/dif.pl +++ b/src/prolog/lib/dif.pl @@ -2,35 +2,29 @@ :- use_module(library(atts)). -:- attribute dif/2. +:- attribute dif/1. + +non_unif_member([X \== Y | Z], V, W) :- + ( X == V, Y == W -> true + ; non_unif_member(Z, V, W) + ). + +put_dif_att(Var, X, Y) :- + ( get_atts(Var, +dif(Z)) -> + ( non_unif_member(Z, X, Y) -> true + ; put_atts(Var, +dif([X \== Y | Z])) + ) + ; put_atts(Var, +dif([X \== Y])) + ). dif_set_variables([], _, _). dif_set_variables([Var|Vars], X, Y) :- - put_atts(Var, dif(X, Y)), + put_dif_att(Var, X, Y), dif_set_variables(Vars, X, Y). -verify_dif_attrs([dif(X, Y) | Attrs], Value, [X \== Y | Goals]) :- - ( get_atts(Value, +dif(X, Y)) -> true - ; put_atts(Value, +dif(X, Y)) - ), - verify_dif_attrs(Attrs, Value, Goals). -verify_dif_attrs([_ | Attrs], Value, Goals) :- - verify_dif_attrs(Attrs, Value, Goals). -verify_dif_attrs([], _, []). - -verify_dif_attrs_no_var([dif(X, Y) | Attrs], Value, [X \== Y | Goals]) :- - term_variables(Value, ValueVars), - dif_set_variables(ValueVars, X, Y), - verify_dif_attrs_no_var(Attrs, Value, Goals). -verify_dif_attrs_no_var([_ | Attrs], Value, Goals) :- - verify_dif_attrs_no_var(Attrs, Value, Goals). -verify_dif_attrs_no_var([], _, []). - verify_attributes(Var, Value, Goals) :- - ( get_atts(Var, Attrs) -> - ( var(Value) -> verify_dif_attrs(Attrs, Value, Goals) - ; verify_dif_attrs_no_var(Attrs, Value, Goals) - ) + ( get_atts(Var, +dif(Goals)) -> true + ; Goals = [] ). % Probably the world's worst dif/2 implementation. I'm open to @@ -42,13 +36,10 @@ dif(X, Y) :- X \== Y, dif_set_variables(YVars, X, Y) ). -gather_dif_goals(Attrs, _) :- - var(Attrs), !. -gather_dif_goals([dif(X, Y) | Attrs], [dif(X, Y) | Goals]) :- - gather_dif_goals(Attrs, Goals). -gather_dif_goals([_ | Attrs], Goals) :- - gather_dif_goals(Attrs, Goals). +gather_dif_goals([], _). +gather_dif_goals([(X \== Y) | Goals0], [dif(X, Y) | Goals]) :- + gather_dif_goals(Goals0, Goals). -attribute_goals(X, Goal) :- - '$get_attr_list'(X, Attrs), - gather_dif_goals(Attrs, Goal). +attribute_goals(X, Goals) :- + get_atts(X, +dif(Goals0)), + gather_dif_goals(Goals0, Goals). diff --git a/src/prolog/lib/freeze.pl b/src/prolog/lib/freeze.pl index ae0669d0..2eb24951 100644 --- a/src/prolog/lib/freeze.pl +++ b/src/prolog/lib/freeze.pl @@ -8,8 +8,7 @@ verify_attributes(Var, Other, Goals) :- get_atts(Var, frozen(Fa)), !, % are we involved? ( var(Other) -> % must be attributed then ( get_atts(Other, frozen(Fb)) % has a pending goal? - -> put_atts(Other, -frozen(Fb)), - put_atts(Other, frozen((Fb,Fa))) % rescue conjunction + -> put_atts(Other, frozen((Fb,Fa))) % rescue conjunction ; put_atts(Other, frozen(Fa)) % rescue the pending goal ), Goals = [] @@ -23,8 +22,8 @@ freeze(X, Goal) :- gather_freeze_goals(Attrs, _, _) :- var(Attrs), !. -gather_freeze_goals([frozen(X) | Attrs], Var, [frozen(Var, X) | Goals]) :- - gather_freeze_goals(Attrs, Var, Goals). +gather_freeze_goals([frozen(X) | _], Var, [frozen(Var, X) | _]) :- + !. gather_freeze_goals([_ | Attrs], Var, Goals) :- gather_freeze_goals(Attrs, Var, Goals). diff --git a/src/tests.rs b/src/tests.rs index b2ece073..dd27affb 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -2363,42 +2363,41 @@ fn test_queries_on_attributed_variables() assert_prolog_success!(&mut wam, "?- ( put_atts(V, my_mod, dif(1)) ; put_atts(V, my_mod, dif(2)) ), get_atts(V, my_mod, L).", - [["L = [dif(1)]", "V = _12"], - ["L = [dif(2)]", "V = _12"]]); + [["L = [dif(1)]", "V = _10"], + ["L = [dif(2)]", "V = _10"]]); assert_prolog_success!(&mut wam, "?- put_atts(V, my_mod, frozen(a)), ( put_atts(V, my_mod, dif(1)) ; put_atts(V, my_mod, -frozen(a)), put_atts(V, my_mod, dif(2)) ; put_atts(V, my_mod, dif(different)) ), get_atts(V, my_mod, Ls).", - [["Ls = [frozen(a), dif(1)]", "V = _12"], - ["Ls = [dif(2)]", "V = _12"], - ["Ls = [frozen(a), dif(different)]", "V = _12"]]); + [["Ls = [frozen(a), dif(1)]", "V = _10"], + ["Ls = [dif(2)]", "V = _10"], + ["Ls = [frozen(a), dif(different)]", "V = _10"]]); assert_prolog_success!(&mut wam, "?- put_atts(V, my_mod, [dif(1), dif(2), frozen(a)]), ( put_atts(V, my_mod, -dif(2)); put_atts(V, my_mod, -frozen(A)) ), get_atts(V, my_mod, L).", - [["A = _69", "L = [dif(1), frozen(a)]", "V = _27"], - ["A = _69", "L = [dif(1), dif(2)]", "V = _27"]]); + [["A = _71", "L = [frozen(a)]", "V = _25"], + ["A = _71", "L = [dif(2)]", "V = _25"]]); assert_prolog_success!(&mut wam, "?- put_atts(V, my_mod, [dif(1), dif(2), frozen(a), frozen(b)]), ( put_atts(V, my_mod, -dif(2)) ; put_atts(V, my_mod, -frozen(A)) ), get_atts(V, my_mod, L).", - [["A = _97", "L = [dif(1), frozen(a), frozen(b)]", "V = _31"], - ["A = _97", "L = [dif(1), dif(2)]", "V = _31"]]); - assert_prolog_failure!(&mut wam, "?- put_atts(V, my_mod, [dif(1), dif(2), frozen(a), frozen(b)]), + [["A = _111", "L = [frozen(b)]", "V = _29"], + ["A = _111", "L = [dif(2)]", "V = _29"]]); + assert_prolog_success!(&mut wam, "?- put_atts(V, my_mod, [dif(1), dif(2), frozen(a), frozen(b)]), get_atts(V, my_mod, -dif(1))."); assert_prolog_success!(&mut wam, "?- put_atts(V, my_mod, [dif(1), dif(2), frozen(a), frozen(b)]), get_atts(V, my_mod, -dif(3))."); assert_prolog_success!(&mut wam, "?- put_atts(V, my_mod, [dif(1), dif(2), frozen(a), frozen(b)]), get_atts(V, my_mod, dif(X)).", - [["X = 1", "V = _31"], - ["X = 2", "V = _31"]]); + [["X = 2", "V = _29"]]); assert_prolog_success!(&mut wam, "?- put_atts(V, my_mod, [dif(1), dif(2), frozen(a), frozen(b)]), put_atts(V, my_mod, -dif(A)), get_atts(V, my_mod, Ls).", - [["A = _98", "Ls = [frozen(a), frozen(b)]", "V = _31"]]); + [["A = _112", "Ls = [frozen(b)]", "V = _29"]]); assert_prolog_success!(&mut wam, "?- put_atts(V, my_mod, [dif(1), frozen(a), dif(2), frozen(b)]), put_atts(V, my_mod, -dif(A)), get_atts(V, my_mod, Ls).", - [["A = _98", "Ls = [frozen(a), frozen(b)]", "V = _31"]]); + [["A = _114", "Ls = [frozen(b)]", "V = _29"]]); submit(&mut wam, include_str!("./prolog/examples/minatotask.pl")); submit(&mut wam, ":- use_module(library(zdd))."); @@ -2416,5 +2415,5 @@ fn test_queries_on_attributed_variables() Vs = [X,Y], variables_set_zdd(Vs, ZDD), X = 0.", - [["Vs = [0, _59]", "X = 0", "Y = _59", "ZDD = 0->b(true);_59->b(true);b(false)"]]); + [["Vs = [0, _58]", "X = 0", "Y = _58", "ZDD = 0->b(true);_58->b(true);b(false)"]]); } -- 2.54.0