From a00d9ee5aea401b3f76ec1e7fa5ff2b9baeaaa65 Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Mon, 25 Dec 2017 13:36:03 -0700 Subject: [PATCH] correct ',', backtrack bugs --- src/prolog/ast.rs | 3 +- src/prolog/builtins.rs | 26 +++++----- src/prolog/io.rs | 6 +-- src/prolog/machine.rs | 105 ++++++++++++++++------------------------- src/prolog/macros.rs | 10 +--- 5 files changed, 61 insertions(+), 89 deletions(-) diff --git a/src/prolog/ast.rs b/src/prolog/ast.rs index 9e6f4935..12d8bf95 100644 --- a/src/prolog/ast.rs +++ b/src/prolog/ast.rs @@ -724,8 +724,7 @@ pub enum BuiltInInstruction { IsVar(RegType), ResetBlock, SetBall, - SetNeckCutPoint(RegType), - SetNonNeckCutPoint(RegType), + SetCutPoint(RegType), Succeed, Unify, UnwindStack diff --git a/src/prolog/builtins.rs b/src/prolog/builtins.rs index 8b47f093..2b99e3f8 100644 --- a/src/prolog/builtins.rs +++ b/src/prolog/builtins.rs @@ -122,36 +122,40 @@ fn get_builtins() -> Code { get_structure!(String::from(","), 2, temp_v!(2)), unify_variable!(temp_v!(1)), unify_variable!(temp_v!(2))], - set_neck_cut!(temp_v!(3)), + set_cp!(temp_v!(3)), goto!(83, 3), retry_me_else!(4), fact![get_constant!(Constant::from("!"), temp_v!(1)), get_constant!(Constant::from("!"), temp_v!(2))], - set_neck_cut!(temp_v!(3)), + set_cp!(temp_v!(3)), proceed!(), trust_me!(), fact![get_constant!(Constant::from("!"), temp_v!(1))], - set_neck_cut!(temp_v!(3)), + set_cp!(temp_v!(3)), query![put_value!(temp_v!(2), 1)], execute_n!(1), retry_me_else!(8), - allocate!(2), + allocate!(3), fact![get_structure!(String::from(","), 2, temp_v!(2)), unify_variable!(perm_v!(2)), - unify_variable!(perm_v!(1))], + unify_variable!(perm_v!(1)), + get_var_in_fact!(perm_v!(3), 3)], neck_cut!(), call_n!(1), query![put_unsafe_value!(2, 1), - put_unsafe_value!(1, 2)], + put_unsafe_value!(1, 2), + put_value!(perm_v!(3), 3)], deallocate!(), goto!(83, 3), - retry_me_else!(9), + retry_me_else!(10), allocate!(1), get_level!(), - fact![get_constant!(Constant::from("!"), temp_v!(2))], + fact![get_constant!(Constant::from("!"), temp_v!(2)), + get_var_in_fact!(perm_v!(1), 3)], neck_cut!(), call_n!(1), - set_non_neck_cut!(temp_v!(3)), + query![put_value!(perm_v!(1), 1)], + set_cp!(temp_v!(1)), deallocate!(), proceed!(), trust_me!(), @@ -161,7 +165,7 @@ fn get_builtins() -> Code { query![put_value!(perm_v!(1), 1)], deallocate!(), execute_n!(1), - allocate!(2), // (->)/2, 125. + allocate!(2), // (->)/2, 126. get_level!(), fact![get_var_in_fact!(perm_v!(2), 2)], call_n!(1), @@ -235,7 +239,7 @@ pub fn build_code_dir() -> (Code, CodeDir, OpDir) code_dir.insert((String::from(";"), 2), (PredicateKeyType::BuiltIn, 76)); code_dir.insert((String::from(","), 2), (PredicateKeyType::BuiltIn, 81)); - code_dir.insert((String::from("->"), 2), (PredicateKeyType::BuiltIn, 125)); + code_dir.insert((String::from("->"), 2), (PredicateKeyType::BuiltIn, 126)); (builtin_code, code_dir, op_dir) } diff --git a/src/prolog/io.rs b/src/prolog/io.rs index fda5b6a5..3774520f 100644 --- a/src/prolog/io.rs +++ b/src/prolog/io.rs @@ -172,10 +172,8 @@ impl fmt::Display for BuiltInInstruction { write!(f, "reset_block"), &BuiltInInstruction::SetBall => write!(f, "set_ball"), - &BuiltInInstruction::SetNeckCutPoint(r) => - write!(f, "set_neck_cp {}", r), - &BuiltInInstruction::SetNonNeckCutPoint(r) => - write!(f, "set_non_neck_cp {}", r), + &BuiltInInstruction::SetCutPoint(r) => + write!(f, "set_cp {}", r), &BuiltInInstruction::Succeed => write!(f, "true"), &BuiltInInstruction::UnwindStack => diff --git a/src/prolog/machine.rs b/src/prolog/machine.rs index 00a99f74..8c723981 100644 --- a/src/prolog/machine.rs +++ b/src/prolog/machine.rs @@ -349,29 +349,19 @@ impl Machine { fn backtrack(&mut self) { - let b0 = self.ms - .or_stack - .top() - .map(|fr| fr.b0) - .unwrap_or(0); - - let p = if self.ms.b > 0 { + if self.ms.b > 0 { let b = self.ms.b - 1; - self.ms.or_stack[b].bp - } else { - self.ms.p = CodePtr::TopLevel(0, 0); - return; - }; - - self.ms.p = p; + + self.ms.b0 = self.ms.or_stack[b].b0; + self.ms.p = self.ms.or_stack[b].bp; - if let CodePtr::TopLevel(_, p) = p { - self.ms.fail = p == 0; - self.ms.b0 = b0; - - return; + if let CodePtr::TopLevel(_, p) = self.ms.p { + self.ms.fail = p == 0; + } else { + self.ms.fail = false; + } } else { - self.ms.fail = false; + self.ms.p = CodePtr::TopLevel(0, 0); } } @@ -1665,24 +1655,19 @@ impl MachineState { self.p += 1; }, - &BuiltInInstruction::SetNeckCutPoint(r) => { + &BuiltInInstruction::SetCutPoint(r) => { let addr = self.store(self.deref(self[r].clone())); match addr { Addr::Con(Constant::Usize(nb)) => { - self.b = nb; - self.neck_cut(); - }, - _ => self.fail = true - }; - }, - &BuiltInInstruction::SetNonNeckCutPoint(r) => { - let addr = self.store(self.deref(self[r].clone())); + self.b0 = nb; - match addr { - Addr::Con(Constant::Usize(nb)) => { - self.b = nb; - self.non_neck_cut(); + if self.b > nb { + self.b = nb; + self.tidy_trail(); + } + + self.p += 1; }, _ => self.fail = true }; @@ -2025,37 +2010,19 @@ impl MachineState { } } - fn neck_cut(&mut self) - { - let b = self.b; - let b0 = self.b0; - - if b > b0 { - self.b = b0; - self.tidy_trail(); - } - - self.p += 1; - } - - fn non_neck_cut(&mut self) - { - let b = self.b; - let e = self.e; - let b0 = self.and_stack[e].b0; // STACK[E+2+1] - - if b > b0 { - self.b = b0; - self.tidy_trail(); - } - - self.p += 1; - } - fn execute_cut_instr(&mut self, instr: &CutInstruction) { match instr { - &CutInstruction::Cut => - self.non_neck_cut(), + &CutInstruction::NeckCut => { + let b = self.b; + let b0 = self.b0; + + if b > b0 { + self.b = b0; + self.tidy_trail(); + } + + self.p += 1; + }, &CutInstruction::GetLevel => { let b0 = self.b0; let e = self.e; @@ -2063,8 +2030,18 @@ impl MachineState { self.and_stack[e].b0 = b0; self.p += 1; }, - &CutInstruction::NeckCut => - self.neck_cut() + &CutInstruction::Cut => { + let b = self.b; + let e = self.e; + let b0 = self.and_stack[e].b0; // STACK[E+2+1] + + if b > b0 { + self.b = b0; + self.tidy_trail(); + } + + self.p += 1; + } } } diff --git a/src/prolog/macros.rs b/src/prolog/macros.rs index 680ee2b1..4474dd62 100644 --- a/src/prolog/macros.rs +++ b/src/prolog/macros.rs @@ -309,15 +309,9 @@ macro_rules! unify_variable { ) } -macro_rules! set_neck_cut { +macro_rules! set_cp { ($r:expr) => ( - Line::BuiltIn(BuiltInInstruction::SetNeckCutPoint($r)) - ) -} - -macro_rules! set_non_neck_cut { - ($r:expr) => ( - Line::BuiltIn(BuiltInInstruction::SetNonNeckCutPoint($r)) + Line::BuiltIn(BuiltInInstruction::SetCutPoint($r)) ) } -- 2.54.0