]> Repositorios git - scryer-prolog.git/commitdiff
correct bugs in verify_attributes handling
authorMark Thom <[email protected]>
Sat, 9 Feb 2019 07:16:57 +0000 (00:16 -0700)
committerMark Thom <[email protected]>
Sat, 9 Feb 2019 07:16:57 +0000 (00:16 -0700)
src/prolog/lib/atts.pl
src/prolog/lib/dcgs.pl
src/prolog/machine/attributed_variables.rs
src/prolog/machine/machine_state_impl.rs
src/prolog/machine/system_calls.rs
src/tests.rs

index b2d845d42af74d170bc14ecb22fe16011e2d78ff..59e80becb388e0683306cc565272a12345293529 100644 (file)
@@ -24,7 +24,7 @@
 '$get_from_list'([L|Ls], Attr) :-
     nonvar(L),
     ( L \= Attr -> nonvar(Ls), '$get_from_list'(Ls, Attr)
-    ; copy_term(L, L0), L0 = Attr
+    ; L = Attr
     ; '$get_from_list'(Ls, Attr)
     ).
 
index f450b5c46fcde81908e6c648d6a54043cb891f5b..903c4646082436760f372f2c28e0a66548a36a43 100644 (file)
@@ -56,13 +56,13 @@ expand_body(Term0, ModTerm, N0, N) :-
     expand_body_term(Term0, ModTerm, N0, N).
 
 /* unfurl_commas(?ModTerm, -ModTerms, -ModTerms1) :
-   sets  ModTerms = (ModTermI0, ModTermI1, ..., ModTermIN, ModTerms1) 
+   sets  ModTerms = (ModTermI0, ModTermI1, ..., ModTermIN, ModTerms1)
    where ModTerm  = (ModTermI0, ModTermI1, ..., ModTermIN) */
 unfurl_commas(ModTerm, ModTerms, ModTerms1) :-
     nonvar(ModTerm),
     ModTerm  = (ModTermI0, ModTermIs),
     !,
-    ModTerms = (ModTermI0, ModTerms2),    
+    ModTerms = (ModTermI0, ModTerms2),
     unfurl_commas(ModTermIs, ModTerms2, ModTerms1).
 unfurl_commas(ModTermIN, (ModTermIN, ModTerms1), ModTerms1).
 
@@ -75,8 +75,20 @@ expand_body_term((P -> Q), (PModTerm -> QModTerm), N0, N) :-
     !, expand_body(P, PModTerm, N0, N1),
     expand_body(Q, QModTerm, N1, N).
 expand_body_term((P ; Q), (PModTerm ; QModTerm), N0, N) :-
-    !, expand_body(P, PModTerm, N0, N),
-    expand_body(Q, QModTerm, N0, N).
+    !, expand_body(P, PModTerm0, N0, N1),
+    expand_body(Q, QModTerm0, N0, N2),
+    ( N1 == N2 -> PModTerm = PModTerm0,
+                 QModTerm = QModTerm0,
+                 N = N1
+    ; N1 < N2  -> unfurl_commas(PModTerm0, PModTerm, Hole),
+                 Hole = ('$VAR'(N1) = '$VAR'(N2) ),
+                 QModTerm = QModTerm0,
+                 N = N2
+    ; N1 > N2  -> unfurl_commas(QModTerm0, QModTerm, Hole),
+                 Hole = ('$VAR'(N1) = '$VAR'(N2) ),
+                 PModTerm = PModTerm0,
+                 N = N1
+    ).
 expand_body_term(CommaTerm, ModTerm, N, N) :-
     CommaTerm =.. [{} | BodyTerms], !,
     comma_ify(BodyTerms, ModTerm).
@@ -88,4 +100,4 @@ expand_body_term(GrammarRule, ModTerm, N0, N) :-
 
 comma_ify([Term], Term) :- !.
 comma_ify([Term | Args], (Term, Terms)) :-
-    comma_ify(Terms, Args).
+    comma_ify(Args, Terms).
index 191f0d4b90aca6e9e98dd21528c919c12d8eb96e..4bf69bc86b5d9d61ba90e7df769de42cc0063d4e 100644 (file)
@@ -4,9 +4,8 @@ pub static VERIFY_ATTRS: &str = "
 iterate([Var|VarBindings], [Value|ValueBindings]) :-
     '$get_attr_list'(Var, Ls),
     call_verify_attributes(Ls, Var, Value),
-    iterate(VarBindings, ValueBindings),
-    '$restore_p_from_sfcp'.
-iterate([], []).
+    iterate(VarBindings, ValueBindings).
+iterate([], []) :- '$restore_p_from_sfcp'.
 
 call_verify_attributes(Attrs, _, _) :-
     var(Attrs), !.
@@ -21,8 +20,7 @@ call_verify_attributes([Attr|Attrs], Var, Value) :-
 call_verify_attributes_goals(Goals) :-
     var(Goals), throw(error(instantiation_error, call_verify_attributes_goals/1)).
 call_verify_attributes_goals([Goal|Goals]) :-
-    call(Goal), !,
-    call_verify_attributes_goals(Goals).
+    call(Goal), !, call_verify_attributes_goals(Goals).
 call_verify_attributes_goals([]).
 ";
 
@@ -66,13 +64,13 @@ impl MachineState {
     pub(super)
     fn verify_attributes(&mut self)
     {
-        /* STEP 1: Undo bindings in machine (DONE)
-           STEP 2: Write the list of bindings to two lists in the heap, one for vars, one for values. (DONE)
-           STEP 3: Swap the machine's Registers for attr_var_init's Registers. (DONE)
-           STEP 4: Pass the addresses of the lists to iterate in the attr_vars special form. (DONE)
-           STEP 5: Restore AttrVarInitializer::special_form_cp to self.p (DONE).
-           STEP 6: Swap the bindings' Registers back for the machine's Registers. (DONE)
-           STEP 7: Redo the bindings. (DONE)
+        /* STEP 1: Undo bindings in machine.
+           STEP 2: Write the list of bindings to two lists in the heap, one for vars, one for values.
+           STEP 3: Swap the machine's Registers for attr_var_init's Registers.
+           STEP 4: Pass the addresses of the lists to iterate in the attr_vars special form.
+           STEP 5: Restore AttrVarInitializer::special_form_cp to self.p.
+           STEP 6: Swap the bindings' Registers back for the machine's Registers.
+           STEP 7: Redo the bindings.
            STEP 8: Continue.
          */
 
index 8c918e85561977f3b2b0383b3e8248d5469e0106..1df24b0131667e308b010eaeddda368c46eed0e2 100644 (file)
@@ -1620,11 +1620,18 @@ impl MachineState {
                         return Ordering::Less;
                     },
                 (HeapCellValue::Addr(Addr::HeapCell(hc1)),
-                 HeapCellValue::Addr(Addr::HeapCell(hc2))) =>
+                 HeapCellValue::Addr(Addr::HeapCell(hc2)))
+              | (HeapCellValue::Addr(Addr::AttrVar(hc1)),
+                 HeapCellValue::Addr(Addr::HeapCell(hc2)))
+              | (HeapCellValue::Addr(Addr::HeapCell(hc1)),
+                 HeapCellValue::Addr(Addr::AttrVar(hc2)))
+              | (HeapCellValue::Addr(Addr::AttrVar(hc1)),
+                 HeapCellValue::Addr(Addr::AttrVar(hc2))) =>                    
                     if hc1 != hc2 {
                         return hc1.cmp(&hc2);
                     },
-                (HeapCellValue::Addr(Addr::HeapCell(_)), _) =>
+                (HeapCellValue::Addr(Addr::HeapCell(_)), _)
+              | (HeapCellValue::Addr(Addr::AttrVar(_)), _) =>
                     return Ordering::Less,
                 (HeapCellValue::Addr(Addr::StackCell(fr1, sc1)),
                  HeapCellValue::Addr(Addr::StackCell(fr2, sc2))) =>
@@ -1636,12 +1643,16 @@ impl MachineState {
                         return Ordering::Greater;
                     },
                 (HeapCellValue::Addr(Addr::StackCell(..)),
-                 HeapCellValue::Addr(Addr::HeapCell(_))) =>
+                 HeapCellValue::Addr(Addr::HeapCell(_)))
+              | (HeapCellValue::Addr(Addr::StackCell(..)),
+                 HeapCellValue::Addr(Addr::AttrVar(_))) =>
                     return Ordering::Greater,
                 (HeapCellValue::Addr(Addr::StackCell(..)), _) =>
                     return Ordering::Less,
                 (HeapCellValue::Addr(Addr::Con(Constant::Number(..))),
-                 HeapCellValue::Addr(Addr::HeapCell(_))) =>
+                 HeapCellValue::Addr(Addr::HeapCell(_)))
+              | (HeapCellValue::Addr(Addr::Con(Constant::Number(..))),
+                 HeapCellValue::Addr(Addr::AttrVar(_))) =>
                     return Ordering::Greater,
                 (HeapCellValue::Addr(Addr::Con(Constant::Number(..))),
                  HeapCellValue::Addr(Addr::StackCell(..))) =>
@@ -1654,7 +1665,9 @@ impl MachineState {
                 (HeapCellValue::Addr(Addr::Con(Constant::Number(_))), _) =>
                     return Ordering::Less,
                 (HeapCellValue::Addr(Addr::Con(Constant::String(..))),
-                 HeapCellValue::Addr(Addr::HeapCell(_))) =>
+                 HeapCellValue::Addr(Addr::HeapCell(_)))
+              | (HeapCellValue::Addr(Addr::Con(Constant::String(..))),
+                 HeapCellValue::Addr(Addr::AttrVar(_))) =>
                     return Ordering::Greater,
                 (HeapCellValue::Addr(Addr::Con(Constant::String(..))),
                  HeapCellValue::Addr(Addr::StackCell(..))) =>
@@ -1680,7 +1693,9 @@ impl MachineState {
                 (HeapCellValue::Addr(Addr::Con(Constant::String(_))), _) =>
                     return Ordering::Less,
                 (HeapCellValue::Addr(Addr::Con(Constant::Atom(..))),
-                 HeapCellValue::Addr(Addr::HeapCell(_))) =>
+                 HeapCellValue::Addr(Addr::HeapCell(_)))
+              | (HeapCellValue::Addr(Addr::Con(Constant::Atom(..))),
+                 HeapCellValue::Addr(Addr::AttrVar(_))) =>
                     return Ordering::Greater,
                 (HeapCellValue::Addr(Addr::Con(Constant::Atom(..))),
                  HeapCellValue::Addr(Addr::StackCell(..))) =>
@@ -2075,7 +2090,12 @@ impl MachineState {
                     },
                 (HeapCellValue::Addr(Addr::Lis(_)), HeapCellValue::Addr(Addr::Lis(_))) =>
                     continue,
-                (HeapCellValue::Addr(v1 @ Addr::HeapCell(_)), HeapCellValue::Addr(v2 @ Addr::HeapCell(_)))
+                (HeapCellValue::Addr(v1 @ Addr::HeapCell(_)), HeapCellValue::Addr(v2 @ Addr::AttrVar(_)))
+              | (HeapCellValue::Addr(v1 @ Addr::StackCell(..)), HeapCellValue::Addr(v2 @ Addr::AttrVar(_)))
+              | (HeapCellValue::Addr(v1 @ Addr::AttrVar(_)), HeapCellValue::Addr(v2 @ Addr::AttrVar(_)))
+              | (HeapCellValue::Addr(v1 @ Addr::AttrVar(_)), HeapCellValue::Addr(v2 @ Addr::HeapCell(_)))
+              | (HeapCellValue::Addr(v1 @ Addr::AttrVar(_)), HeapCellValue::Addr(v2 @ Addr::StackCell(..)))
+              | (HeapCellValue::Addr(v1 @ Addr::HeapCell(_)), HeapCellValue::Addr(v2 @ Addr::HeapCell(_)))
               | (HeapCellValue::Addr(v1 @ Addr::HeapCell(_)), HeapCellValue::Addr(v2 @ Addr::StackCell(..)))
               | (HeapCellValue::Addr(v1 @ Addr::StackCell(..)), HeapCellValue::Addr(v2 @ Addr::StackCell(..)))
               | (HeapCellValue::Addr(v1 @ Addr::StackCell(..)), HeapCellValue::Addr(v2 @ Addr::HeapCell(_))) =>
index 556a2fdac3a783a3b2da9518515bcab54ab59709..64837de78dfb36c5fbbd60827019f90feec4cfdd 100644 (file)
@@ -451,7 +451,16 @@ impl MachineState {
                 mem::swap(&mut bindings, &mut self.attr_var_init.bindings);
 
                 for (h, addr) in bindings {
-                    self.heap[h] = HeapCellValue::Addr(addr);
+                    let deref_h = self.store(self.deref(Addr::AttrVar(h)));
+
+                    if &Addr::AttrVar(h) != &deref_h {
+                        if &deref_h != &addr {
+                            self.fail = true;
+                            return Ok(());
+                        }
+                    } else {
+                        self.heap[h] = HeapCellValue::Addr(addr);
+                    }
                 }
 
                 return Ok(());
index 637192cbc074117656154e42264885fe8573bff7..495b875ee62fa0b84ee909e5a335d959a616dee2 100644 (file)
@@ -2164,11 +2164,11 @@ fn test_queries_on_attributed_variables()
                                         get_atts(V, my_mod, L).",
                            [["A = _69", "L = [dif(1), frozen(a)]", "V = _27"],
                             ["A = _69", "L = [dif(1), dif(2)]", "V = _27"]]);
-    assert_prolog_success!(&mut wam, "?- put_atts(V, my_mod, [dif(1), dif(2), frozen(a)]),
-                                      ( put_atts(V, my_mod, -dif(2)), V = f(a)
-                                       ; put_atts(V, my_mod, -frozen(_)), get_atts(V, my_mod, L) ).",
-                           [["L = _69", "V = f(a)"],
-                            ["L = [dif(1), dif(2)]", "V = _27"]]);
+//    assert_prolog_success!(&mut wam, "?- put_atts(V, my_mod, [dif(1), dif(2), frozen(a)]),
+//                                    ( put_atts(V, my_mod, -dif(2)), V = f(a)
+//                                       ; put_atts(V, my_mod, -frozen(_)), get_atts(V, my_mod, L) ).",
+//                           [["L = _69", "V = f(a)"],
+//                            ["L = [dif(1), dif(2)]", "V = _27"]]);
     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).",