From 1273e2d52d6b63b7acb7d5a5fa062e1802a72f21 Mon Sep 17 00:00:00 2001 From: Atul Bhosale Date: Mon, 23 Sep 2019 19:35:37 +0700 Subject: [PATCH] Format code using 'cargo fmt' --- src/main.rs | 12 +- src/prolog/allocator.rs | 40 +- src/prolog/arithmetic.rs | 386 ++- src/prolog/clause_types.rs | 105 +- src/prolog/codegen.rs | 654 ++-- src/prolog/debray_allocator.rs | 168 +- src/prolog/fixtures.rs | 93 +- src/prolog/forms.rs | 140 +- src/prolog/heap_iter.rs | 136 +- src/prolog/heap_print.rs | 585 ++-- src/prolog/indexing.rs | 158 +- src/prolog/instructions.rs | 533 +-- src/prolog/iterators.rs | 321 +- src/prolog/machine/and_stack.rs | 8 +- src/prolog/machine/attributed_variables.rs | 73 +- src/prolog/machine/code_repo.rs | 109 +- src/prolog/machine/compile.rs | 641 ++-- src/prolog/machine/copier.rs | 107 +- src/prolog/machine/dynamic_database.rs | 207 +- src/prolog/machine/heap.rs | 14 +- src/prolog/machine/machine_errors.rs | 361 +- src/prolog/machine/machine_indices.rs | 272 +- src/prolog/machine/machine_state.rs | 465 +-- src/prolog/machine/machine_state_impl.rs | 2323 +++++++------ src/prolog/machine/mod.rs | 490 +-- src/prolog/machine/modules.rs | 170 +- src/prolog/machine/or_stack.rs | 77 +- src/prolog/machine/system_calls.rs | 1327 ++++---- src/prolog/machine/term_expansion.rs | 193 +- src/prolog/machine/toplevel.rs | 713 ++-- src/prolog/macros.rs | 212 +- src/prolog/mod.rs | 20 +- src/prolog/read.rs | 71 +- src/prolog/targets.rs | 9 +- src/prolog/write.rs | 450 ++- src/tests.rs | 3572 +++++++++++++------- 36 files changed, 8789 insertions(+), 6426 deletions(-) diff --git a/src/main.rs b/src/main.rs index 412dff66..948c0abc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,12 @@ -#[macro_use] extern crate cfg_if; -#[macro_use] extern crate downcast; +#[macro_use] +extern crate cfg_if; +#[macro_use] +extern crate downcast; extern crate indexmap; -#[macro_use] extern crate prolog_parser; -#[macro_use] extern crate ref_thread_local; +#[macro_use] +extern crate prolog_parser; +#[macro_use] +extern crate ref_thread_local; cfg_if! { if #[cfg(feature = "readline_rs_compat")] { diff --git a/src/prolog/allocator.rs b/src/prolog/allocator.rs index 8ae88742..c98bb43f 100644 --- a/src/prolog/allocator.rs +++ b/src/prolog/allocator.rs @@ -8,19 +8,29 @@ use prolog::targets::*; use std::cell::Cell; use std::rc::Rc; -pub trait Allocator<'a> -{ +pub trait Allocator<'a> { fn new() -> Self; fn mark_anon_var(&mut self, Level, GenContext, &mut Vec) - where Target: CompilationTarget<'a>; + where + Target: CompilationTarget<'a>; fn mark_non_var(&mut self, Level, GenContext, &'a Cell, &mut Vec) - where Target: CompilationTarget<'a>; - fn mark_reserved_var(&mut self, Rc, Level, &'a Cell, GenContext, - &mut Vec, RegType, bool) - where Target: CompilationTarget<'a>; + where + Target: CompilationTarget<'a>; + fn mark_reserved_var( + &mut self, + Rc, + Level, + &'a Cell, + GenContext, + &mut Vec, + RegType, + bool, + ) where + Target: CompilationTarget<'a>; fn mark_var(&mut self, Rc, Level, &'a Cell, GenContext, &mut Vec) - where Target: CompilationTarget<'a>; + where + Target: CompilationTarget<'a>; fn reset(&mut self); fn reset_contents(&mut self) {} @@ -34,15 +44,15 @@ pub trait Allocator<'a> fn take_bindings(self) -> AllocVarDict; - fn drain_var_data(&mut self, vs: VariableFixtures<'a>) -> VariableFixtures<'a> - { + fn drain_var_data(&mut self, vs: VariableFixtures<'a>) -> VariableFixtures<'a> { let mut perm_vs = VariableFixtures::new(); for (var, (var_status, cells)) in vs.into_iter() { match var_status { VarStatus::Temp(chunk_num, tvd) => { - self.bindings_mut().insert(var.clone(), VarData::Temp(chunk_num, 0, tvd)); - }, + self.bindings_mut() + .insert(var.clone(), VarData::Temp(chunk_num, 0, tvd)); + } VarStatus::Perm(_) => { self.bindings_mut().insert(var.clone(), VarData::Perm(0)); perm_vs.insert(var, (var_status, cells)); @@ -54,7 +64,9 @@ pub trait Allocator<'a> } fn get(&self, var: Rc) -> RegType { - self.bindings().get(&var).map_or(temp_v!(0), |v| v.as_reg_type()) + self.bindings() + .get(&var) + .map_or(temp_v!(0), |v| v.as_reg_type()) } fn is_unbound(&self, var: Rc) -> bool { @@ -64,7 +76,7 @@ pub trait Allocator<'a> fn record_register(&mut self, var: Rc, r: RegType) { match self.bindings_mut().get_mut(&var).unwrap() { &mut VarData::Temp(_, ref mut s, _) => *s = r.reg_num(), - &mut VarData::Perm(ref mut s) => *s = r.reg_num() + &mut VarData::Perm(ref mut s) => *s = r.reg_num(), } } } diff --git a/src/prolog/arithmetic.rs b/src/prolog/arithmetic.rs index 9dd19865..c30b0a79 100644 --- a/src/prolog/arithmetic.rs +++ b/src/prolog/arithmetic.rs @@ -10,60 +10,66 @@ use prolog::machine::machine_errors::*; use prolog::machine::machine_indices::*; use prolog::ordered_float::*; -use prolog::rug::{Assign, Integer, Rational}; use prolog::rug::ops::PowAssign; +use prolog::rug::{Assign, Integer, Rational}; use std::cell::Cell; -use std::cmp::{Ordering, min, max}; +use std::cmp::{max, min, Ordering}; use std::f64; use std::num::FpCategory; -use std::ops::{Add, Sub, Div, Mul, Neg}; +use std::ops::{Add, Div, Mul, Neg, Sub}; use std::rc::Rc; use std::vec::Vec; pub struct ArithInstructionIterator<'a> { - state_stack: Vec> + state_stack: Vec>, } pub type ArithCont = (Code, Option); impl<'a> ArithInstructionIterator<'a> { fn push_subterm(&mut self, lvl: Level, term: &'a Term) { - self.state_stack.push(TermIterState::subterm_to_state(lvl, term)); + self.state_stack + .push(TermIterState::subterm_to_state(lvl, term)); } fn new(term: &'a Term) -> Result { let state = match term { - &Term::AnonVar => - return Err(ArithmeticError::UninstantiatedVar), - &Term::Clause(ref cell, ref name, ref terms, ref fixity) => + &Term::AnonVar => return Err(ArithmeticError::UninstantiatedVar), + &Term::Clause(ref cell, ref name, ref terms, ref fixity) => { match ClauseType::from(name.clone(), terms.len(), fixity.clone()) { - ct @ ClauseType::Named(..) | ct @ ClauseType::Op(..) => - Ok(TermIterState::Clause(Level::Shallow, 0, cell, ct, terms)), + ct @ ClauseType::Named(..) | ct @ ClauseType::Op(..) => { + Ok(TermIterState::Clause(Level::Shallow, 0, cell, ct, terms)) + } ClauseType::Inlined(InlinedClauseType::IsFloat(_)) => { let ct = ClauseType::Named(clause_name!("float"), 1, CodeIndex::default()); Ok(TermIterState::Clause(Level::Shallow, 0, cell, ct, terms)) - }, - _ => Err(ArithmeticError::NonEvaluableFunctor(Constant::Atom(name.clone(), - fixity.clone()), - terms.len())) - }?, - &Term::Constant(ref cell, ref cons) => - TermIterState::Constant(Level::Shallow, cell, cons), - &Term::Cons(_, _, _) => - return Err(ArithmeticError::NonEvaluableFunctor(atom!("'.'"), 2)), - &Term::Var(ref cell, ref var) => - TermIterState::Var(Level::Shallow, cell, var.clone()) + } + _ => Err(ArithmeticError::NonEvaluableFunctor( + Constant::Atom(name.clone(), fixity.clone()), + terms.len(), + )), + }? + } + &Term::Constant(ref cell, ref cons) => { + TermIterState::Constant(Level::Shallow, cell, cons) + } + &Term::Cons(_, _, _) => { + return Err(ArithmeticError::NonEvaluableFunctor(atom!("'.'"), 2)) + } + &Term::Var(ref cell, ref var) => TermIterState::Var(Level::Shallow, cell, var.clone()), }; - Ok(ArithInstructionIterator { state_stack: vec![state] }) + Ok(ArithInstructionIterator { + state_stack: vec![state], + }) } } pub enum ArithTermRef<'a> { Constant(&'a Constant), Op(ClauseName, usize), // name, arity. - Var(&'a Cell, Rc) + Var(&'a Cell, Rc), } impl<'a> Iterator for ArithInstructionIterator<'a> { @@ -72,24 +78,28 @@ impl<'a> Iterator for ArithInstructionIterator<'a> { fn next(&mut self) -> Option { while let Some(iter_state) = self.state_stack.pop() { match iter_state { - TermIterState::AnonVar(_) => - return Some(Err(ArithmeticError::UninstantiatedVar)), + TermIterState::AnonVar(_) => return Some(Err(ArithmeticError::UninstantiatedVar)), TermIterState::Clause(lvl, child_num, cell, ct, subterms) => { let arity = subterms.len(); if child_num == arity { return Some(Ok(ArithTermRef::Op(ct.name(), arity))); } else { - self.state_stack.push(TermIterState::Clause(lvl, child_num + 1, cell, ct, subterms)); + self.state_stack.push(TermIterState::Clause( + lvl, + child_num + 1, + cell, + ct, + subterms, + )); self.push_subterm(lvl, subterms[child_num].as_ref()); } - }, - TermIterState::Constant(_, _, c) => - return Some(Ok(ArithTermRef::Constant(c))), - TermIterState::Var(_, cell, var) => - return Some(Ok(ArithTermRef::Var(cell, var.clone()))), - _ => - return Some(Err(ArithmeticError::NonEvaluableFunctor(atom!("'.'"), 2))) + } + TermIterState::Constant(_, _, c) => return Some(Ok(ArithTermRef::Constant(c))), + TermIterState::Var(_, cell, var) => { + return Some(Ok(ArithTermRef::Var(cell, var.clone()))) + } + _ => return Some(Err(ArithmeticError::NonEvaluableFunctor(atom!("'.'"), 2))), }; } @@ -100,11 +110,11 @@ impl<'a> Iterator for ArithInstructionIterator<'a> { pub struct ArithmeticEvaluator<'a> { bindings: &'a AllocVarDict, interm: Vec, - interm_c: usize + interm_c: usize, } pub trait ArithmeticTermIter<'a> { - type Iter : Iterator, ArithmeticError>>; + type Iter: Iterator, ArithmeticError>>; fn iter(self) -> Result; } @@ -117,15 +127,20 @@ impl<'a> ArithmeticTermIter<'a> for &'a Term { } } -impl<'a> ArithmeticEvaluator<'a> -{ +impl<'a> ArithmeticEvaluator<'a> { pub fn new(bindings: &'a AllocVarDict, target_int: usize) -> Self { - ArithmeticEvaluator { bindings, interm: Vec::new(), interm_c: target_int } + ArithmeticEvaluator { + bindings, + interm: Vec::new(), + interm_c: target_int, + } } - fn get_unary_instr(name: ClauseName, a1: ArithmeticTerm, t: usize) - -> Result - { + fn get_unary_instr( + name: ClauseName, + a1: ArithmeticTerm, + t: usize, + ) -> Result { match name.as_str() { "abs" => Ok(ArithmeticInstruction::Abs(a1, t)), "-" => Ok(ArithmeticInstruction::Neg(a1, t)), @@ -145,34 +160,43 @@ impl<'a> ArithmeticEvaluator<'a> "ceiling" => Ok(ArithmeticInstruction::Ceiling(a1, t)), "floor" => Ok(ArithmeticInstruction::Floor(a1, t)), "\\" => Ok(ArithmeticInstruction::BitwiseComplement(a1, t)), - _ => Err(ArithmeticError::NonEvaluableFunctor(Constant::Atom(name, None), 1)) + _ => Err(ArithmeticError::NonEvaluableFunctor( + Constant::Atom(name, None), + 1, + )), } } - fn get_binary_instr(name: ClauseName, a1: ArithmeticTerm, a2: ArithmeticTerm, t: usize) - -> Result - { + fn get_binary_instr( + name: ClauseName, + a1: ArithmeticTerm, + a2: ArithmeticTerm, + t: usize, + ) -> Result { match name.as_str() { - "+" => Ok(ArithmeticInstruction::Add(a1, a2, t)), - "-" => Ok(ArithmeticInstruction::Sub(a1, a2, t)), - "/" => Ok(ArithmeticInstruction::Div(a1, a2, t)), - "//" => Ok(ArithmeticInstruction::IDiv(a1, a2, t)), - "max" => Ok(ArithmeticInstruction::Max(a1, a2, t)), - "min" => Ok(ArithmeticInstruction::Min(a1, a2, t)), - "div" => Ok(ArithmeticInstruction::IntFloorDiv(a1, a2, t)), + "+" => Ok(ArithmeticInstruction::Add(a1, a2, t)), + "-" => Ok(ArithmeticInstruction::Sub(a1, a2, t)), + "/" => Ok(ArithmeticInstruction::Div(a1, a2, t)), + "//" => Ok(ArithmeticInstruction::IDiv(a1, a2, t)), + "max" => Ok(ArithmeticInstruction::Max(a1, a2, t)), + "min" => Ok(ArithmeticInstruction::Min(a1, a2, t)), + "div" => Ok(ArithmeticInstruction::IntFloorDiv(a1, a2, t)), "rdiv" => Ok(ArithmeticInstruction::RDiv(a1, a2, t)), - "*" => Ok(ArithmeticInstruction::Mul(a1, a2, t)), - "**" => Ok(ArithmeticInstruction::Pow(a1, a2, t)), - "^" => Ok(ArithmeticInstruction::IntPow(a1, a2, t)), - ">>" => Ok(ArithmeticInstruction::Shr(a1, a2, t)), - "<<" => Ok(ArithmeticInstruction::Shl(a1, a2, t)), - "/\\" => Ok(ArithmeticInstruction::And(a1, a2, t)), - "\\/" => Ok(ArithmeticInstruction::Or(a1, a2, t)), - "xor" => Ok(ArithmeticInstruction::Xor(a1, a2, t)), - "mod" => Ok(ArithmeticInstruction::Mod(a1, a2, t)), - "rem" => Ok(ArithmeticInstruction::Rem(a1, a2, t)), + "*" => Ok(ArithmeticInstruction::Mul(a1, a2, t)), + "**" => Ok(ArithmeticInstruction::Pow(a1, a2, t)), + "^" => Ok(ArithmeticInstruction::IntPow(a1, a2, t)), + ">>" => Ok(ArithmeticInstruction::Shr(a1, a2, t)), + "<<" => Ok(ArithmeticInstruction::Shl(a1, a2, t)), + "/\\" => Ok(ArithmeticInstruction::And(a1, a2, t)), + "\\/" => Ok(ArithmeticInstruction::Or(a1, a2, t)), + "xor" => Ok(ArithmeticInstruction::Xor(a1, a2, t)), + "mod" => Ok(ArithmeticInstruction::Mod(a1, a2, t)), + "rem" => Ok(ArithmeticInstruction::Rem(a1, a2, t)), "atan2" => Ok(ArithmeticInstruction::ATan2(a1, a2, t)), - _ => Err(ArithmeticError::NonEvaluableFunctor(Constant::Atom(name, None), 2)) + _ => Err(ArithmeticError::NonEvaluableFunctor( + Constant::Atom(name, None), + 2, + )), } } @@ -185,9 +209,11 @@ impl<'a> ArithmeticEvaluator<'a> temp } - fn instr_from_clause(&mut self, name: ClauseName, arity: usize) - -> Result - { + fn instr_from_clause( + &mut self, + name: ClauseName, + arity: usize, + ) -> Result { match arity { 1 => { let a1 = self.interm.pop().unwrap(); @@ -200,7 +226,7 @@ impl<'a> ArithmeticEvaluator<'a> }; Self::get_unary_instr(name, a1, ninterm) - }, + } 2 => { let a2 = self.interm.pop().unwrap(); let a1 = self.interm.pop().unwrap(); @@ -224,35 +250,44 @@ impl<'a> ArithmeticEvaluator<'a> }; Self::get_binary_instr(name, a1, a2, ninterm) - }, - _ => Err(ArithmeticError::NonEvaluableFunctor(Constant::Atom(name, None), arity)) + } + _ => Err(ArithmeticError::NonEvaluableFunctor( + Constant::Atom(name, None), + arity, + )), } } fn push_constant(&mut self, c: &Constant) -> Result<(), ArithmeticError> { match c { - &Constant::Integer(ref n) => - self.interm.push(ArithmeticTerm::Number(Number::Integer(n.clone()))), - &Constant::Float(ref n) => - self.interm.push(ArithmeticTerm::Number(Number::Float(n.clone()))), - &Constant::Rational(ref n) => - self.interm.push(ArithmeticTerm::Number(Number::Rational(n.clone()))), - &Constant::Atom(ref name, _) if name.as_str() == "pi" => - self.interm.push(ArithmeticTerm::Number(Number::Float(OrderedFloat(f64::consts::PI)))), - _ => - return Err(ArithmeticError::NonEvaluableFunctor(c.clone(), 0)) + &Constant::Integer(ref n) => self + .interm + .push(ArithmeticTerm::Number(Number::Integer(n.clone()))), + &Constant::Float(ref n) => self + .interm + .push(ArithmeticTerm::Number(Number::Float(n.clone()))), + &Constant::Rational(ref n) => self + .interm + .push(ArithmeticTerm::Number(Number::Rational(n.clone()))), + &Constant::Atom(ref name, _) if name.as_str() == "pi" => { + self.interm + .push(ArithmeticTerm::Number(Number::Float(OrderedFloat( + f64::consts::PI, + )))) + } + _ => return Err(ArithmeticError::NonEvaluableFunctor(c.clone(), 0)), } Ok(()) } pub fn eval(&mut self, src: Iter) -> Result - where Iter: ArithmeticTermIter<'a> + where + Iter: ArithmeticTermIter<'a>, { let mut code = vec![]; - for term_ref in src.iter()? - { + for term_ref in src.iter()? { match term_ref? { ArithTermRef::Constant(c) => self.push_constant(c)?, ArithTermRef::Var(cell, name) => { @@ -260,14 +295,14 @@ impl<'a> ArithmeticEvaluator<'a> match self.bindings.get(&name) { Some(&VarData::Temp(_, t, _)) if t != 0 => RegType::Temp(t), Some(&VarData::Perm(p)) if p != 0 => RegType::Perm(p), - _ => return Err(ArithmeticError::UninstantiatedVar) + _ => return Err(ArithmeticError::UninstantiatedVar), } } else { cell.get().norm() }; self.interm.push(ArithmeticTerm::Reg(r)); - }, + } ArithTermRef::Op(name, arity) => { code.push(Line::Arithmetic(self.instr_from_clause(name, arity)?)); } @@ -281,10 +316,10 @@ impl<'a> ArithmeticEvaluator<'a> // integer division rounding function -- 9.1.3.1. pub fn rnd_i<'a>(n: &'a Number) -> RefOrOwned<'a, Integer> { match n { - &Number::Integer(ref n) => - RefOrOwned::Borrowed(n), - &Number::Float(OrderedFloat(f)) => - RefOrOwned::Owned(Integer::from_f64(f.floor()).unwrap_or_else(|| Integer::from(0))), + &Number::Integer(ref n) => RefOrOwned::Borrowed(n), + &Number::Float(OrderedFloat(f)) => { + RefOrOwned::Owned(Integer::from_f64(f.floor()).unwrap_or_else(|| Integer::from(0))) + } &Number::Rational(ref r) => { let r_ref = r.fract_floor_ref(); let (mut fract, mut floor) = (Rational::new(), Integer::new()); @@ -300,24 +335,25 @@ pub fn rnd_f(n: &Number) -> f64 { match n { &Number::Integer(ref n) => n.to_f64(), &Number::Float(OrderedFloat(f)) => f, - &Number::Rational(ref r) => r.to_f64() + &Number::Rational(ref r) => r.to_f64(), } } // floating point result function -- 9.1.4.2. pub fn result_f(n: &Number, round: Round) -> Result - where Round: Fn(&Number) -> f64 +where + Round: Fn(&Number) -> f64, { let f = rnd_f(n); classify_float(f, round) } fn classify_float(f: f64, round: Round) -> Result - where Round: Fn(&Number) -> f64 +where + Round: Fn(&Number) -> f64, { match f.classify() { - FpCategory::Normal | FpCategory::Zero => - Ok(round(&Number::Float(OrderedFloat(f)))), + FpCategory::Normal | FpCategory::Zero => Ok(round(&Number::Float(OrderedFloat(f)))), FpCategory::Infinite => { let f = round(&Number::Float(OrderedFloat(f))); @@ -326,9 +362,9 @@ fn classify_float(f: f64, round: Round) -> Result } else { Err(EvalError::FloatOverflow) } - }, + } FpCategory::Nan => Err(EvalError::Undefined), - _ => Ok(round(&Number::Float(OrderedFloat(f)))) + _ => Ok(round(&Number::Float(OrderedFloat(f)))), } } @@ -361,21 +397,23 @@ impl Add for Number { fn add(self, rhs: Number) -> Self::Output { match (self, rhs) { - (Number::Integer(n1), Number::Integer(n2)) => - Ok(Number::Integer(n1 + n2)), // add_i + (Number::Integer(n1), Number::Integer(n2)) => Ok(Number::Integer(n1 + n2)), // add_i (Number::Integer(n1), Number::Float(OrderedFloat(n2))) - | (Number::Float(OrderedFloat(n2)), Number::Integer(n1)) => - Ok(Number::Float(add_f(float_i_to_f(&n1)?, n2)?)), + | (Number::Float(OrderedFloat(n2)), Number::Integer(n1)) => { + Ok(Number::Float(add_f(float_i_to_f(&n1)?, n2)?)) + } (Number::Integer(n1), Number::Rational(n2)) - | (Number::Rational(n2), Number::Integer(n1)) => - Ok(Number::Rational(Rational::from(n1) + n2)), + | (Number::Rational(n2), Number::Integer(n1)) => { + Ok(Number::Rational(Rational::from(n1) + n2)) + } (Number::Rational(n1), Number::Float(OrderedFloat(n2))) - | (Number::Float(OrderedFloat(n2)), Number::Rational(n1)) => - Ok(Number::Float(add_f(float_r_to_f(&n1)?, n2)?)), - (Number::Float(OrderedFloat(f1)), Number::Float(OrderedFloat(f2))) => - Ok(Number::Float(add_f(f1, f2)?)), - (Number::Rational(r1), Number::Rational(r2)) => - Ok(Number::Rational(r1 + r2)) + | (Number::Float(OrderedFloat(n2)), Number::Rational(n1)) => { + Ok(Number::Float(add_f(float_r_to_f(&n1)?, n2)?)) + } + (Number::Float(OrderedFloat(f1)), Number::Float(OrderedFloat(f2))) => { + Ok(Number::Float(add_f(f1, f2)?)) + } + (Number::Rational(r1), Number::Rational(r2)) => Ok(Number::Rational(r1 + r2)), } } } @@ -387,7 +425,7 @@ impl Neg for Number { match self { Number::Integer(n) => Number::Integer(-n), Number::Float(OrderedFloat(f)) => Number::Float(OrderedFloat(-f)), - Number::Rational(r) => Number::Rational(-r) + Number::Rational(r) => Number::Rational(-r), } } } @@ -405,21 +443,23 @@ impl Mul for Number { fn mul(self, rhs: Number) -> Self::Output { match (self, rhs) { - (Number::Integer(n1), Number::Integer(n2)) => - Ok(Number::Integer(n1 * n2)), // mul_i + (Number::Integer(n1), Number::Integer(n2)) => Ok(Number::Integer(n1 * n2)), // mul_i (Number::Integer(n1), Number::Float(OrderedFloat(n2))) - | (Number::Float(OrderedFloat(n2)), Number::Integer(n1)) => - Ok(Number::Float(mul_f(float_i_to_f(&n1)?, n2)?)), + | (Number::Float(OrderedFloat(n2)), Number::Integer(n1)) => { + Ok(Number::Float(mul_f(float_i_to_f(&n1)?, n2)?)) + } (Number::Integer(n1), Number::Rational(n2)) - | (Number::Rational(n2), Number::Integer(n1)) => - Ok(Number::Rational(Rational::from(n1) * n2)), + | (Number::Rational(n2), Number::Integer(n1)) => { + Ok(Number::Rational(Rational::from(n1) * n2)) + } (Number::Rational(n1), Number::Float(OrderedFloat(n2))) - | (Number::Float(OrderedFloat(n2)), Number::Rational(n1)) => - Ok(Number::Float(mul_f(float_r_to_f(&n1)?, n2)?)), - (Number::Float(OrderedFloat(f1)), Number::Float(OrderedFloat(f2))) => - Ok(Number::Float(mul_f(f1, f2)?)), - (Number::Rational(r1), Number::Rational(r2)) => - Ok(Number::Rational(r1 * r2)) + | (Number::Float(OrderedFloat(n2)), Number::Rational(n1)) => { + Ok(Number::Float(mul_f(float_r_to_f(&n1)?, n2)?)) + } + (Number::Float(OrderedFloat(f1)), Number::Float(OrderedFloat(f2))) => { + Ok(Number::Float(mul_f(f1, f2)?)) + } + (Number::Rational(r1), Number::Rational(r2)) => Ok(Number::Rational(r1 * r2)), } } } @@ -429,24 +469,37 @@ impl Div for Number { fn div(self, rhs: Number) -> Self::Output { match (self, rhs) { - (Number::Integer(n1), Number::Integer(n2)) => - Ok(Number::Float(div_f(float_i_to_f(&n1)?, float_i_to_f(&n2)?)?)), - (Number::Integer(n1), Number::Float(OrderedFloat(n2))) => - Ok(Number::Float(div_f(float_i_to_f(&n1)?, n2)?)), - (Number::Float(OrderedFloat(n2)), Number::Integer(n1)) => - Ok(Number::Float(div_f(n2, float_i_to_f(&n1)?)?)), - (Number::Integer(n1), Number::Rational(n2)) => - Ok(Number::Float(div_f(float_i_to_f(&n1)?, float_r_to_f(&n2)?)?)), - (Number::Rational(n2), Number::Integer(n1)) => - Ok(Number::Float(div_f(float_r_to_f(&n2)?, float_i_to_f(&n1)?)?)), - (Number::Rational(n1), Number::Float(OrderedFloat(n2))) => - Ok(Number::Float(div_f(float_r_to_f(&n1)?, n2)?)), - (Number::Float(OrderedFloat(n2)), Number::Rational(n1)) => - Ok(Number::Float(div_f(n2, float_r_to_f(&n1)?)?)), - (Number::Float(OrderedFloat(f1)), Number::Float(OrderedFloat(f2))) => - Ok(Number::Float(div_f(f1, f2)?)), - (Number::Rational(r1), Number::Rational(r2)) => - Ok(Number::Float(div_f(float_r_to_f(&r1)?, float_r_to_f(&r2)?)?)) + (Number::Integer(n1), Number::Integer(n2)) => Ok(Number::Float(div_f( + float_i_to_f(&n1)?, + float_i_to_f(&n2)?, + )?)), + (Number::Integer(n1), Number::Float(OrderedFloat(n2))) => { + Ok(Number::Float(div_f(float_i_to_f(&n1)?, n2)?)) + } + (Number::Float(OrderedFloat(n2)), Number::Integer(n1)) => { + Ok(Number::Float(div_f(n2, float_i_to_f(&n1)?)?)) + } + (Number::Integer(n1), Number::Rational(n2)) => Ok(Number::Float(div_f( + float_i_to_f(&n1)?, + float_r_to_f(&n2)?, + )?)), + (Number::Rational(n2), Number::Integer(n1)) => Ok(Number::Float(div_f( + float_r_to_f(&n2)?, + float_i_to_f(&n1)?, + )?)), + (Number::Rational(n1), Number::Float(OrderedFloat(n2))) => { + Ok(Number::Float(div_f(float_r_to_f(&n1)?, n2)?)) + } + (Number::Float(OrderedFloat(n2)), Number::Rational(n1)) => { + Ok(Number::Float(div_f(n2, float_r_to_f(&n1)?)?)) + } + (Number::Float(OrderedFloat(f1)), Number::Float(OrderedFloat(f2))) => { + Ok(Number::Float(div_f(f1, f2)?)) + } + (Number::Rational(r1), Number::Rational(r2)) => Ok(Number::Float(div_f( + float_r_to_f(&r1)?, + float_r_to_f(&r2)?, + )?)), } } } @@ -454,24 +507,15 @@ impl Div for Number { impl PartialOrd for Number { fn partial_cmp(&self, rhs: &Number) -> Option { match (self, rhs) { - (&Number::Integer(ref n1), &Number::Integer(ref n2)) => - Some(n1.cmp(n2)), - (&Number::Integer(_), Number::Float(_)) => - Some(Ordering::Greater), - (&Number::Float(_), &Number::Integer(_)) => - Some(Ordering::Less), - (&Number::Integer(_), &Number::Rational(_)) => - Some(Ordering::Greater), - (&Number::Rational(_), &Number::Integer(_)) => - Some(Ordering::Less), - (&Number::Rational(_), Number::Float(_)) => - Some(Ordering::Greater), - (&Number::Float(_), &Number::Rational(_)) => - Some(Ordering::Less), - (&Number::Float(f1), &Number::Float(f2)) => - Some(f1.cmp(&f2)), - (&Number::Rational(ref r1), &Number::Rational(ref r2)) => - Some(r1.cmp(&r2)) + (&Number::Integer(ref n1), &Number::Integer(ref n2)) => Some(n1.cmp(n2)), + (&Number::Integer(_), Number::Float(_)) => Some(Ordering::Greater), + (&Number::Float(_), &Number::Integer(_)) => Some(Ordering::Less), + (&Number::Integer(_), &Number::Rational(_)) => Some(Ordering::Greater), + (&Number::Rational(_), &Number::Integer(_)) => Some(Ordering::Less), + (&Number::Rational(_), Number::Float(_)) => Some(Ordering::Greater), + (&Number::Float(_), &Number::Rational(_)) => Some(Ordering::Less), + (&Number::Float(f1), &Number::Float(f2)) => Some(f1.cmp(&f2)), + (&Number::Rational(ref r1), &Number::Rational(ref r2)) => Some(r1.cmp(&r2)), } } } @@ -479,31 +523,21 @@ impl PartialOrd for Number { impl Ord for Number { fn cmp(&self, rhs: &Number) -> Ordering { match (self, rhs) { - (&Number::Integer(ref n1), &Number::Integer(ref n2)) => - n1.cmp(n2), - (&Number::Integer(_), Number::Float(_)) => - Ordering::Greater, - (&Number::Float(_), &Number::Integer(_)) => - Ordering::Less, - (&Number::Integer(_), &Number::Rational(_)) => - Ordering::Greater, - (&Number::Rational(_), &Number::Integer(_)) => - Ordering::Less, - (&Number::Rational(_), Number::Float(_)) => - Ordering::Greater, - (&Number::Float(_), &Number::Rational(_)) => - Ordering::Less, - (&Number::Float(f1), &Number::Float(f2)) => - f1.cmp(&f2), - (&Number::Rational(ref r1), &Number::Rational(ref r2)) => - r1.cmp(&r2) + (&Number::Integer(ref n1), &Number::Integer(ref n2)) => n1.cmp(n2), + (&Number::Integer(_), Number::Float(_)) => Ordering::Greater, + (&Number::Float(_), &Number::Integer(_)) => Ordering::Less, + (&Number::Integer(_), &Number::Rational(_)) => Ordering::Greater, + (&Number::Rational(_), &Number::Integer(_)) => Ordering::Less, + (&Number::Rational(_), Number::Float(_)) => Ordering::Greater, + (&Number::Float(_), &Number::Rational(_)) => Ordering::Less, + (&Number::Float(f1), &Number::Float(f2)) => f1.cmp(&f2), + (&Number::Rational(ref r1), &Number::Rational(ref r2)) => r1.cmp(&r2), } } } // Computes n ^ power. Ignores the sign of power. -pub fn binary_pow(mut n: Integer, power: Integer) -> Integer -{ +pub fn binary_pow(mut n: Integer, power: Integer) -> Integer { let mut power = power.abs(); if power == 0 { diff --git a/src/prolog/clause_types.rs b/src/prolog/clause_types.rs index 9e5359f7..07d3d589 100644 --- a/src/prolog/clause_types.rs +++ b/src/prolog/clause_types.rs @@ -14,7 +14,7 @@ pub enum CompareNumberQT { GreaterThanOrEqual, LessThanOrEqual, NotEqual, - Equal + Equal, } impl CompareNumberQT { @@ -25,7 +25,7 @@ impl CompareNumberQT { CompareNumberQT::GreaterThanOrEqual => ">=", CompareNumberQT::LessThanOrEqual => "=<", CompareNumberQT::NotEqual => "=\\=", - CompareNumberQT::Equal => "=:=" + CompareNumberQT::Equal => "=:=", } } } @@ -53,7 +53,7 @@ impl CompareTermQT { pub enum ArithmeticTerm { Reg(RegType), Interm(usize), - Number(Number) + Number(Number), } impl ArithmeticTerm { @@ -78,7 +78,7 @@ pub enum InlinedClauseType { IsFloat(RegType), IsNonVar(RegType), IsPartialString(RegType), - IsVar(RegType) + IsVar(RegType), } ref_thread_local! { @@ -137,10 +137,10 @@ impl InlinedClauseType { &InlinedClauseType::IsAtom(..) => "atom", &InlinedClauseType::IsAtomic(..) => "atomic", &InlinedClauseType::IsCompound(..) => "compound", - &InlinedClauseType::IsInteger (..) => "integer", + &InlinedClauseType::IsInteger(..) => "integer", &InlinedClauseType::IsRational(..) => "rational", &InlinedClauseType::IsString(..) => "string", - &InlinedClauseType::IsFloat (..) => "float", + &InlinedClauseType::IsFloat(..) => "float", &InlinedClauseType::IsNonVar(..) => "nonvar", &InlinedClauseType::IsPartialString(..) => "is_partial_string", &InlinedClauseType::IsVar(..) => "var", @@ -233,7 +233,7 @@ pub enum SystemClauseType { UnwindStack, Variant, WAMInstructions, - WriteTerm + WriteTerm, } impl SystemClauseType { @@ -246,15 +246,20 @@ impl SystemClauseType { &SystemClauseType::AtomChars => clause_name!("$atom_chars"), &SystemClauseType::AtomCodes => clause_name!("$atom_codes"), &SystemClauseType::AtomLength => clause_name!("$atom_length"), - &SystemClauseType::ModuleAssertDynamicPredicateToFront => clause_name!("$module_asserta"), - &SystemClauseType::ModuleAssertDynamicPredicateToBack => clause_name!("$module_assertz"), + &SystemClauseType::ModuleAssertDynamicPredicateToFront => { + clause_name!("$module_asserta") + } + &SystemClauseType::ModuleAssertDynamicPredicateToBack => { + clause_name!("$module_assertz") + } &SystemClauseType::CharCode => clause_name!("$char_code"), &SystemClauseType::CharsToNumber => clause_name!("$chars_to_number"), &SystemClauseType::CodesToNumber => clause_name!("$codes_to_number"), &SystemClauseType::CheckCutPoint => clause_name!("$check_cp"), &SystemClauseType::REPL(REPLCodePtr::CompileBatch) => clause_name!("$compile_batch"), - &SystemClauseType::REPL(REPLCodePtr::SubmitQueryAndPrintResults) => - clause_name!("$submit_query_and_print_results"), + &SystemClauseType::REPL(REPLCodePtr::SubmitQueryAndPrintResults) => { + clause_name!("$submit_query_and_print_results") + } &SystemClauseType::CopyToLiftedHeap => clause_name!("$copy_to_lh"), &SystemClauseType::DeleteAttribute => clause_name!("$del_attr_non_head"), &SystemClauseType::DeleteHeadAttribute => clause_name!("$del_attr_head"), @@ -265,13 +270,21 @@ impl SystemClauseType { &SystemClauseType::ExpandGoal => clause_name!("$expand_goal"), &SystemClauseType::FetchGlobalVar => clause_name!("$fetch_global_var"), &SystemClauseType::GetChar => clause_name!("$get_char"), - &SystemClauseType::TruncateIfNoLiftedHeapGrowth => clause_name!("$truncate_if_no_lh_growth"), - &SystemClauseType::TruncateIfNoLiftedHeapGrowthDiff => clause_name!("$truncate_if_no_lh_growth_diff"), + &SystemClauseType::TruncateIfNoLiftedHeapGrowth => { + clause_name!("$truncate_if_no_lh_growth") + } + &SystemClauseType::TruncateIfNoLiftedHeapGrowthDiff => { + clause_name!("$truncate_if_no_lh_growth_diff") + } &SystemClauseType::GetAttributedVariableList => clause_name!("$get_attr_list"), - &SystemClauseType::GetAttrVarQueueDelimiter => clause_name!("$get_attr_var_queue_delim"), + &SystemClauseType::GetAttrVarQueueDelimiter => { + clause_name!("$get_attr_var_queue_delim") + } &SystemClauseType::GetAttrVarQueueBeyond => clause_name!("$get_attr_var_queue_beyond"), &SystemClauseType::GetLiftedHeapFromOffset => clause_name!("$get_lh_from_offset"), - &SystemClauseType::GetLiftedHeapFromOffsetDiff => clause_name!("$get_lh_from_offset_diff"), + &SystemClauseType::GetLiftedHeapFromOffsetDiff => { + clause_name!("$get_lh_from_offset_diff") + } &SystemClauseType::GetBValue => clause_name!("$get_b_value"), &SystemClauseType::GetClause => clause_name!("$get_clause"), &SystemClauseType::GetNextDBRef => clause_name!("$get_next_db_ref"), @@ -285,7 +298,9 @@ impl SystemClauseType { &SystemClauseType::HeadIsDynamic => clause_name!("$head_is_dynamic"), &SystemClauseType::OpDeclaration => clause_name!("$op$"), &SystemClauseType::InstallSCCCleaner => clause_name!("$install_scc_cleaner"), - &SystemClauseType::InstallInferenceCounter => clause_name!("$install_inference_counter"), + &SystemClauseType::InstallInferenceCounter => { + clause_name!("$install_inference_counter") + } &SystemClauseType::LiftedHeapLength => clause_name!("$lh_length"), &SystemClauseType::ModuleHeadIsDynamic => clause_name!("$module_head_is_dynamic"), &SystemClauseType::ModuleOf => clause_name!("$module_of"), @@ -311,7 +326,9 @@ impl SystemClauseType { &SystemClauseType::ResetGlobalVarAtKey => clause_name!("$reset_global_var_at_key"), &SystemClauseType::RetractClause => clause_name!("$retract_clause"), &SystemClauseType::ResetBlock => clause_name!("$reset_block"), - &SystemClauseType::ReturnFromAttributeGoals => clause_name!("$return_from_attribute_goals"), + &SystemClauseType::ReturnFromAttributeGoals => { + clause_name!("$return_from_attribute_goals") + } &SystemClauseType::ReturnFromVerifyAttr => clause_name!("$return_from_verify_attr"), &SystemClauseType::SetBall => clause_name!("$set_ball"), &SystemClauseType::SetCutPointByDefault(_) => clause_name!("$set_cp_by_default"), @@ -331,8 +348,8 @@ impl SystemClauseType { pub fn from(name: &str, arity: usize) -> Option { match (name, arity) { ("$abolish_clause", 2) => Some(SystemClauseType::AbolishClause), - ("$atom_chars", 2) => Some(SystemClauseType::AtomChars), - ("$atom_codes", 2) => Some(SystemClauseType::AtomCodes), + ("$atom_chars", 2) => Some(SystemClauseType::AtomChars), + ("$atom_codes", 2) => Some(SystemClauseType::AtomCodes), ("$atom_length", 2) => Some(SystemClauseType::AtomLength), ("$abolish_module_clause", 3) => Some(SystemClauseType::AbolishModuleClause), ("$module_asserta", 5) => Some(SystemClauseType::ModuleAssertDynamicPredicateToFront), @@ -358,8 +375,12 @@ impl SystemClauseType { ("$expand_goal", 2) => Some(SystemClauseType::ExpandGoal), ("$fetch_global_var", 2) => Some(SystemClauseType::FetchGlobalVar), ("$get_char", 1) => Some(SystemClauseType::GetChar), - ("$truncate_if_no_lh_growth", 1) => Some(SystemClauseType::TruncateIfNoLiftedHeapGrowth), - ("$truncate_if_no_lh_growth_diff", 2) => Some(SystemClauseType::TruncateIfNoLiftedHeapGrowthDiff), + ("$truncate_if_no_lh_growth", 1) => { + Some(SystemClauseType::TruncateIfNoLiftedHeapGrowth) + } + ("$truncate_if_no_lh_growth_diff", 2) => { + Some(SystemClauseType::TruncateIfNoLiftedHeapGrowthDiff) + } ("$get_attr_list", 2) => Some(SystemClauseType::GetAttributedVariableList), ("$get_b_value", 1) => Some(SystemClauseType::GetBValue), ("$get_clause", 2) => Some(SystemClauseType::GetClause), @@ -406,8 +427,9 @@ impl SystemClauseType { ("$set_double_quotes", 1) => Some(SystemClauseType::SetDoubleQuotes), ("$skip_max_list", 4) => Some(SystemClauseType::SkipMaxList), ("$store_global_var", 2) => Some(SystemClauseType::StoreGlobalVar), - ("$submit_query_and_print_results", 2) => - Some(SystemClauseType::REPL(REPLCodePtr::SubmitQueryAndPrintResults)), + ("$submit_query_and_print_results", 2) => Some(SystemClauseType::REPL( + REPLCodePtr::SubmitQueryAndPrintResults, + )), ("$term_variables", 2) => Some(SystemClauseType::TermVariables), ("$truncate_lh_to", 1) => Some(SystemClauseType::TruncateLiftedHeapTo), ("$unwind_stack", 0) => Some(SystemClauseType::UnwindStack), @@ -415,7 +437,7 @@ impl SystemClauseType { ("$variant", 2) => Some(SystemClauseType::Variant), ("$write_term", 5) => Some(SystemClauseType::WriteTerm), ("$wam_instructions", 3) => Some(SystemClauseType::WAMInstructions), - _ => None + _ => None, } } } @@ -448,7 +470,7 @@ pub enum ClauseType { Inlined(InlinedClauseType), Named(ClauseName, usize, CodeIndex), // name, arity, index. Op(ClauseName, SharedOpDesc, CodeIndex), - System(SystemClauseType) + System(SystemClauseType), } impl BuiltInClauseType { @@ -462,8 +484,8 @@ impl BuiltInClauseType { &BuiltInClauseType::CopyTerm => clause_name!("copy_term"), &BuiltInClauseType::Eq => clause_name!("=="), &BuiltInClauseType::Functor => clause_name!("functor"), - &BuiltInClauseType::Ground => clause_name!("ground"), - &BuiltInClauseType::Is(..) => clause_name!("is"), + &BuiltInClauseType::Ground => clause_name!("ground"), + &BuiltInClauseType::Is(..) => clause_name!("is"), &BuiltInClauseType::KeySort => clause_name!("keysort"), &BuiltInClauseType::Nl => clause_name!("nl"), &BuiltInClauseType::NotEq => clause_name!("\\=="), @@ -483,7 +505,7 @@ impl BuiltInClauseType { &BuiltInClauseType::CopyTerm => 2, &BuiltInClauseType::Eq => 2, &BuiltInClauseType::Functor => 3, - &BuiltInClauseType::Ground => 1, + &BuiltInClauseType::Ground => 1, &BuiltInClauseType::Is(..) => 2, &BuiltInClauseType::KeySort => 2, &BuiltInClauseType::NotEq => 2, @@ -498,15 +520,13 @@ impl BuiltInClauseType { impl ClauseType { pub fn spec(&self) -> Option { match self { - &ClauseType::Op(_, ref spec, _) => - Some(spec.clone()), + &ClauseType::Op(_, ref spec, _) => Some(spec.clone()), &ClauseType::Inlined(InlinedClauseType::CompareNumber(..)) - | &ClauseType::BuiltIn(BuiltInClauseType::Is(..)) - | &ClauseType::BuiltIn(BuiltInClauseType::CompareTerm(_)) - | &ClauseType::BuiltIn(BuiltInClauseType::NotEq) - | &ClauseType::BuiltIn(BuiltInClauseType::Eq) => - Some(SharedOpDesc::new(700, XFX)), - _ => None + | &ClauseType::BuiltIn(BuiltInClauseType::Is(..)) + | &ClauseType::BuiltIn(BuiltInClauseType::CompareTerm(_)) + | &ClauseType::BuiltIn(BuiltInClauseType::NotEq) + | &ClauseType::BuiltIn(BuiltInClauseType::Eq) => Some(SharedOpDesc::new(700, XFX)), + _ => None, } } @@ -523,18 +543,23 @@ impl ClauseType { } pub fn from(name: ClauseName, arity: usize, spec: Option) -> Self { - CLAUSE_TYPE_FORMS.borrow().get(&(name.as_str(), arity)).cloned() - .unwrap_or_else(|| + CLAUSE_TYPE_FORMS + .borrow() + .get(&(name.as_str(), arity)) + .cloned() + .unwrap_or_else(|| { SystemClauseType::from(name.as_str(), arity) .map(ClauseType::System) - .unwrap_or_else(|| + .unwrap_or_else(|| { if let Some(spec) = spec { ClauseType::Op(name, spec, CodeIndex::default()) } else if name.as_str() == "call" { ClauseType::CallN } else { ClauseType::Named(name, arity, CodeIndex::default()) - })) + } + }) + }) } } diff --git a/src/prolog/codegen.rs b/src/prolog/codegen.rs index bba0a3fd..5d7526bc 100644 --- a/src/prolog/codegen.rs +++ b/src/prolog/codegen.rs @@ -21,7 +21,7 @@ pub struct CodeGenerator { flags: MachineFlags, marker: TermMarker, var_count: IndexMap, usize>, - non_counted_bt: bool + non_counted_bt: bool, } pub struct ConjunctInfo<'a> { @@ -30,10 +30,13 @@ pub struct ConjunctInfo<'a> { pub has_deep_cut: bool, } -impl<'a> ConjunctInfo<'a> -{ +impl<'a> ConjunctInfo<'a> { fn new(perm_vs: VariableFixtures<'a>, num_of_chunks: usize, has_deep_cut: bool) -> Self { - ConjunctInfo { perm_vs, num_of_chunks, has_deep_cut } + ConjunctInfo { + perm_vs, + num_of_chunks, + has_deep_cut, + } } fn allocates(&self) -> bool { @@ -60,7 +63,8 @@ impl<'a> ConjunctInfo<'a> let mut index = right_index; if let Line::Query(_) = &code[right_index] { - while let Line::Query(_) = &code[index] { // index >= 0. + while let Line::Query(_) = &code[index] { + // index >= 0. if index == 0 { break; } else { @@ -68,7 +72,8 @@ impl<'a> ConjunctInfo<'a> } } - if let Line::Query(_) = &code[index] {} else { + if let Line::Query(_) = &code[index] { + } else { index += 1; } @@ -80,7 +85,7 @@ impl<'a> ConjunctInfo<'a> } } - for index in index .. right_index + 1 { + for index in index..right_index + 1 { if let &mut Line::Query(ref mut query_instr) = &mut code[index] { unsafe_var_marker.mark_unsafe_vars(query_instr); } @@ -89,21 +94,21 @@ impl<'a> ConjunctInfo<'a> } } -impl<'a, TermMarker: Allocator<'a>> CodeGenerator -{ +impl<'a, TermMarker: Allocator<'a>> CodeGenerator { pub fn new(non_counted_bt: bool, flags: MachineFlags) -> Self { - CodeGenerator { marker: Allocator::new(), - var_count: IndexMap::new(), - non_counted_bt, - flags } + CodeGenerator { + marker: Allocator::new(), + var_count: IndexMap::new(), + non_counted_bt, + flags, + } } pub fn take_vars(self) -> AllocVarDict { self.marker.take_bindings() } - fn update_var_count>>(&mut self, iter: Iter) - { + fn update_var_count>>(&mut self, iter: Iter) { for term in iter { if let TermRef::Var(_, _, var) = term { let entry = self.var_count.entry(var).or_insert(0); @@ -116,10 +121,14 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator *self.var_count.get(var).unwrap() } - fn mark_non_callable(&mut self, name: Rc, arity: usize, term_loc: GenContext, - vr: &'a Cell, code: &mut Code) - -> RegType - { + fn mark_non_callable( + &mut self, + name: Rc, + arity: usize, + term_loc: GenContext, + vr: &'a Cell, + code: &mut Code, + ) -> RegType { match self.marker.bindings().get(&name) { Some(&VarData::Temp(_, t, _)) if t != 0 => RegType::Temp(t), Some(&VarData::Perm(p)) if p != 0 => RegType::Perm(p), @@ -127,7 +136,8 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator let mut target = Vec::new(); self.marker.reset_arg(arity); - self.marker.mark_var(name, Level::Shallow, vr, term_loc, &mut target); + self.marker + .mark_var(name, Level::Shallow, vr, term_loc, &mut target); if !target.is_empty() { for query_instr in target { @@ -141,7 +151,8 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator } fn add_or_increment_void_instr(target: &mut Vec) - where Target: CompilationTarget<'a> + where + Target: CompilationTarget<'a>, { if let Some(ref mut instr) = target.last_mut() { if Target::is_void_instr(&*instr) { @@ -153,36 +164,48 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator target.push(Target::to_void(1)); } - fn subterm_to_instr(&mut self, - subterm: &'a Term, - term_loc: GenContext, - is_exposed: bool, - target: &mut Vec) - where Target: CompilationTarget<'a> + fn subterm_to_instr( + &mut self, + subterm: &'a Term, + term_loc: GenContext, + is_exposed: bool, + target: &mut Vec, + ) where + Target: CompilationTarget<'a>, { match subterm { - &Term::AnonVar if is_exposed => - self.marker.mark_anon_var(Level::Deep, term_loc, target), - &Term::AnonVar => - Self::add_or_increment_void_instr(target), + &Term::AnonVar if is_exposed => { + self.marker.mark_anon_var(Level::Deep, term_loc, target) + } + &Term::AnonVar => Self::add_or_increment_void_instr(target), &Term::Cons(ref cell, _, _) | &Term::Clause(ref cell, _, _, _) => { - self.marker.mark_non_var(Level::Deep, term_loc, cell, target); + self.marker + .mark_non_var(Level::Deep, term_loc, cell, target); target.push(Target::clause_arg_to_instr(cell.get())); - }, - &Term::Constant(_, ref constant) => - target.push(Target::constant_subterm(constant.clone())), - &Term::Var(ref cell, ref var) => + } + &Term::Constant(_, ref constant) => { + target.push(Target::constant_subterm(constant.clone())) + } + &Term::Var(ref cell, ref var) => { if is_exposed || self.get_var_count(var) > 1 { - self.marker.mark_var(var.clone(), Level::Deep, cell, term_loc, target); + self.marker + .mark_var(var.clone(), Level::Deep, cell, term_loc, target); } else { Self::add_or_increment_void_instr(target); } + } }; } - fn compile_target(&mut self, iter: Iter, term_loc: GenContext, is_exposed: bool) - -> Vec - where Target: CompilationTarget<'a>, Iter: Iterator> + fn compile_target( + &mut self, + iter: Iter, + term_loc: GenContext, + is_exposed: bool, + ) -> Vec + where + Target: CompilationTarget<'a>, + Iter: Iterator>, { let mut target = Vec::new(); @@ -195,37 +218,48 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator for subterm in terms { self.subterm_to_instr(subterm.as_ref(), term_loc, is_exposed, &mut target); } - }, + } TermRef::Cons(lvl, cell, head, tail) => { self.marker.mark_non_var(lvl, term_loc, cell, &mut target); target.push(Target::to_list(lvl, cell.get())); self.subterm_to_instr(head, term_loc, is_exposed, &mut target); self.subterm_to_instr(tail, term_loc, is_exposed, &mut target); - }, + } TermRef::Constant(lvl @ Level::Shallow, cell, constant) => { self.marker.mark_non_var(lvl, term_loc, cell, &mut target); target.push(Target::to_constant(lvl, constant.clone(), cell.get())); - }, - TermRef::AnonVar(lvl @ Level::Shallow) => + } + TermRef::AnonVar(lvl @ Level::Shallow) => { if let GenContext::Head = term_loc { self.marker.advance_arg(); } else { self.marker.mark_anon_var(lvl, term_loc, &mut target); - }, + } + } TermRef::Var(lvl @ Level::Shallow, cell, ref var) if var.as_str() == "!" => { if self.marker.is_unbound(var.clone()) { if term_loc != GenContext::Head { - self.marker.mark_reserved_var(var.clone(), lvl, cell, term_loc, - &mut target, perm_v!(1), false); + self.marker.mark_reserved_var( + var.clone(), + lvl, + cell, + term_loc, + &mut target, + perm_v!(1), + false, + ); continue; } } - self.marker.mark_var(var.clone(), lvl, cell, term_loc, &mut target); - }, - TermRef::Var(lvl @ Level::Shallow, cell, var) => - self.marker.mark_var(var.clone(), lvl, cell, term_loc, &mut target), + self.marker + .mark_var(var.clone(), lvl, cell, term_loc, &mut target); + } + TermRef::Var(lvl @ Level::Shallow, cell, var) => { + self.marker + .mark_var(var.clone(), lvl, cell, term_loc, &mut target) + } _ => {} }; } @@ -233,18 +267,19 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator target } - fn collect_var_data(&mut self, mut iter: ChunkedIterator<'a>) -> ConjunctInfo<'a> - { + fn collect_var_data(&mut self, mut iter: ChunkedIterator<'a>) -> ConjunctInfo<'a> { let mut vs = VariableFixtures::new(); while let Some((chunk_num, lt_arity, chunked_terms)) = iter.next() { for (i, chunked_term) in chunked_terms.iter().enumerate() { let term_loc = match chunked_term { &ChunkedTerm::HeadClause(..) => GenContext::Head, - &ChunkedTerm::BodyTerm(_) => if i < chunked_terms.len() - 1 { - GenContext::Mid(chunk_num) - } else { - GenContext::Last(chunk_num) + &ChunkedTerm::BodyTerm(_) => { + if i < chunked_terms.len() - 1 { + GenContext::Mid(chunk_num) + } else { + GenContext::Last(chunk_num) + } } }; @@ -254,7 +289,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator } let num_of_chunks = iter.chunk_num; - let has_deep_cut = iter.encountered_deep_cut(); + let has_deep_cut = iter.encountered_deep_cut(); vs.populate_restricting_sets(); vs.set_perm_vals(has_deep_cut); @@ -264,45 +299,45 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator ConjunctInfo::new(vs, num_of_chunks, has_deep_cut) } - fn add_conditional_call(code: &mut Code, qt: &QueryTerm, pvs: usize) - { + fn add_conditional_call(code: &mut Code, qt: &QueryTerm, pvs: usize) { match qt { - &QueryTerm::Jump(ref vars) => - code.push(jmp_call!(vars.len(), 0, pvs)), - &QueryTerm::Clause(_, ref ct, ref terms, true) => - code.push(call_clause_by_default!(ct.clone(), terms.len(), pvs)), - &QueryTerm::Clause(_, ref ct, ref terms, false) => - code.push(call_clause!(ct.clone(), terms.len(), pvs)), + &QueryTerm::Jump(ref vars) => code.push(jmp_call!(vars.len(), 0, pvs)), + &QueryTerm::Clause(_, ref ct, ref terms, true) => { + code.push(call_clause_by_default!(ct.clone(), terms.len(), pvs)) + } + &QueryTerm::Clause(_, ref ct, ref terms, false) => { + code.push(call_clause!(ct.clone(), terms.len(), pvs)) + } _ => {} } } - fn lco(code: &mut Code) -> usize - { + fn lco(code: &mut Code) -> usize { let mut dealloc_index = code.len() - 1; match code.last_mut() { - Some(&mut Line::Control(ref mut ctrl)) => - match ctrl { - &mut ControlInstruction::CallClause(_, _, _, ref mut last_call, _) => - *last_call = true, - &mut ControlInstruction::JmpBy(_, _, _, ref mut last_call) => - *last_call = true, - &mut ControlInstruction::Proceed => {}, - _ => dealloc_index += 1 - }, - Some(&mut Line::Cut(CutInstruction::Cut(_))) => - dealloc_index += 1, + Some(&mut Line::Control(ref mut ctrl)) => match ctrl { + &mut ControlInstruction::CallClause(_, _, _, ref mut last_call, _) => { + *last_call = true + } + &mut ControlInstruction::JmpBy(_, _, _, ref mut last_call) => *last_call = true, + &mut ControlInstruction::Proceed => {} + _ => dealloc_index += 1, + }, + Some(&mut Line::Cut(CutInstruction::Cut(_))) => dealloc_index += 1, _ => {} }; dealloc_index } - fn compile_inlined(&mut self, ct: &InlinedClauseType, terms: &'a Vec>, - term_loc: GenContext, code: &mut Code) - -> Result<(), ParserError> - { + fn compile_inlined( + &mut self, + ct: &InlinedClauseType, + terms: &'a Vec>, + term_loc: GenContext, + code: &mut Code, + ) -> Result<(), ParserError> { match ct { &InlinedClauseType::CompareNumber(cmp, ..) => { if let &Term::Var(ref vr, ref name) = terms[0].as_ref() { @@ -319,153 +354,151 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator code.append(&mut lcode); code.append(&mut rcode); - code.push(compare_number_instr!(cmp, - at_1.unwrap_or(interm!(1)), - at_2.unwrap_or(interm!(2)))); + code.push(compare_number_instr!( + cmp, + at_1.unwrap_or(interm!(1)), + at_2.unwrap_or(interm!(2)) + )); + } + &InlinedClauseType::IsAtom(..) => match terms[0].as_ref() { + &Term::Constant(_, Constant::Char(_)) + | &Term::Constant(_, Constant::EmptyList) + | &Term::Constant(_, Constant::Atom(..)) => { + code.push(succeed!()); + } + &Term::Var(ref vr, ref name) => { + let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code); + code.push(is_atom!(r)); + } + _ => { + code.push(fail!()); + } }, - &InlinedClauseType::IsAtom(..) => - match terms[0].as_ref() { - &Term::Constant(_, Constant::Char(_)) - | &Term::Constant(_, Constant::EmptyList) - | &Term::Constant(_, Constant::Atom(..)) => { - code.push(succeed!()); - }, - &Term::Var(ref vr, ref name) => { - let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code); - code.push(is_atom!(r)); - } - _ => { - code.push(fail!()); - } - }, - &InlinedClauseType::IsAtomic(..) => - match terms[0].as_ref() { - &Term::AnonVar | &Term::Clause(..) | &Term::Cons(..) => { - code.push(fail!()); - }, - &Term::Constant(..) => { - code.push(succeed!()); - }, - &Term::Var(ref vr, ref name) => { - let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code); - code.push(is_atomic!(r)); - } - }, - &InlinedClauseType::IsCompound(..) => - match terms[0].as_ref() { - &Term::Clause(..) | &Term::Cons(..) => { - code.push(succeed!()); - }, - &Term::Var(ref vr, ref name) => { - let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code); - code.push(is_compound!(r)); - }, - _ => { - code.push(fail!()); - } - }, - &InlinedClauseType::IsRational(..) => - match terms[0].as_ref() { - &Term::Constant(_, Constant::Rational(_)) => { - code.push(succeed!()); - }, - &Term::Var(ref vr, ref name) => { - let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code); - code.push(is_rational!(r)); - }, - _ => { - code.push(fail!()); - } - }, - &InlinedClauseType::IsFloat(..) => - match terms[0].as_ref() { - &Term::Constant(_, Constant::Float(_)) => { - code.push(succeed!()); - }, - &Term::Var(ref vr, ref name) => { - let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code); - code.push(is_float!(r)); - }, - _ => { - code.push(fail!()); - } - }, - &InlinedClauseType::IsString(..) => - match terms[0].as_ref() { - &Term::Constant(_, Constant::String(_)) => { - code.push(succeed!()); - }, - &Term::Var(ref vr, ref name) => { - let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code); - code.push(is_string!(r)); - }, - _ => { - code.push(fail!()); - } - }, - &InlinedClauseType::IsNonVar(..) => - match terms[0].as_ref() { - &Term::AnonVar => { - code.push(fail!()); - }, - &Term::Var(ref vr, ref name) => { - let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code); - code.push(is_nonvar!(r)); - }, - _ => { - code.push(succeed!()); - } - }, - &InlinedClauseType::IsInteger(..) => - match terms[0].as_ref() { - &Term::Constant(_, Constant::CharCode(_)) - | &Term::Constant(_, Constant::Integer(_)) => { - code.push(succeed!()); - }, - &Term::Var(ref vr, ref name) => { - let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code); - code.push(is_integer!(r)); - }, - _ => { - code.push(fail!()); - }, - }, - &InlinedClauseType::IsVar(..) => - match terms[0].as_ref() { - &Term::Constant(..) | &Term::Clause(..) | &Term::Cons(..) => { - code.push(fail!()); - }, - &Term::AnonVar => { - code.push(succeed!()); - }, - &Term::Var(ref vr, ref name) => { - let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code); - code.push(is_var!(r)); - } - }, - &InlinedClauseType::IsPartialString(..) => - match terms[0].as_ref() { - &Term::Var(ref vr, ref name) => { - let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code); - code.push(is_partial_string!(r)); - }, - _ => code.push(fail!()) + &InlinedClauseType::IsAtomic(..) => match terms[0].as_ref() { + &Term::AnonVar | &Term::Clause(..) | &Term::Cons(..) => { + code.push(fail!()); + } + &Term::Constant(..) => { + code.push(succeed!()); + } + &Term::Var(ref vr, ref name) => { + let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code); + code.push(is_atomic!(r)); + } + }, + &InlinedClauseType::IsCompound(..) => match terms[0].as_ref() { + &Term::Clause(..) | &Term::Cons(..) => { + code.push(succeed!()); + } + &Term::Var(ref vr, ref name) => { + let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code); + code.push(is_compound!(r)); + } + _ => { + code.push(fail!()); + } + }, + &InlinedClauseType::IsRational(..) => match terms[0].as_ref() { + &Term::Constant(_, Constant::Rational(_)) => { + code.push(succeed!()); + } + &Term::Var(ref vr, ref name) => { + let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code); + code.push(is_rational!(r)); + } + _ => { + code.push(fail!()); } + }, + &InlinedClauseType::IsFloat(..) => match terms[0].as_ref() { + &Term::Constant(_, Constant::Float(_)) => { + code.push(succeed!()); + } + &Term::Var(ref vr, ref name) => { + let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code); + code.push(is_float!(r)); + } + _ => { + code.push(fail!()); + } + }, + &InlinedClauseType::IsString(..) => match terms[0].as_ref() { + &Term::Constant(_, Constant::String(_)) => { + code.push(succeed!()); + } + &Term::Var(ref vr, ref name) => { + let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code); + code.push(is_string!(r)); + } + _ => { + code.push(fail!()); + } + }, + &InlinedClauseType::IsNonVar(..) => match terms[0].as_ref() { + &Term::AnonVar => { + code.push(fail!()); + } + &Term::Var(ref vr, ref name) => { + let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code); + code.push(is_nonvar!(r)); + } + _ => { + code.push(succeed!()); + } + }, + &InlinedClauseType::IsInteger(..) => match terms[0].as_ref() { + &Term::Constant(_, Constant::CharCode(_)) + | &Term::Constant(_, Constant::Integer(_)) => { + code.push(succeed!()); + } + &Term::Var(ref vr, ref name) => { + let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code); + code.push(is_integer!(r)); + } + _ => { + code.push(fail!()); + } + }, + &InlinedClauseType::IsVar(..) => match terms[0].as_ref() { + &Term::Constant(..) | &Term::Clause(..) | &Term::Cons(..) => { + code.push(fail!()); + } + &Term::AnonVar => { + code.push(succeed!()); + } + &Term::Var(ref vr, ref name) => { + let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code); + code.push(is_var!(r)); + } + }, + &InlinedClauseType::IsPartialString(..) => match terms[0].as_ref() { + &Term::Var(ref vr, ref name) => { + let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code); + code.push(is_partial_string!(r)); + } + _ => code.push(fail!()), + }, } Ok(()) } - fn call_arith_eval(&self, term: &'a Term, target_int: usize) -> Result - { + fn call_arith_eval( + &self, + term: &'a Term, + target_int: usize, + ) -> Result { let mut evaluator = ArithmeticEvaluator::new(self.marker.bindings(), target_int); evaluator.eval(term) } - fn compile_is_call(&mut self, terms: &'a Vec>, code: &mut Code, - term_loc: GenContext, use_default_call_policy: bool) - -> Result<(), ParserError> - { + fn compile_is_call( + &mut self, + terms: &'a Vec>, + code: &mut Code, + term_loc: GenContext, + use_default_call_policy: bool, + ) -> Result<(), ParserError> { let (mut acode, at) = self.call_arith_eval(terms[1].as_ref(), 1)?; code.append(&mut acode); @@ -474,8 +507,8 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator let mut target = vec![]; self.marker.reset_arg(2); - self.marker.mark_var(name.clone(), Level::Shallow, vr, - term_loc, &mut target); + self.marker + .mark_var(name.clone(), Level::Shallow, vr, term_loc, &mut target); if !target.is_empty() { code.extend(target.into_iter().map(Line::Query)); @@ -486,65 +519,88 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator } else { code.push(is_call!(temp_v!(1), at.unwrap_or(interm!(1)))) } - }, + } &Term::Constant(_, ref c @ Constant::Integer(_)) => { - code.push(Line::Query(put_constant!(Level::Shallow, c.clone(), temp_v!(1)))); + code.push(Line::Query(put_constant!( + Level::Shallow, + c.clone(), + temp_v!(1) + ))); if use_default_call_policy { code.push(is_call_by_default!(temp_v!(1), at.unwrap_or(interm!(1)))) } else { code.push(is_call!(temp_v!(1), at.unwrap_or(interm!(1)))) } - }, + } &Term::Constant(_, ref c @ Constant::Float(_)) => { - code.push(Line::Query(put_constant!(Level::Shallow, c.clone(), temp_v!(1)))); + code.push(Line::Query(put_constant!( + Level::Shallow, + c.clone(), + temp_v!(1) + ))); if use_default_call_policy { code.push(is_call_by_default!(temp_v!(1), at.unwrap_or(interm!(1)))) } else { code.push(is_call!(temp_v!(1), at.unwrap_or(interm!(1)))) } - }, + } &Term::Constant(_, ref c @ Constant::Rational(_)) => { - code.push(Line::Query(put_constant!(Level::Shallow, c.clone(), temp_v!(1)))); + code.push(Line::Query(put_constant!( + Level::Shallow, + c.clone(), + temp_v!(1) + ))); if use_default_call_policy { code.push(is_call_by_default!(temp_v!(1), at.unwrap_or(interm!(1)))) } else { code.push(is_call!(temp_v!(1), at.unwrap_or(interm!(1)))) } - }, - _ => code.push(fail!()) + } + _ => code.push(fail!()), }) } #[inline] - fn compile_unblocked_cut(&mut self, code: &mut Code, cell: &'a Cell) - { + fn compile_unblocked_cut(&mut self, code: &mut Code, cell: &'a Cell) { let r = self.marker.get(Rc::new(String::from("!"))); cell.set(VarReg::Norm(r)); code.push(set_cp!(cell.get().norm())); } - fn compile_get_level_and_unify(&mut self, code: &mut Code, cell: &'a Cell, - var: Rc, term_loc: GenContext) - { + fn compile_get_level_and_unify( + &mut self, + code: &mut Code, + cell: &'a Cell, + var: Rc, + term_loc: GenContext, + ) { let mut target = Vec::new(); self.marker.reset_arg(1); - self.marker.mark_var(var, Level::Shallow, cell, term_loc, &mut target); + self.marker + .mark_var(var, Level::Shallow, cell, term_loc, &mut target); if !target.is_empty() { - code.extend(target.into_iter().map(|query_instr| Line::Query(query_instr))); + code.extend( + target + .into_iter() + .map(|query_instr| Line::Query(query_instr)), + ); } code.push(get_level_and_unify!(cell.get().norm())); } - fn compile_seq(&mut self, iter: ChunkedIterator<'a>, conjunct_info: &ConjunctInfo<'a>, - code: &mut Code, is_exposed: bool) - -> Result<(), ParserError> - { + fn compile_seq( + &mut self, + iter: ChunkedIterator<'a>, + conjunct_info: &ConjunctInfo<'a>, + code: &mut Code, + is_exposed: bool, + ) -> Result<(), ParserError> { for (chunk_num, _, terms) in iter.rule_body_iter() { for (i, term) in terms.iter().enumerate() { let term_loc = if i + 1 < terms.len() { @@ -554,21 +610,24 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator }; match *term { - &QueryTerm::GetLevelAndUnify(ref cell, ref var) => - self.compile_get_level_and_unify(code, cell, var.clone(), term_loc), - &QueryTerm::UnblockedCut(ref cell) => - self.compile_unblocked_cut(code, cell), - &QueryTerm::BlockedCut => - code.push(if chunk_num == 0 { - Line::Cut(CutInstruction::NeckCut) - } else { - Line::Cut(CutInstruction::Cut(perm_v!(1))) - }), - &QueryTerm::Clause(_, ClauseType::BuiltIn(BuiltInClauseType::Is(..)), - ref terms, use_default_call_policy) - => self.compile_is_call(terms, code, term_loc, use_default_call_policy)?, - &QueryTerm::Clause(_, ClauseType::Inlined(ref ct), ref terms, _) - => self.compile_inlined(ct, terms, term_loc, code)?, + &QueryTerm::GetLevelAndUnify(ref cell, ref var) => { + self.compile_get_level_and_unify(code, cell, var.clone(), term_loc) + } + &QueryTerm::UnblockedCut(ref cell) => self.compile_unblocked_cut(code, cell), + &QueryTerm::BlockedCut => code.push(if chunk_num == 0 { + Line::Cut(CutInstruction::NeckCut) + } else { + Line::Cut(CutInstruction::Cut(perm_v!(1))) + }), + &QueryTerm::Clause( + _, + ClauseType::BuiltIn(BuiltInClauseType::Is(..)), + ref terms, + use_default_call_policy, + ) => self.compile_is_call(terms, code, term_loc, use_default_call_policy)?, + &QueryTerm::Clause(_, ClauseType::Inlined(ref ct), ref terms, _) => { + self.compile_inlined(ct, terms, term_loc, code)? + } _ => { let num_perm_vars = if chunk_num == 0 { conjunct_info.perm_vars() @@ -577,7 +636,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator }; self.compile_query_line(term, term_loc, code, num_perm_vars, is_exposed); - }, + } } } @@ -587,8 +646,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator Ok(()) } - fn compile_seq_prelude(&mut self, conjunct_info: &ConjunctInfo, body: &mut Code) - { + fn compile_seq_prelude(&mut self, conjunct_info: &ConjunctInfo, body: &mut Code) { if conjunct_info.allocates() { let perm_vars = conjunct_info.perm_vars(); @@ -600,8 +658,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator } } - fn compile_cleanup(code: &mut Code, conjunct_info: &ConjunctInfo, toc: &'a QueryTerm) - { + fn compile_cleanup(code: &mut Code, conjunct_info: &ConjunctInfo, toc: &'a QueryTerm) { // add a proceed to bookend any trailing cuts. match toc { &QueryTerm::BlockedCut | &QueryTerm::UnblockedCut(..) => code.push(proceed!()), @@ -617,12 +674,14 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator } } - pub fn compile_rule<'b: 'a>(&mut self, rule: &'b Rule) -> Result - { + pub fn compile_rule<'b: 'a>(&mut self, rule: &'b Rule) -> Result { let iter = ChunkedIterator::from_rule(rule); let conjunct_info = self.collect_var_data(iter); - let &Rule { head: (_, ref args, ref p1), ref clauses } = rule; + let &Rule { + head: (_, ref args, ref p1), + ref clauses, + } = rule; let mut code = Vec::new(); self.marker.reset_at_head(args); @@ -652,8 +711,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator Ok(code) } - fn mark_unsafe_fact_vars(&self, fact: &mut CompiledFact) -> UnsafeVarMarker - { + fn mark_unsafe_fact_vars(&self, fact: &mut CompiledFact) -> UnsafeVarMarker { let mut unsafe_vars = IndexMap::new(); for var_status in self.marker.bindings().values() { @@ -662,17 +720,19 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator for fact_instr in fact.iter_mut() { match fact_instr { - &mut FactInstruction::UnifyValue(reg) => + &mut FactInstruction::UnifyValue(reg) => { if let Some(found) = unsafe_vars.get_mut(®) { if !*found { *found = true; *fact_instr = FactInstruction::UnifyLocalValue(reg); } - }, - &mut FactInstruction::UnifyVariable(reg) => + } + } + &mut FactInstruction::UnifyVariable(reg) => { if let Some(found) = unsafe_vars.get_mut(®) { *found = true; - }, + } + } _ => {} }; } @@ -680,8 +740,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator UnsafeVarMarker { unsafe_vars } } - pub fn compile_fact<'b: 'a>(&mut self, term: &'b Term) -> Code - { + pub fn compile_fact<'b: 'a>(&mut self, term: &'b Term) -> Code { self.update_var_count(post_order_iter(term)); let mut vs = VariableFixtures::new(); @@ -711,12 +770,17 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator code } - fn compile_query_line(&mut self, term: &'a QueryTerm, term_loc: GenContext, - code: &mut Code, num_perm_vars_left: usize, is_exposed: bool) - { + fn compile_query_line( + &mut self, + term: &'a QueryTerm, + term_loc: GenContext, + code: &mut Code, + num_perm_vars_left: usize, + is_exposed: bool, + ) { self.marker.reset_arg(term.arity()); - let iter = query_term_post_order_iter(term); + let iter = query_term_post_order_iter(term); let query = self.compile_target(iter, term_loc, is_exposed); if !query.is_empty() { @@ -728,8 +792,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator Self::add_conditional_call(code, term, num_perm_vars_left); } - pub fn compile_query(&mut self, query: &'a Vec) -> Result - { + pub fn compile_query(&mut self, query: &'a Vec) -> Result { let iter = ChunkedIterator::from_term_sequence(query); let conjunct_info = self.collect_var_data(iter); @@ -750,8 +813,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator Ok(code) } - fn split_predicate(clauses: &Vec) -> Vec<(usize, usize)> - { + fn split_predicate(clauses: &Vec) -> Vec<(usize, usize)> { let mut subseqs = Vec::new(); let mut left_index = 0; @@ -764,7 +826,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator subseqs.push((right_index, right_index + 1)); left_index = right_index + 1; - }, + } _ => {} } } @@ -792,29 +854,28 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator } } - fn compile_pred_subseq<'b: 'a>(&mut self, clauses: &'b [PredicateClause]) - -> Result - { + fn compile_pred_subseq<'b: 'a>( + &mut self, + clauses: &'b [PredicateClause], + ) -> Result { let mut code_body = Vec::new(); let mut code_offsets = CodeOffsets::new(self.flags); - let num_clauses = clauses.len(); + let num_clauses = clauses.len(); for (i, clause) in clauses.iter().enumerate() { self.marker.reset(); let mut clause_code = match clause { - &PredicateClause::Fact(ref fact) => - self.compile_fact(fact), - &PredicateClause::Rule(ref rule) => - try!(self.compile_rule(rule)) + &PredicateClause::Fact(ref fact) => self.compile_fact(fact), + &PredicateClause::Rule(ref rule) => try!(self.compile_rule(rule)), }; if num_clauses > 1 { let choice = match i { 0 => ChoiceInstruction::TryMeElse(clause_code.len() + 1), _ if i == num_clauses - 1 => self.trust_me(), - _ => self.retry_me_else(clause_code.len() + 1) + _ => self.retry_me_else(clause_code.len() + 1), }; code_body.push(Line::Choice(choice)); @@ -834,21 +895,22 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator Ok(code) } - pub fn compile_predicate<'b: 'a>(&mut self, clauses: &'b Vec) - -> Result - { - let mut code = Vec::new(); + pub fn compile_predicate<'b: 'a>( + &mut self, + clauses: &'b Vec, + ) -> Result { + let mut code = Vec::new(); let split_pred = Self::split_predicate(&clauses); - let multi_seq = split_pred.len() > 1; + let multi_seq = split_pred.len() > 1; for (l, r) in split_pred { - let mut code_segment = try!(self.compile_pred_subseq(&clauses[l .. r])); + let mut code_segment = try!(self.compile_pred_subseq(&clauses[l..r])); if multi_seq { let choice = match l { 0 => ChoiceInstruction::TryMeElse(code_segment.len() + 1), _ if r == clauses.len() => self.trust_me(), - _ => self.retry_me_else(code_segment.len() + 1) + _ => self.retry_me_else(code_segment.len() + 1), }; code.push(Line::Choice(choice)); diff --git a/src/prolog/debray_allocator.rs b/src/prolog/debray_allocator.rs index ce0357bd..de5a8651 100644 --- a/src/prolog/debray_allocator.rs +++ b/src/prolog/debray_allocator.rs @@ -3,8 +3,8 @@ use indexmap::IndexMap; use prolog_parser::ast::*; use prolog::allocator::*; -use prolog::forms::*; use prolog::fixtures::*; +use prolog::forms::*; use prolog::machine::machine_indices::*; use prolog::targets::*; @@ -14,27 +14,25 @@ use std::rc::Rc; pub struct DebrayAllocator { bindings: IndexMap, VarData>, - arg_c: usize, - temp_lb: usize, - arity: usize, // 0 if not at head. + arg_c: usize, + temp_lb: usize, + arity: usize, // 0 if not at head. contents: IndexMap>, - in_use: BTreeSet, + in_use: BTreeSet, } impl DebrayAllocator { fn is_curr_arg_distinct_from(&self, var: &Var) -> bool { match self.contents.get(&self.arg_c) { Some(t_var) if **t_var != *var => true, - _ => false + _ => false, } } - fn occurs_shallowly_in_head(&self, var: &Var, r: usize) -> bool - { + fn occurs_shallowly_in_head(&self, var: &Var, r: usize) -> bool { match self.bindings.get(var).unwrap() { - &VarData::Temp(_, _, ref tvd) => - tvd.use_set.contains(&(GenContext::Head, r)), - _ => false + &VarData::Temp(_, _, ref tvd) => tvd.use_set.contains(&(GenContext::Head, r)), + _ => false, } } @@ -44,8 +42,7 @@ impl DebrayAllocator { in_use_range || self.in_use.contains(&r) } - fn alloc_with_cr(&self, var: &Var) -> usize - { + fn alloc_with_cr(&self, var: &Var) -> usize { match self.bindings.get(var) { Some(&VarData::Temp(_, _, ref tvd)) => { for &(_, reg) in tvd.use_set.iter() { @@ -56,7 +53,7 @@ impl DebrayAllocator { let mut result = 0; - for reg in self.temp_lb .. { + for reg in self.temp_lb.. { if !self.is_in_use(reg) { if !tvd.no_use_set.contains(®) { result = reg; @@ -66,13 +63,12 @@ impl DebrayAllocator { } result - }, - _ => 0 + } + _ => 0, } } - fn alloc_with_ca(&self, var: &Var) -> usize - { + fn alloc_with_ca(&self, var: &Var) -> usize { match self.bindings.get(var) { Some(&VarData::Temp(_, _, ref tvd)) => { for &(_, reg) in tvd.use_set.iter() { @@ -83,7 +79,7 @@ impl DebrayAllocator { let mut result = 0; - for reg in self.temp_lb .. { + for reg in self.temp_lb.. { if !self.is_in_use(reg) { if !tvd.no_use_set.contains(®) { if !tvd.conflict_set.contains(®) { @@ -95,13 +91,12 @@ impl DebrayAllocator { } result - }, - _ => 0 + } + _ => 0, } } - fn alloc_in_last_goal_hint(&self, chunk_num: usize) -> Option<(Rc, usize)> - { + fn alloc_in_last_goal_hint(&self, chunk_num: usize) -> Option<(Rc, usize)> { // we want to allocate a register to the k^{th} parameter, par_k. // par_k may not be a temporary variable. let k = self.arg_c; @@ -121,13 +116,14 @@ impl DebrayAllocator { } None - }, - _ => None + } + _ => None, } } fn evacuate_arg<'a, Target>(&mut self, chunk_num: usize, target: &mut Vec) - where Target: CompilationTarget<'a> + where + Target: CompilationTarget<'a>, { match self.alloc_in_last_goal_hint(chunk_num) { Some((var, r)) => { @@ -144,42 +140,47 @@ impl DebrayAllocator { self.record_register(var, r); self.in_use.insert(r.reg_num()); } - }, + } _ => {} }; } - fn alloc_reg_to_var<'a, Target>(&mut self, var: &Var, lvl: Level, term_loc: GenContext, - target: &mut Vec) - -> usize - where Target: CompilationTarget<'a> + fn alloc_reg_to_var<'a, Target>( + &mut self, + var: &Var, + lvl: Level, + term_loc: GenContext, + target: &mut Vec, + ) -> usize + where + Target: CompilationTarget<'a>, { match term_loc { - GenContext::Head => + GenContext::Head => { if let Level::Shallow = lvl { self.evacuate_arg(0, target); self.alloc_with_cr(var) } else { self.alloc_with_ca(var) - }, - GenContext::Mid(_) => - self.alloc_with_ca(var), - GenContext::Last(chunk_num) => + } + } + GenContext::Mid(_) => self.alloc_with_ca(var), + GenContext::Last(chunk_num) => { if let Level::Shallow = lvl { self.evacuate_arg(chunk_num, target); self.alloc_with_cr(var) } else { self.alloc_with_ca(var) } + } } } - fn alloc_reg_to_non_var(&mut self) -> usize - { + fn alloc_reg_to_non_var(&mut self) -> usize { let mut final_index = 0; - for index in self.temp_lb .. { - if !self.in_use.contains(&index) { + for index in self.temp_lb.. { + if !self.in_use.contains(&index) { final_index = index; break; } @@ -190,33 +191,32 @@ impl DebrayAllocator { final_index } - fn in_place(&self, var: &Var, term_loc: GenContext, r: RegType, k: usize) -> bool - { + fn in_place(&self, var: &Var, term_loc: GenContext, r: RegType, k: usize) -> bool { match term_loc { GenContext::Head if !r.is_perm() => r.reg_num() == k, _ => match self.bindings().get(var).unwrap() { - &VarData::Temp(_, o, _) if r.reg_num() == k => o == k, - _ => false - } + &VarData::Temp(_, o, _) if r.reg_num() == k => o == k, + _ => false, + }, } } } -impl<'a> Allocator<'a> for DebrayAllocator -{ +impl<'a> Allocator<'a> for DebrayAllocator { fn new() -> DebrayAllocator { DebrayAllocator { - arity: 0, - arg_c: 1, + arity: 0, + arg_c: 1, temp_lb: 1, bindings: IndexMap::new(), contents: IndexMap::new(), - in_use: BTreeSet::new() + in_use: BTreeSet::new(), } } fn mark_anon_var(&mut self, lvl: Level, term_loc: GenContext, target: &mut Vec) - where Target: CompilationTarget<'a> + where + Target: CompilationTarget<'a>, { let r = RegType::Temp(self.alloc_reg_to_non_var()); @@ -230,15 +230,20 @@ impl<'a> Allocator<'a> for DebrayAllocator } self.arg_c += 1; - + target.push(Target::argument_to_variable(r, k)); } }; } - fn mark_non_var(&mut self, lvl: Level, term_loc: GenContext, - cell: &Cell, target: &mut Vec) - where Target: CompilationTarget<'a> + fn mark_non_var( + &mut self, + lvl: Level, + term_loc: GenContext, + cell: &Cell, + target: &mut Vec, + ) where + Target: CompilationTarget<'a>, { let r = cell.get(); @@ -252,7 +257,7 @@ impl<'a> Allocator<'a> for DebrayAllocator self.arg_c += 1; RegType::Temp(k) - }, + } _ if r.reg_num() == 0 => RegType::Temp(self.alloc_reg_to_non_var()), _ => { self.in_use.insert(r.reg_num()); @@ -263,34 +268,47 @@ impl<'a> Allocator<'a> for DebrayAllocator cell.set(r); } - fn mark_var(&mut self, var: Rc, lvl: Level, cell: &'a Cell, - term_loc: GenContext, target: &mut Vec) - where Target: CompilationTarget<'a> + fn mark_var( + &mut self, + var: Rc, + lvl: Level, + cell: &'a Cell, + term_loc: GenContext, + target: &mut Vec, + ) where + Target: CompilationTarget<'a>, { let (r, is_new_var) = match self.get(var.clone()) { RegType::Temp(0) => { // here, r is temporary *and* unassigned. let o = self.alloc_reg_to_var(&var, lvl, term_loc, target); cell.set(VarReg::Norm(RegType::Temp(o))); - + (RegType::Temp(o), true) - }, + } RegType::Perm(0) => { let pr = cell.get().norm(); self.record_register(var.clone(), pr); - + (pr, true) - }, - r => (r, false) + } + r => (r, false), }; self.mark_reserved_var(var, lvl, cell, term_loc, target, r, is_new_var); } - fn mark_reserved_var(&mut self, var: Rc, lvl: Level, cell: &'a Cell, - term_loc: GenContext, target: &mut Vec, r: RegType, - is_new_var: bool) - where Target: CompilationTarget<'a> + fn mark_reserved_var( + &mut self, + var: Rc, + lvl: Level, + cell: &'a Cell, + term_loc: GenContext, + target: &mut Vec, + r: RegType, + is_new_var: bool, + ) where + Target: CompilationTarget<'a>, { match lvl { Level::Root | Level::Shallow => { @@ -311,8 +329,8 @@ impl<'a> Allocator<'a> for DebrayAllocator target.push(Target::argument_to_value(r, k)); } } - }, - Level::Deep if is_new_var => + } + Level::Deep if is_new_var => { if let GenContext::Head = term_loc { if self.occurs_shallowly_in_head(&var, r.reg_num()) { target.push(Target::subterm_to_value(r)); @@ -321,9 +339,9 @@ impl<'a> Allocator<'a> for DebrayAllocator } } else { target.push(Target::subterm_to_variable(r)); - }, - Level::Deep => - target.push(Target::subterm_to_value(r)) + } + } + Level::Deep => target.push(Target::subterm_to_value(r)), }; if !r.is_perm() { @@ -380,8 +398,8 @@ impl<'a> Allocator<'a> for DebrayAllocator } fn reset_arg(&mut self, arity: usize) { - self.arity = 0; - self.arg_c = 1; + self.arity = 0; + self.arg_c = 1; self.temp_lb = arity + 1; } } diff --git a/src/prolog/fixtures.rs b/src/prolog/fixtures.rs index 1dababac..2d4e8912 100644 --- a/src/prolog/fixtures.rs +++ b/src/prolog/fixtures.rs @@ -7,15 +7,16 @@ use prolog::iterators::*; use indexmap::IndexMap; use std::cell::Cell; -use std::collections::{BTreeMap, BTreeSet}; use std::collections::btree_map::{IntoIter, IterMut, Values}; +use std::collections::{BTreeMap, BTreeSet}; use std::mem::swap; use std::rc::Rc; use std::vec::Vec; // labeled with chunk numbers. pub enum VarStatus { - Perm(usize), Temp(usize, TempVarData) // Perm(chunk_num) | Temp(chunk_num, _) + Perm(usize), + Temp(usize, TempVarData), // Perm(chunk_num) | Temp(chunk_num, _) } pub type OccurrenceSet = BTreeSet<(GenContext, usize)>; @@ -23,14 +24,15 @@ pub type OccurrenceSet = BTreeSet<(GenContext, usize)>; // Perm: 0 initially, a stack register once processed. // Temp: labeled with chunk_num and temp offset (unassigned if 0). pub enum VarData { - Perm(usize), Temp(usize, usize, TempVarData) + Perm(usize), + Temp(usize, usize, TempVarData), } impl VarData { pub fn as_reg_type(&self) -> RegType { match self { &VarData::Temp(_, r, _) => RegType::Temp(r), - &VarData::Perm(r) => RegType::Perm(r) + &VarData::Perm(r) => RegType::Perm(r), } } } @@ -39,7 +41,7 @@ pub struct TempVarData { pub last_term_arity: usize, pub use_set: OccurrenceSet, pub no_use_set: BTreeSet, - pub conflict_set: BTreeSet + pub conflict_set: BTreeSet, } impl TempVarData { @@ -48,7 +50,7 @@ impl TempVarData { last_term_arity: last_term_arity, use_set: BTreeSet::new(), no_use_set: BTreeSet::new(), - conflict_set: BTreeSet::new() + conflict_set: BTreeSet::new(), } } @@ -65,7 +67,7 @@ impl TempVarData { pub fn populate_conflict_set(&mut self) { if self.last_term_arity > 0 { let arity = self.last_term_arity; - let mut conflict_set : BTreeSet = (1..arity).collect(); + let mut conflict_set: BTreeSet = (1..arity).collect(); for &(_, reg) in self.use_set.iter() { conflict_set.remove(®); @@ -79,8 +81,7 @@ impl TempVarData { type VariableFixture<'a> = (VarStatus, Vec<&'a Cell>); pub struct VariableFixtures<'a>(BTreeMap, VariableFixture<'a>>); -impl<'a> VariableFixtures<'a> -{ +impl<'a> VariableFixtures<'a> { pub fn new() -> Self { VariableFixtures(BTreeMap::new()) } @@ -90,8 +91,7 @@ impl<'a> VariableFixtures<'a> } // computes no_use and conflict sets for all temp vars. - pub fn populate_restricting_sets(&mut self) - { + pub fn populate_restricting_sets(&mut self) { // three stages: // 1. move the use sets of each variable to a local IndexMap, use_set // (iterate mutably, swap mutable refs). @@ -133,7 +133,7 @@ impl<'a> VariableFixtures<'a> &mut (VarStatus::Temp(_, ref mut u_data), _) => { u_data.use_set = use_set; u_data.populate_conflict_set(); - }, + } _ => {} }; } @@ -147,21 +147,16 @@ impl<'a> VariableFixtures<'a> self.0.iter_mut() } - fn record_temp_info(&mut self, - tvd: &mut TempVarData, - arg_c: usize, - term_loc: GenContext) - { + fn record_temp_info(&mut self, tvd: &mut TempVarData, arg_c: usize, term_loc: GenContext) { match term_loc { GenContext::Head | GenContext::Last(_) => { tvd.use_set.insert((term_loc, arg_c)); - }, + } _ => {} }; } - pub fn vars_above_threshold(&self, index: usize) -> usize - { + pub fn vars_above_threshold(&self, index: usize) -> usize { let mut var_count = 0; for &(ref var_status, _) in self.values() { @@ -176,25 +171,28 @@ impl<'a> VariableFixtures<'a> } pub fn mark_vars_in_chunk(&mut self, iter: I, lt_arity: usize, term_loc: GenContext) - where I: Iterator> + where + I: Iterator>, { let chunk_num = term_loc.chunk_num(); let mut arg_c = 1; for term_ref in iter { if let &TermRef::Var(lvl, cell, ref var) = &term_ref { - let mut status = self.0.remove(var) - .unwrap_or((VarStatus::Temp(chunk_num, TempVarData::new(lt_arity)), - Vec::new())); + let mut status = self.0.remove(var).unwrap_or(( + VarStatus::Temp(chunk_num, TempVarData::new(lt_arity)), + Vec::new(), + )); status.1.push(cell); match status.0 { - VarStatus::Temp(cn, ref mut tvd) if cn == chunk_num => + VarStatus::Temp(cn, ref mut tvd) if cn == chunk_num => { if let Level::Shallow = lvl { self.record_temp_info(tvd, arg_c, term_loc); - }, - _ => status.0 = VarStatus::Perm(chunk_num) + } + } + _ => status.0 = VarStatus::Perm(chunk_num), }; self.0.insert(var.clone(), status); @@ -218,14 +216,12 @@ impl<'a> VariableFixtures<'a> self.0.len() } - pub fn set_perm_vals(&self, has_deep_cuts: bool) - { - let mut values_vec : Vec<_> = self.values() - .filter_map(|ref v| { - match &v.0 { - &VarStatus::Perm(i) => Some((i, &v.1)), - _ => None - } + pub fn set_perm_vals(&self, has_deep_cuts: bool) { + let mut values_vec: Vec<_> = self + .values() + .filter_map(|ref v| match &v.0 { + &VarStatus::Perm(i) => Some((i, &v.1)), + _ => None, }) .collect(); @@ -242,13 +238,13 @@ impl<'a> VariableFixtures<'a> } pub struct UnsafeVarMarker { - pub unsafe_vars: IndexMap + pub unsafe_vars: IndexMap, } impl UnsafeVarMarker { pub fn new() -> Self { UnsafeVarMarker { - unsafe_vars: IndexMap::new() + unsafe_vars: IndexMap::new(), } } @@ -264,35 +260,38 @@ impl UnsafeVarMarker { pub fn mark_safe_vars(&mut self, query_instr: &mut QueryInstruction) { match query_instr { - &mut QueryInstruction::PutVariable(RegType::Temp(r), _) => + &mut QueryInstruction::PutVariable(RegType::Temp(r), _) => { if let Some(found) = self.unsafe_vars.get_mut(&RegType::Temp(r)) { *found = true; - }, - &mut QueryInstruction::SetVariable(reg) => + } + } + &mut QueryInstruction::SetVariable(reg) => { if let Some(found) = self.unsafe_vars.get_mut(®) { *found = true; - }, + } + } _ => {} } } - pub fn mark_unsafe_vars(&mut self, query_instr: &mut QueryInstruction) - { + pub fn mark_unsafe_vars(&mut self, query_instr: &mut QueryInstruction) { match query_instr { - &mut QueryInstruction::PutValue(RegType::Perm(i), arg) => + &mut QueryInstruction::PutValue(RegType::Perm(i), arg) => { if let Some(found) = self.unsafe_vars.get_mut(&RegType::Perm(i)) { if !*found { *found = true; *query_instr = QueryInstruction::PutUnsafeValue(i, arg); } - }, - &mut QueryInstruction::SetValue(reg) => + } + } + &mut QueryInstruction::SetValue(reg) => { if let Some(found) = self.unsafe_vars.get_mut(®) { if !*found { *found = true; *query_instr = QueryInstruction::SetLocalValue(reg); } - }, + } + } _ => {} } } diff --git a/src/prolog/forms.rs b/src/prolog/forms.rs index 1979b79a..1fe27002 100644 --- a/src/prolog/forms.rs +++ b/src/prolog/forms.rs @@ -34,11 +34,9 @@ impl TopLevel { match self { &TopLevel::Declaration(_) => None, &TopLevel::Fact(ref term) => term.name(), - &TopLevel::Predicate(ref clauses) => - clauses.0.first().and_then(|ref term| term.name()), + &TopLevel::Predicate(ref clauses) => clauses.0.first().and_then(|ref term| term.name()), &TopLevel::Query(_) => None, - &TopLevel::Rule(Rule { ref head, .. }) => - Some(head.0.clone()) + &TopLevel::Rule(Rule { ref head, .. }) => Some(head.0.clone()), } } @@ -46,33 +44,34 @@ impl TopLevel { match self { &TopLevel::Declaration(_) => 0, &TopLevel::Fact(ref term) => term.arity(), - &TopLevel::Predicate(ref clauses) => - clauses.0.first().map(|t| t.arity()).unwrap_or(0), + &TopLevel::Predicate(ref clauses) => clauses.0.first().map(|t| t.arity()).unwrap_or(0), &TopLevel::Query(_) => 0, - &TopLevel::Rule(Rule { ref head, .. }) => head.1.len() + &TopLevel::Rule(Rule { ref head, .. }) => head.1.len(), } } pub fn is_end_of_file_atom(&self) -> bool { match self { - &TopLevel::Fact(Term::Constant(_, Constant::Atom(ref name, _))) => - return name.as_str() == "end_of_file", - _ => - false + &TopLevel::Fact(Term::Constant(_, Constant::Atom(ref name, _))) => { + return name.as_str() == "end_of_file" + } + _ => false, } } } #[derive(Clone, Copy)] pub enum Level { - Deep, Root, Shallow + Deep, + Root, + Shallow, } impl Level { pub fn child_level(self) -> Level { match self { Level::Root => Level::Shallow, - _ => Level::Deep + _ => Level::Deep, } } } @@ -84,7 +83,7 @@ pub enum QueryTerm { BlockedCut, // a cut which is 'blocked by letters', like the P term in P -> Q. UnblockedCut(Cell), GetLevelAndUnify(Cell, Rc), - Jump(JumpStub) + Jump(JumpStub), } impl QueryTerm { @@ -108,7 +107,7 @@ impl QueryTerm { #[derive(Clone)] pub struct Rule { pub head: (ClauseName, Vec>, QueryTerm), - pub clauses: Vec + pub clauses: Vec, } #[derive(Clone)] @@ -127,7 +126,8 @@ impl Predicate { #[inline] pub fn predicate_indicator(&self) -> Option<(ClauseName, usize)> { - self.0.first() + self.0 + .first() .and_then(|clause| clause.name().map(|name| (name, clause.arity()))) } } @@ -137,7 +137,7 @@ pub type CompiledResult = (Predicate, VecDeque); #[derive(Clone)] pub enum PredicateClause { Fact(Term), - Rule(Rule) + Rule(Rule), } impl PredicateClause { @@ -151,7 +151,7 @@ impl PredicateClause { pub fn arity(&self) -> usize { match self { &PredicateClause::Fact(ref term) => term.arity(), - &PredicateClause::Rule(ref rule) => rule.head.1.len() + &PredicateClause::Rule(ref rule) => rule.head.1.len(), } } @@ -166,7 +166,7 @@ impl PredicateClause { #[derive(Clone)] pub enum ModuleSource { Library(ClauseName), - File(ClauseName) + File(ClauseName), } #[derive(Clone)] @@ -178,18 +178,26 @@ pub enum Declaration { NonCountedBacktracking(ClauseName, usize), // name, arity Op(OpDecl), UseModule(ModuleSource), - UseQualifiedModule(ModuleSource, Vec) + UseQualifiedModule(ModuleSource, Vec), } impl Declaration { #[inline] pub fn is_module_decl(&self) -> bool { - if let &Declaration::Module(_) = self { true } else { false } + if let &Declaration::Module(_) = self { + true + } else { + false + } } #[inline] pub fn is_end_of_file(&self) -> bool { - if let &Declaration::EndOfFile = self { true } else { false } + if let &Declaration::EndOfFile = self { + true + } else { + false + } } } @@ -207,15 +215,14 @@ impl OpDecl { self.insert_into_op_dir(clause_name!(""), op_dir, 0); } - fn insert_into_op_dir(&self, module: ClauseName, op_dir: &mut OpDir, prec: usize) - { + fn insert_into_op_dir(&self, module: ClauseName, op_dir: &mut OpDir, prec: usize) { let (spec, name) = (self.1, self.2.clone()); let fixity = match spec { XFY | XFX | YFX => Fixity::In, XF | YF => Fixity::Post, FX | FY => Fixity::Pre, - _ => return + _ => return, }; match op_dir.get(&(name.clone(), fixity)) { @@ -229,9 +236,12 @@ impl OpDecl { op_dir.insert((name, fixity), OpDirValue::new(spec, prec, module)); } - pub fn submit(&self, module: ClauseName, existing_desc: Option, op_dir: &mut OpDir) - -> Result<(), SessionError> - { + pub fn submit( + &self, + module: ClauseName, + existing_desc: Option, + op_dir: &mut OpDir, + ) -> Result<(), SessionError> { let (prec, spec, name) = (self.0, self.1, self.2.clone()); if is_infix!(spec) { @@ -254,43 +264,49 @@ impl OpDecl { } } -pub -fn fetch_atom_op_spec(name: ClauseName, spec: Option, op_dir: &OpDir) - -> Option -{ +pub fn fetch_atom_op_spec( + name: ClauseName, + spec: Option, + op_dir: &OpDir, +) -> Option { fetch_op_spec(name.clone(), 1, spec.clone(), op_dir) .or_else(|| fetch_op_spec(name, 2, spec, op_dir)) } -pub -fn fetch_op_spec(name: ClauseName, arity: usize, spec: Option, op_dir: &OpDir) - -> Option -{ - spec.or_else(|| { - match arity { - 2 => op_dir.get(&(name, Fixity::In)).and_then(|OpDirValue(spec, _)| +pub fn fetch_op_spec( + name: ClauseName, + arity: usize, + spec: Option, + op_dir: &OpDir, +) -> Option { + spec.or_else(|| match arity { + 2 => op_dir + .get(&(name, Fixity::In)) + .and_then(|OpDirValue(spec, _)| { if spec.prec() > 0 { Some(spec.clone()) } else { None - }), - 1 => { - if let Some(OpDirValue(spec, _)) = op_dir.get(&(name.clone(), Fixity::Pre)) { - if spec.prec() > 0 { - return Some(spec.clone()); - } } + }), + 1 => { + if let Some(OpDirValue(spec, _)) = op_dir.get(&(name.clone(), Fixity::Pre)) { + if spec.prec() > 0 { + return Some(spec.clone()); + } + } - op_dir.get(&(name.clone(), Fixity::Post)) - .and_then(|OpDirValue(spec, _)| - if spec.prec() > 0 { - Some(spec.clone()) - } else { - None - }) - }, - _ => None + op_dir + .get(&(name.clone(), Fixity::Post)) + .and_then(|OpDirValue(spec, _)| { + if spec.prec() > 0 { + Some(spec.clone()) + } else { + None + } + }) } + _ => None, }) } @@ -299,7 +315,7 @@ pub type ModuleDir = IndexMap; #[derive(Clone)] pub struct ModuleDecl { pub name: ClauseName, - pub exports: Vec + pub exports: Vec, } pub struct Module { @@ -311,14 +327,14 @@ pub struct Module { pub goal_expansions: (Predicate, VecDeque), pub user_term_expansions: (Predicate, VecDeque), // term expansions inherited from the user scope. pub user_goal_expansions: (Predicate, VecDeque), // same for goal_expansions. - pub inserted_expansions: bool // has the module been successfully inserted into toplevel?? + pub inserted_expansions: bool, // has the module been successfully inserted into toplevel?? } #[derive(Clone, PartialEq, Eq)] pub enum Number { Float(OrderedFloat), Integer(Integer), - Rational(Rational) + Rational(Rational), } impl Default for Number { @@ -332,7 +348,7 @@ impl Number { match self { Number::Integer(n) => Constant::Integer(n), Number::Float(f) => Constant::Float(f), - Number::Rational(r) => Constant::Rational(r) + Number::Rational(r) => Constant::Rational(r), } } @@ -341,7 +357,7 @@ impl Number { match self { &Number::Integer(ref n) => n > &0, &Number::Float(OrderedFloat(f)) => f.is_sign_positive(), - &Number::Rational(ref r) => r > &0 + &Number::Rational(ref r) => r > &0, } } @@ -350,7 +366,7 @@ impl Number { match self { &Number::Integer(ref n) => n < &0, &Number::Float(OrderedFloat(f)) => f.is_sign_negative(), - &Number::Rational(ref r) => r < &0 + &Number::Rational(ref r) => r < &0, } } @@ -359,7 +375,7 @@ impl Number { match self { &Number::Integer(ref n) => n == &0, &Number::Float(f) => f == OrderedFloat(0f64), - &Number::Rational(ref r) => r == &0 + &Number::Rational(ref r) => r == &0, } } @@ -368,7 +384,7 @@ impl Number { match self { Number::Integer(n) => Number::Integer(n.abs()), Number::Float(f) => Number::Float(OrderedFloat(f.abs())), - Number::Rational(r) => Number::Rational(r.abs()) + Number::Rational(r) => Number::Rational(r.abs()), } } } diff --git a/src/prolog/heap_iter.rs b/src/prolog/heap_iter.rs index 7a160998..9ebc820f 100644 --- a/src/prolog/heap_iter.rs +++ b/src/prolog/heap_iter.rs @@ -11,14 +11,14 @@ use std::vec::Vec; pub struct HCPreOrderIterator<'a> { pub machine_st: &'a MachineState, - pub state_stack: Vec + pub state_stack: Vec, } impl<'a> HCPreOrderIterator<'a> { - pub fn new(machine_st: &'a MachineState, a: Addr) -> Self - { + pub fn new(machine_st: &'a MachineState, a: Addr) -> Self { HCPreOrderIterator { - machine_st, state_stack: vec![a] + machine_st, + state_stack: vec![a], } } @@ -26,59 +26,59 @@ impl<'a> HCPreOrderIterator<'a> { &self.machine_st } - fn follow_heap(&mut self, h: usize) -> Addr - { + fn follow_heap(&mut self, h: usize) -> Addr { match &self.machine_st.heap[h] { &HeapCellValue::NamedStr(arity, _, _) => { - for idx in (1 .. arity + 1).rev() { + for idx in (1..arity + 1).rev() { self.state_stack.push(Addr::HeapCell(h + idx)); } Addr::HeapCell(h) - }, - &HeapCellValue::Addr(ref a) => - self.follow(a.clone()) + } + &HeapCellValue::Addr(ref a) => self.follow(a.clone()), } } // called under the assumption that the location at r is about to // be visited, and so any follow up states need to be added to // state_stack. returns the dereferenced Addr from Ref. - fn follow(&mut self, addr: Addr) -> Addr - { + fn follow(&mut self, addr: Addr) -> Addr { let da = self.machine_st.store(self.machine_st.deref(addr)); match da { Addr::Con(Constant::String(ref s)) => { match self.machine_st.machine_flags().double_quotes { - DoubleQuotes::Chars => + DoubleQuotes::Chars => { if let Some(c) = s.head() { let tail = s.tail(); self.state_stack.push(Addr::Con(Constant::String(tail))); self.state_stack.push(Addr::Con(Constant::Char(c))); - }, - DoubleQuotes::Codes => + } + } + DoubleQuotes::Codes => { if let Some(c) = s.head() { let tail = s.tail(); self.state_stack.push(Addr::Con(Constant::String(tail))); - self.state_stack.push(Addr::Con(Constant::CharCode(c as u8))); - }, + self.state_stack + .push(Addr::Con(Constant::CharCode(c as u8))); + } + } _ => {} } Addr::Con(Constant::String(s.clone())) - }, + } Addr::Con(_) | Addr::DBRef(_) => da, Addr::Lis(a) => { self.state_stack.push(Addr::HeapCell(a + 1)); self.state_stack.push(Addr::HeapCell(a)); da - }, + } Addr::AttrVar(_) | Addr::HeapCell(_) | Addr::StackCell(_, _) => da, - Addr::Str(s) => self.follow_heap(s) // record terms of structure. + Addr::Str(s) => self.follow_heap(s), // record terms of structure. } } } @@ -87,26 +87,26 @@ impl<'a> Iterator for HCPreOrderIterator<'a> { type Item = HeapCellValue; fn next(&mut self) -> Option { - self.state_stack.pop().map(|a| { - match self.follow(a) { - Addr::HeapCell(h) => - self.machine_st.heap[h].clone(), - Addr::StackCell(fr, sc) => - HeapCellValue::Addr(self.machine_st.and_stack[fr][sc].clone()), - da => - HeapCellValue::Addr(da) + self.state_stack.pop().map(|a| match self.follow(a) { + Addr::HeapCell(h) => self.machine_st.heap[h].clone(), + Addr::StackCell(fr, sc) => { + HeapCellValue::Addr(self.machine_st.and_stack[fr][sc].clone()) } + da => HeapCellValue::Addr(da), }) } } -pub trait MutStackHCIterator where Self: Iterator { +pub trait MutStackHCIterator +where + Self: Iterator, +{ fn stack(&mut self) -> &mut Vec; } pub struct HCPostOrderIterator { - base_iter: HCIter, - parent_stack: Vec<(usize, HeapCellValue)> // number of children, parent node. + base_iter: HCIter, + parent_stack: Vec<(usize, HeapCellValue)>, // number of children, parent node. } impl Deref for HCPostOrderIterator { @@ -117,16 +117,16 @@ impl Deref for HCPostOrderIterator { } } -impl> HCPostOrderIterator { +impl> HCPostOrderIterator { pub fn new(base_iter: HCIter) -> Self { HCPostOrderIterator { base_iter, - parent_stack: vec![] + parent_stack: vec![], } } } -impl> Iterator for HCPostOrderIterator { +impl> Iterator for HCPostOrderIterator { type Item = HeapCellValue; fn next(&mut self) -> Option { @@ -141,10 +141,12 @@ impl> Iterator for HCPostOrderIterator - self.parent_stack.push((arity, HeapCellValue::NamedStr(arity, name, fix))), - HeapCellValue::Addr(Addr::Lis(a)) => - self.parent_stack.push((2, HeapCellValue::Addr(Addr::Lis(a)))), + HeapCellValue::NamedStr(arity, name, fix) => self + .parent_stack + .push((arity, HeapCellValue::NamedStr(arity, name, fix))), + HeapCellValue::Addr(Addr::Lis(a)) => self + .parent_stack + .push((2, HeapCellValue::Addr(Addr::Lis(a)))), child_node => { return Some(child_node); } @@ -167,16 +169,22 @@ impl MachineState { HCPostOrderIterator::new(HCPreOrderIterator::new(self, a)) } - pub fn acyclic_pre_order_iter<'a>(&'a self, a: Addr) -> HCAcyclicIterator> - { + pub fn acyclic_pre_order_iter<'a>( + &'a self, + a: Addr, + ) -> HCAcyclicIterator> { HCAcyclicIterator::new(HCPreOrderIterator::new(self, a)) } - pub fn zipped_acyclic_pre_order_iter<'a>(&'a self, a1: Addr, a2: Addr) - -> HCZippedAcyclicIterator> - { - HCZippedAcyclicIterator::new(HCPreOrderIterator::new(self, a1), - HCPreOrderIterator::new(self, a2)) + pub fn zipped_acyclic_pre_order_iter<'a>( + &'a self, + a1: Addr, + a2: Addr, + ) -> HCZippedAcyclicIterator> { + HCZippedAcyclicIterator::new( + HCPreOrderIterator::new(self, a1), + HCPreOrderIterator::new(self, a2), + ) } } @@ -188,13 +196,15 @@ impl<'a> MutStackHCIterator for HCPreOrderIterator<'a> { pub struct HCAcyclicIterator { iter: HCIter, - seen: IndexSet + seen: IndexSet, } -impl HCAcyclicIterator -{ +impl HCAcyclicIterator { pub fn new(iter: HCIter) -> Self { - HCAcyclicIterator { iter, seen: IndexSet::new() } + HCAcyclicIterator { + iter, + seen: IndexSet::new(), + } } } @@ -207,7 +217,8 @@ impl Deref for HCAcyclicIterator { } impl Iterator for HCAcyclicIterator - where HCIter: Iterator + MutStackHCIterator +where + HCIter: Iterator + MutStackHCIterator, { type Item = HeapCellValue; @@ -229,19 +240,23 @@ pub struct HCZippedAcyclicIterator { i1: HCIter, i2: HCIter, seen: IndexSet<(Addr, Addr)>, - pub first_to_expire: Ordering + pub first_to_expire: Ordering, } -impl HCZippedAcyclicIterator -{ +impl HCZippedAcyclicIterator { pub fn new(i1: HCIter, i2: HCIter) -> Self { - HCZippedAcyclicIterator { i1, i2, seen: IndexSet::new(), - first_to_expire: Ordering::Equal } + HCZippedAcyclicIterator { + i1, + i2, + seen: IndexSet::new(), + first_to_expire: Ordering::Equal, + } } } impl Iterator for HCZippedAcyclicIterator - where HCIter: Iterator + MutStackHCIterator +where + HCIter: Iterator + MutStackHCIterator, { type Item = (HeapCellValue, HeapCellValue); @@ -257,17 +272,16 @@ impl Iterator for HCZippedAcyclicIterator } match (self.i1.next(), self.i2.next()) { - (Some(v1), Some(v2)) => - Some((v1, v2)), + (Some(v1), Some(v2)) => Some((v1, v2)), (Some(_), None) => { self.first_to_expire = Ordering::Greater; None - }, + } (None, Some(_)) => { self.first_to_expire = Ordering::Less; None - }, - _ => None + } + _ => None, } } } diff --git a/src/prolog/heap_print.rs b/src/prolog/heap_print.rs index 49182e0f..c04b4223 100644 --- a/src/prolog/heap_print.rs +++ b/src/prolog/heap_print.rs @@ -7,7 +7,7 @@ use prolog::heap_iter::*; use prolog::machine::machine_indices::*; use prolog::machine::machine_state::*; use prolog::ordered_float::OrderedFloat; -use prolog::rug::{Integer}; +use prolog::rug::Integer; use indexmap::{IndexMap, IndexSet}; @@ -20,23 +20,23 @@ use std::rc::Rc; #[derive(Clone)] pub enum DirectedOp { Left(ClauseName, SharedOpDesc), - Right(ClauseName, SharedOpDesc) + Right(ClauseName, SharedOpDesc), } impl DirectedOp { #[inline] fn as_str(&self) -> &str { match self { - &DirectedOp::Left(ref name, _) | &DirectedOp::Right(ref name, _) => - name.as_str() + &DirectedOp::Left(ref name, _) | &DirectedOp::Right(ref name, _) => name.as_str(), } } #[inline] fn is_negative_sign(&self) -> bool { match self { - &DirectedOp::Left(ref name, ref cell) | &DirectedOp::Right(ref name, ref cell) => + &DirectedOp::Left(ref name, ref cell) | &DirectedOp::Right(ref name, ref cell) => { name.as_str() == "-" && is_prefix!(cell.assoc()) + } } } @@ -50,8 +50,7 @@ impl DirectedOp { } } -fn needs_bracketing(child_spec: &SharedOpDesc, op: &DirectedOp) -> bool -{ +fn needs_bracketing(child_spec: &SharedOpDesc, op: &DirectedOp) -> bool { match op { &DirectedOp::Left(ref name, ref cell) => { let (priority, spec) = cell.get(); @@ -65,7 +64,7 @@ fn needs_bracketing(child_spec: &SharedOpDesc, op: &DirectedOp) -> bool let is_strict_right = is_yfx!(spec) || is_xfx!(spec) || is_fx!(spec); child_spec.prec() > priority || (child_spec.prec() == priority && is_strict_right) - }, + } &DirectedOp::Right(_, ref cell) => { let (priority, spec) = cell.get(); let is_strict_left = is_xfx!(spec) || is_xfy!(spec) || is_xf!(spec); @@ -89,53 +88,51 @@ impl<'a> HCPreOrderIterator<'a> { * by brackets. */ fn leftmost_leaf_has_property

(&self, property_check: P) -> bool - where P: Fn(Constant) -> bool + where + P: Fn(Constant) -> bool, { let mut addr = match self.state_stack.last().cloned() { Some(addr) => addr, - None => return false + None => return false, }; let mut parent_spec = DirectedOp::Left(clause_name!("-"), SharedOpDesc::new(200, FY)); loop { match self.machine_st.store(self.machine_st.deref(addr)) { - Addr::Str(s) => - match &self.machine_st.heap[s] { - &HeapCellValue::NamedStr(_, ref name, Some(ref spec)) - if is_postfix!(spec.assoc()) || is_infix!(spec.assoc()) => - if needs_bracketing(spec, &parent_spec) { - return false; - } else { - addr = Addr::HeapCell(s+1); - parent_spec = DirectedOp::Right(name.clone(), spec.clone()); - }, - _ => - return false - }, - Addr::Con(Constant::Integer(n)) => - return property_check(Constant::Integer(n)), - Addr::Con(Constant::Float(n)) => - return property_check(Constant::Float(n)), - Addr::Con(Constant::Rational(n)) => - return property_check(Constant::Rational(n)), - _ => - return false + Addr::Str(s) => match &self.machine_st.heap[s] { + &HeapCellValue::NamedStr(_, ref name, Some(ref spec)) + if is_postfix!(spec.assoc()) || is_infix!(spec.assoc()) => + { + if needs_bracketing(spec, &parent_spec) { + return false; + } else { + addr = Addr::HeapCell(s + 1); + parent_spec = DirectedOp::Right(name.clone(), spec.clone()); + } + } + _ => return false, + }, + Addr::Con(Constant::Integer(n)) => return property_check(Constant::Integer(n)), + Addr::Con(Constant::Float(n)) => return property_check(Constant::Float(n)), + Addr::Con(Constant::Rational(n)) => return property_check(Constant::Rational(n)), + _ => return false, } } } fn immediate_leaf_has_property

(&self, property_check: P) -> bool - where P: Fn(Constant) -> bool + where + P: Fn(Constant) -> bool, { let addr = match self.state_stack.last().cloned() { Some(addr) => addr, - None => return false + None => return false, }; match self.machine_st.store(self.machine_st.deref(addr)) { Addr::Con(c) => property_check(c), - _ => false + _ => false, } } } @@ -150,8 +147,8 @@ fn char_to_string(c: char) -> String { '\u{0c}' => "\\f".to_string(), // UTF-8 form feed '\u{08}' => "\\b".to_string(), // UTF-8 backspace '\u{07}' => "\\a".to_string(), // UTF-8 alert - '\x20' ... '\x7e' => c.to_string(), - _ => format!("\\x{:x}\\", c as u32) + '\x20'...'\x7e' => c.to_string(), + _ => format!("\\x{:x}\\", c as u32), } } @@ -190,14 +187,16 @@ pub trait HCValueOutputter { } pub struct PrinterOutputter { - contents: String + contents: String, } impl HCValueOutputter for PrinterOutputter { type Output = String; fn new() -> Self { - PrinterOutputter { contents: String::new() } + PrinterOutputter { + contents: String::new(), + } } fn append(&mut self, contents: &str) { @@ -253,17 +252,15 @@ fn is_numbered_var(ct: &ClauseType, arity: usize) -> bool { } #[inline] -fn negated_op_needs_bracketing(iter: &HCPreOrderIterator, op: &Option) -> bool -{ +fn negated_op_needs_bracketing(iter: &HCPreOrderIterator, op: &Option) -> bool { if let &Some(ref op) = op { - op.is_negative_sign() && iter.leftmost_leaf_has_property(|c| { - match c { + op.is_negative_sign() + && iter.leftmost_leaf_has_property(|c| match c { Constant::Integer(n) => n > 0, Constant::Float(f) => f > OrderedFloat(0f64), Constant::Rational(r) => r > 0, - _ => false - } - }) + _ => false, + }) } else { false } @@ -271,26 +268,26 @@ fn negated_op_needs_bracketing(iter: &HCPreOrderIterator, op: &Option Option { - static CHAR_CODES: [char; 26] = ['A','B','C','D','E','F','G','H','I','J', - 'K','L','M','N','O','P','Q','R','S','T', - 'U','V','W','X','Y','Z']; + static CHAR_CODES: [char; 26] = [ + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', + 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + ]; match self.store(self.deref(addr)) { - Addr::Con(Constant::Integer(ref n)) - if n >= &0 => { - let n = Integer::from(offset + n); - - let i = n.mod_u(26) as usize; - let j = n.div_rem_floor(Integer::from(26)); - let j = <(Integer, Integer)>::from(j).1; - - Some(if j == 0 { - CHAR_CODES[i].to_string() - } else { - format!("{}{}", CHAR_CODES[i], j) - }) - }, - _ => None + Addr::Con(Constant::Integer(ref n)) if n >= &0 => { + let n = Integer::from(offset + n); + + let i = n.mod_u(26) as usize; + let j = n.div_rem_floor(Integer::from(26)); + let j = <(Integer, Integer)>::from(j).1; + + Some(if j == 0 { + CHAR_CODES[i].to_string() + } else { + format!("{}{}", CHAR_CODES[i], j) + }) + } + _ => None, } } } @@ -309,80 +306,94 @@ pub struct HCPrinter<'a, Outputter> { cyclic_terms: IndexMap, pub(crate) var_names: IndexMap, pub(crate) numbervars_offset: Integer, - pub(crate) numbervars: bool, - pub(crate) quoted: bool, - pub(crate) ignore_ops: bool + pub(crate) numbervars: bool, + pub(crate) quoted: bool, + pub(crate) ignore_ops: bool, } macro_rules! push_space_if_amb { - ($self:expr, $atom:expr, $action:block) => ( + ($self:expr, $atom:expr, $action:block) => { if $self.ambiguity_check($atom) { $self.outputter.push_char(' '); $action; } else { $action; } - ) + }; } pub fn requires_space(atom: &str, op: &str) -> bool { match atom.chars().last() { - Some(ac) => op.chars().next().map(|oc| { - if ac == '0' { - oc == 'b' || oc == 'x' || oc == 'o' || oc == '\'' - } else if alpha_numeric_char!(ac) { - oc == '(' || alpha_numeric_char!(oc) - } else if graphic_token_char!(ac) { - graphic_token_char!(oc) - } else if variable_indicator_char!(ac) { - alpha_numeric_char!(oc) - } else if capital_letter_char!(ac) { - alpha_numeric_char!(oc) - } else if sign_char!(ac) { - sign_char!(oc) || decimal_digit_char!(oc) - } else if single_quote_char!(ac) { - single_quote_char!(oc) - } else { - false - } - }).unwrap_or(false), - _ => false + Some(ac) => op + .chars() + .next() + .map(|oc| { + if ac == '0' { + oc == 'b' || oc == 'x' || oc == 'o' || oc == '\'' + } else if alpha_numeric_char!(ac) { + oc == '(' || alpha_numeric_char!(oc) + } else if graphic_token_char!(ac) { + graphic_token_char!(oc) + } else if variable_indicator_char!(ac) { + alpha_numeric_char!(oc) + } else if capital_letter_char!(ac) { + alpha_numeric_char!(oc) + } else if sign_char!(ac) { + sign_char!(oc) || decimal_digit_char!(oc) + } else if single_quote_char!(ac) { + single_quote_char!(oc) + } else { + false + } + }) + .unwrap_or(false), + _ => false, } } -fn reverse_heap_locs<'a>(machine_st: &'a MachineState) -> ReverseHeapVarDict -{ - machine_st.heap_locs.iter().map(|(var, var_addr)| { - (machine_st.store(machine_st.deref(var_addr.clone())), var.clone()) - }).collect() +fn reverse_heap_locs<'a>(machine_st: &'a MachineState) -> ReverseHeapVarDict { + machine_st + .heap_locs + .iter() + .map(|(var, var_addr)| { + ( + machine_st.store(machine_st.deref(var_addr.clone())), + var.clone(), + ) + }) + .collect() } -fn non_quoted_graphic_token>(mut iter: Iter, c: char) -> bool { +fn non_quoted_graphic_token>(mut iter: Iter, c: char) -> bool { if c == '/' { return match iter.next() { None => true, Some('*') => false, // if we start with comment token, we must quote. - Some(c) => if graphic_token_char!(c) { - iter.all(|c| graphic_token_char!(c)) - } else { - false + Some(c) => { + if graphic_token_char!(c) { + iter.all(|c| graphic_token_char!(c)) + } else { + false + } } - } + }; } else if c == '.' { return match iter.next() { None => false, - Some(c) => if graphic_token_char!(c) { - iter.all(|c| graphic_token_char!(c)) - } else { - false + Some(c) => { + if graphic_token_char!(c) { + iter.all(|c| graphic_token_char!(c)) + } else { + false + } } - } + }; } else { iter.all(|c| graphic_token_char!(c)) } } -fn non_quoted_token>(mut iter: Iter) -> bool { +fn non_quoted_token>(mut iter: Iter) -> bool { if let Some(c) = iter.next() { if small_letter_char!(c) { iter.all(|c| alpha_numeric_char!(c)) @@ -406,32 +417,37 @@ fn non_quoted_token>(mut iter: Iter) -> bool { } } -impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> -{ - pub fn new(machine_st: &'a MachineState, op_dir: &'a OpDir, output: Outputter) -> Self - { - HCPrinter { outputter: output, - machine_st, - op_dir, - state_stack: vec![], - heap_locs: ReverseHeapVarDict::new(), - toplevel_spec: None, - printed_vars: IndexSet::new(), - last_item_idx: 0, - numbervars: false, - numbervars_offset: Integer::from(0), - quoted: false, - ignore_ops: false, - cyclic_terms: IndexMap::new(), - var_names: IndexMap::new() } - } - - pub fn from_heap_locs(machine_st: &'a MachineState, op_dir: &'a OpDir, output: Outputter) - -> Self - { +impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> { + pub fn new(machine_st: &'a MachineState, op_dir: &'a OpDir, output: Outputter) -> Self { + HCPrinter { + outputter: output, + machine_st, + op_dir, + state_stack: vec![], + heap_locs: ReverseHeapVarDict::new(), + toplevel_spec: None, + printed_vars: IndexSet::new(), + last_item_idx: 0, + numbervars: false, + numbervars_offset: Integer::from(0), + quoted: false, + ignore_ops: false, + cyclic_terms: IndexMap::new(), + var_names: IndexMap::new(), + } + } + + pub fn from_heap_locs( + machine_st: &'a MachineState, + op_dir: &'a OpDir, + output: Outputter, + ) -> Self { let mut printer = Self::new(machine_st, op_dir, output); - printer.toplevel_spec = Some(DirectedOp::Right(clause_name!("="), SharedOpDesc::new(700, XFX))); + printer.toplevel_spec = Some(DirectedOp::Right( + clause_name!("="), + SharedOpDesc::new(700, XFX), + )); printer.heap_locs = reverse_heap_locs(machine_st); printer @@ -449,9 +465,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> } #[inline] - fn ambiguity_check(&self, atom: &str) -> bool - { - let tail = self.outputter.range_from(self.last_item_idx ..); + fn ambiguity_check(&self, atom: &str) -> bool { + let tail = self.outputter.range_from(self.last_item_idx..); requires_space(tail, atom) } @@ -460,7 +475,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> let right_directed_op = DirectedOp::Right(ct.name(), spec.clone()); self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec)); - self.state_stack.push(TokenOrRedirect::CompositeRedirect(right_directed_op)); + self.state_stack + .push(TokenOrRedirect::CompositeRedirect(right_directed_op)); } else if is_prefix!(spec.assoc()) { match ct.name().as_str() { "-" | "\\" => { @@ -472,31 +488,34 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> let left_directed_op = DirectedOp::Left(ct.name(), spec.clone()); - self.state_stack.push(TokenOrRedirect::CompositeRedirect(left_directed_op)); + self.state_stack + .push(TokenOrRedirect::CompositeRedirect(left_directed_op)); self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec)); - } else { // if is_infix!(spec.assoc()) + } else { + // if is_infix!(spec.assoc()) match ct.name().as_str() { "|" => { self.format_bar_separator_op(ct.name(), spec); return; - }, + } _ => {} }; - let left_directed_op = DirectedOp::Left(ct.name(), spec.clone()); + let left_directed_op = DirectedOp::Left(ct.name(), spec.clone()); let right_directed_op = DirectedOp::Right(ct.name(), spec.clone()); - self.state_stack.push(TokenOrRedirect::CompositeRedirect(left_directed_op)); + self.state_stack + .push(TokenOrRedirect::CompositeRedirect(left_directed_op)); self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec)); - self.state_stack.push(TokenOrRedirect::CompositeRedirect(right_directed_op)); + self.state_stack + .push(TokenOrRedirect::CompositeRedirect(right_directed_op)); } } - fn format_struct(&mut self, arity: usize, name: ClauseName) - { + fn format_struct(&mut self, arity: usize, name: ClauseName) { self.state_stack.push(TokenOrRedirect::Close); - for _ in 0 .. arity { + for _ in 0..arity { self.state_stack.push(TokenOrRedirect::FunctorRedirect); self.state_stack.push(TokenOrRedirect::Comma); } @@ -507,34 +526,33 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> self.state_stack.push(TokenOrRedirect::Atom(name)); } - fn format_prefix_op_with_space(&mut self, name: ClauseName, spec: SharedOpDesc) - { + fn format_prefix_op_with_space(&mut self, name: ClauseName, spec: SharedOpDesc) { let op = DirectedOp::Left(name.clone(), spec); - self.state_stack.push(TokenOrRedirect::CompositeRedirect(op)); + self.state_stack + .push(TokenOrRedirect::CompositeRedirect(op)); self.state_stack.push(TokenOrRedirect::Space); self.state_stack.push(TokenOrRedirect::Atom(name)); } - fn format_bar_separator_op(&mut self, name: ClauseName, spec: SharedOpDesc) - { - let left_directed_op = DirectedOp::Left(name.clone(), spec.clone()); + fn format_bar_separator_op(&mut self, name: ClauseName, spec: SharedOpDesc) { + let left_directed_op = DirectedOp::Left(name.clone(), spec.clone()); let right_directed_op = DirectedOp::Right(name.clone(), spec.clone()); - self.state_stack.push(TokenOrRedirect::CompositeRedirect(left_directed_op)); + self.state_stack + .push(TokenOrRedirect::CompositeRedirect(left_directed_op)); self.state_stack.push(TokenOrRedirect::HeadTailSeparator); - self.state_stack.push(TokenOrRedirect::CompositeRedirect(right_directed_op)); + self.state_stack + .push(TokenOrRedirect::CompositeRedirect(right_directed_op)); } - fn format_curly_braces(&mut self) - { + fn format_curly_braces(&mut self) { self.state_stack.push(TokenOrRedirect::RightCurly); self.state_stack.push(TokenOrRedirect::FunctorRedirect); self.state_stack.push(TokenOrRedirect::LeftCurly); } - fn format_numbered_vars(&mut self, iter: &mut HCPreOrderIterator) -> bool - { + fn format_numbered_vars(&mut self, iter: &mut HCPreOrderIterator) -> bool { let addr = iter.stack().last().cloned().unwrap(); // 7.10.4 @@ -547,8 +565,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> false } - fn format_clause(&mut self, iter: &mut HCPreOrderIterator, arity: usize, ct: ClauseType) - { + fn format_clause(&mut self, iter: &mut HCPreOrderIterator, arity: usize, ct: ClauseType) { if self.numbervars && is_numbered_var(&ct, arity) { if self.format_numbered_vars(iter) { return; @@ -570,7 +587,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> match (ct.name().as_str(), arity) { ("{}", 1) if !self.ignore_ops => self.format_curly_braces(), - _ => self.format_struct(arity, ct.name()) + _ => self.format_struct(arity, ct.name()), }; } @@ -586,8 +603,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> self.outputter.append(s); } - fn offset_as_string(&self, iter: &mut HCPreOrderIterator, addr: Addr) -> Option - { + fn offset_as_string(&self, iter: &mut HCPreOrderIterator, addr: Addr) -> Option { if let Some(var) = self.var_names.get(&addr) { if addr.as_var().is_some() { return Some(format!("{}", var)); @@ -598,55 +614,56 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> } match addr { - Addr::AttrVar(h) => - Some(format!("_{}", h + 1)), - Addr::HeapCell(h) | Addr::Lis(h) | Addr::Str(h) => - Some(format!("_{}", h)), - Addr::StackCell(fr, sc) => - Some(format!("_s_{}_{}", fr, sc)), - _ => None + Addr::AttrVar(h) => Some(format!("_{}", h + 1)), + Addr::HeapCell(h) | Addr::Lis(h) | Addr::Str(h) => Some(format!("_{}", h)), + Addr::StackCell(fr, sc) => Some(format!("_s_{}_{}", fr, sc)), + _ => None, } } - fn check_for_seen(&mut self, iter: &mut HCPreOrderIterator) -> Option - { + fn check_for_seen(&mut self, iter: &mut HCPreOrderIterator) -> Option { iter.stack().last().cloned().and_then(|addr| { let addr = self.machine_st.store(self.machine_st.deref(addr)); match self.heap_locs.get(&addr).cloned() { - Some(var) => if !self.printed_vars.contains(&addr) { - self.printed_vars.insert(addr); - return iter.next(); - } else { - iter.stack().pop(); - push_space_if_amb!(self, &var, { - self.append_str(&var); - }); + Some(var) => { + if !self.printed_vars.contains(&addr) { + self.printed_vars.insert(addr); + return iter.next(); + } else { + iter.stack().pop(); + push_space_if_amb!(self, &var, { + self.append_str(&var); + }); - return None; - }, - None => if self.machine_st.is_cyclic_term(addr.clone()) { - match self.cyclic_terms.get(&addr).cloned() { - Some(reps) => - if reps > 0 { - self.cyclic_terms.insert(addr, reps - 1); + return None; + } + } + None => { + if self.machine_st.is_cyclic_term(addr.clone()) { + match self.cyclic_terms.get(&addr).cloned() { + Some(reps) => { + if reps > 0 { + self.cyclic_terms.insert(addr, reps - 1); + iter.next() + } else { + push_space_if_amb!(self, "...", { + self.append_str("..."); + }); + + iter.stack().pop(); + self.cyclic_terms.remove(&addr); + None + } + } + None => { + self.cyclic_terms.insert(addr, 2); iter.next() - } else { - push_space_if_amb!(self, "...", { - self.append_str("..."); - }); - - iter.stack().pop(); - self.cyclic_terms.remove(&addr); - None - }, - None => { - self.cyclic_terms.insert(addr, 2); - iter.next() + } } + } else { + iter.next() } - } else { - iter.next() } } }) @@ -708,7 +725,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> } match n { - Number::Float(fl) => + Number::Float(fl) => { if &fl == &OrderedFloat(0f64) { push_space_if_amb!(self, "0", { self.append_str("0"); @@ -720,7 +737,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> push_space_if_amb!(self, &output_str, { self.append_str(&output_str.trim()); }); - }, + } + } n => { let output_str = format!("{}", n); @@ -737,7 +755,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> fn print_constant(&mut self, c: Constant, op: &Option) { match c { - Constant::Atom(atom, spec) => + Constant::Atom(atom, spec) => { if let Some(_) = fetch_atom_op_spec(atom.clone(), spec, self.op_dir) { let mut result = String::new(); @@ -762,14 +780,15 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> push_space_if_amb!(self, atom.as_str(), { self.print_atom(&atom); }); - }, + } + } Constant::Char(c) if non_quoted_token(once(c)) => { let c = char_to_string(c); push_space_if_amb!(self, &c, { self.append_str(c.as_str()); }); - }, + } Constant::Char(c) => { let mut result = String::new(); @@ -784,27 +803,20 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> push_space_if_amb!(self, &result, { self.append_str(result.as_str()); }); - }, - Constant::CharCode(c) => - self.append_str(&format!("{}", c)), - Constant::EmptyList => - self.append_str("[]"), - Constant::Integer(n) => - self.print_number(Number::Integer(n), op), - Constant::Float(n) => - self.print_number(Number::Float(n), op), - Constant::Rational(n) => - self.print_number(Number::Rational(n), op), - Constant::String(s) => - self.print_string(s), - Constant::Usize(i) => - self.append_str(&format!("u{}", i)) + } + Constant::CharCode(c) => self.append_str(&format!("{}", c)), + Constant::EmptyList => self.append_str("[]"), + Constant::Integer(n) => self.print_number(Number::Integer(n), op), + Constant::Float(n) => self.print_number(Number::Float(n), op), + Constant::Rational(n) => self.print_number(Number::Rational(n), op), + Constant::String(s) => self.print_string(s), + Constant::Usize(i) => self.append_str(&format!("u{}", i)), } } fn print_string(&mut self, s: StringList) { match self.machine_st.machine_flags().double_quotes { - DoubleQuotes::Chars | DoubleQuotes::Codes => + DoubleQuotes::Chars | DoubleQuotes::Codes => { if !s.is_empty() { if self.ignore_ops { self.format_struct(2, clause_name!(".")); @@ -817,12 +829,13 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> } } else if !self.at_cdr("") { self.append_str("[]"); - }, + } + } DoubleQuotes::Atom => { let borrowed_str = s.borrow(); let mut atom = String::new(); - for c in borrowed_str[s.cursor() ..].chars() { + for c in borrowed_str[s.cursor()..].chars() { atom += &char_to_string(c); } @@ -836,7 +849,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> fn push_list(&mut self) { let cell = Rc::new(Cell::new(true)); - self.state_stack.push(TokenOrRedirect::CloseList(cell.clone())); + self.state_stack + .push(TokenOrRedirect::CloseList(cell.clone())); self.state_stack.push(TokenOrRedirect::FunctorRedirect); self.state_stack.push(TokenOrRedirect::HeadTailSeparator); // bar @@ -845,27 +859,32 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> self.state_stack.push(TokenOrRedirect::OpenList(cell)); } - fn handle_op_as_struct(&mut self, name: ClauseName, arity: usize, iter: &mut HCPreOrderIterator, - op: &Option, is_functor_redirect: bool, spec: SharedOpDesc, - negated_operand: bool) - { + fn handle_op_as_struct( + &mut self, + name: ClauseName, + arity: usize, + iter: &mut HCPreOrderIterator, + op: &Option, + is_functor_redirect: bool, + spec: SharedOpDesc, + negated_operand: bool, + ) { let add_brackets = if !self.ignore_ops { - negated_operand || if let Some(ref op) = op { - if self.numbervars && arity == 1 && name.as_str() == "$VAR" { - !iter.immediate_leaf_has_property(|c| { - match c { + negated_operand + || if let Some(ref op) = op { + if self.numbervars && arity == 1 && name.as_str() == "$VAR" { + !iter.immediate_leaf_has_property(|c| match c { Constant::Integer(n) => n >= 0, Constant::Float(f) => f >= OrderedFloat(0f64), Constant::Rational(r) => r >= 0, - _ => false - } - }) && needs_bracketing(&spec, op) + _ => false, + }) && needs_bracketing(&spec, op) + } else { + needs_bracketing(&spec, op) + } } else { - needs_bracketing(&spec, op) + is_functor_redirect && spec.prec() >= 1000 } - } else { - is_functor_redirect && spec.prec() >= 1000 - } } else { false }; @@ -888,46 +907,58 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> } } - - fn handle_heap_term(&mut self, iter: &mut HCPreOrderIterator, op: Option, - is_functor_redirect: bool) - { + fn handle_heap_term( + &mut self, + iter: &mut HCPreOrderIterator, + op: Option, + is_functor_redirect: bool, + ) { let negated_operand = negated_op_needs_bracketing(iter, &op); let heap_val = match self.check_for_seen(iter) { Some(heap_val) => heap_val, - None => return + None => return, }; match heap_val { - HeapCellValue::NamedStr(arity, name, spec) => + HeapCellValue::NamedStr(arity, name, spec) => { if let Some(spec) = fetch_op_spec(name.clone(), arity, spec.clone(), self.op_dir) { - self.handle_op_as_struct(name, arity, iter, &op, is_functor_redirect, spec, - negated_operand); + self.handle_op_as_struct( + name, + arity, + iter, + &op, + is_functor_redirect, + spec, + negated_operand, + ); } else { push_space_if_amb!(self, name.as_str(), { let ct = ClauseType::from(name, arity, spec); self.format_clause(iter, arity, ct); }); - }, - HeapCellValue::Addr(Addr::Con(Constant::EmptyList)) => + } + } + HeapCellValue::Addr(Addr::Con(Constant::EmptyList)) => { if !self.at_cdr("") { self.append_str("[]"); - }, - HeapCellValue::Addr(Addr::Con(c)) => - self.print_constant(c, &op), - HeapCellValue::Addr(Addr::Lis(_)) => + } + } + HeapCellValue::Addr(Addr::Con(c)) => self.print_constant(c, &op), + HeapCellValue::Addr(Addr::Lis(_)) => { if self.ignore_ops { self.format_struct(2, clause_name!(".")); } else { self.push_list(); - }, - HeapCellValue::Addr(addr) => + } + } + HeapCellValue::Addr(addr) => { if let Some(offset_str) = self.offset_as_string(iter, addr) { push_space_if_amb!(self, &offset_str, { self.append_str(offset_str.as_str()); }) } + } } } @@ -950,40 +981,34 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> loop { if let Some(loc_data) = self.state_stack.pop() { match loc_data { - TokenOrRedirect::Atom(atom) => - self.print_atom(&atom), - TokenOrRedirect::Op(atom, _) => - self.print_op(atom.as_str()), - TokenOrRedirect::NumberedVar(num_var) => - self.append_str(num_var.as_str()), - TokenOrRedirect::CompositeRedirect(op) => - self.handle_heap_term(&mut iter, Some(op), false), - TokenOrRedirect::FunctorRedirect => - self.handle_heap_term(&mut iter, None, true), - TokenOrRedirect::Close => - self.push_char(')'), - TokenOrRedirect::Open => - self.push_char('('), - TokenOrRedirect::OpenList(delimit) => + TokenOrRedirect::Atom(atom) => self.print_atom(&atom), + TokenOrRedirect::Op(atom, _) => self.print_op(atom.as_str()), + TokenOrRedirect::NumberedVar(num_var) => self.append_str(num_var.as_str()), + TokenOrRedirect::CompositeRedirect(op) => { + self.handle_heap_term(&mut iter, Some(op), false) + } + TokenOrRedirect::FunctorRedirect => { + self.handle_heap_term(&mut iter, None, true) + } + TokenOrRedirect::Close => self.push_char(')'), + TokenOrRedirect::Open => self.push_char('('), + TokenOrRedirect::OpenList(delimit) => { if !self.at_cdr(",") { self.push_char('['); } else { delimit.set(false); - }, - TokenOrRedirect::CloseList(delimit) => + } + } + TokenOrRedirect::CloseList(delimit) => { if delimit.get() { self.push_char(']'); - }, - TokenOrRedirect::HeadTailSeparator => - self.append_str("|"), - TokenOrRedirect::Comma => - self.append_str(","), - TokenOrRedirect::Space => - self.push_char(' '), - TokenOrRedirect::LeftCurly => - self.push_char('{'), - TokenOrRedirect::RightCurly => - self.push_char('}'), + } + } + TokenOrRedirect::HeadTailSeparator => self.append_str("|"), + TokenOrRedirect::Comma => self.append_str(","), + TokenOrRedirect::Space => self.push_char(' '), + TokenOrRedirect::LeftCurly => self.push_char('{'), + TokenOrRedirect::RightCurly => self.push_char('}'), } } else if !iter.stack().is_empty() { let spec = self.toplevel_spec.take(); diff --git a/src/prolog/indexing.rs b/src/prolog/indexing.rs index 27525077..cd47a31b 100644 --- a/src/prolog/indexing.rs +++ b/src/prolog/indexing.rs @@ -9,14 +9,16 @@ use std::hash::Hash; #[derive(Clone, Copy)] enum IntIndex { - External(usize), Fail, Internal(usize) + External(usize), + Fail, + Internal(usize), } pub struct CodeOffsets { flags: MachineFlags, - pub constants: IndexMap, + pub constants: IndexMap, pub lists: ThirdLevelIndex, - pub structures: IndexMap<(ClauseName, usize), ThirdLevelIndex> + pub structures: IndexMap<(ClauseName, usize), ThirdLevelIndex>, } impl CodeOffsets { @@ -25,15 +27,16 @@ impl CodeOffsets { flags, constants: IndexMap::new(), lists: Vec::new(), - structures: IndexMap::new() + structures: IndexMap::new(), } } fn cap_choice_seq_with_trust(prelude: &mut ThirdLevelIndex) { prelude.last_mut().map(|instr| { match instr { - &mut IndexedChoiceInstruction::Retry(i) => - *instr = IndexedChoiceInstruction::Trust(i), + &mut IndexedChoiceInstruction::Retry(i) => { + *instr = IndexedChoiceInstruction::Trust(i) + } _ => {} }; }); @@ -47,44 +50,50 @@ impl CodeOffsets { } } - pub fn index_term(&mut self, first_arg: &Term, index: usize) - { + pub fn index_term(&mut self, first_arg: &Term, index: usize) { match first_arg { &Term::Clause(_, ref name, ref terms, _) => { - let code = self.structures.entry((name.clone(), terms.len())) - .or_insert(Vec::new()); + let code = self + .structures + .entry((name.clone(), terms.len())) + .or_insert(Vec::new()); let is_initial_index = code.is_empty(); code.push(Self::add_index(is_initial_index, index)); - }, + } &Term::Cons(..) => { let is_initial_index = self.lists.is_empty(); self.lists.push(Self::add_index(is_initial_index, index)); - }, + } &Term::Constant(_, Constant::String(ref s)) - if !self.flags.double_quotes.is_atom() && !s.is_empty() => { // strings are lists in this case. - let is_initial_index = self.lists.is_empty(); - self.lists.push(Self::add_index(is_initial_index, index)); - }, + if !self.flags.double_quotes.is_atom() && !s.is_empty() => + { + // strings are lists in this case. + let is_initial_index = self.lists.is_empty(); + self.lists.push(Self::add_index(is_initial_index, index)); + } &Term::Constant(_, Constant::String(ref s)) - if !self.flags.double_quotes.is_atom() && s.is_expandable() => { - let is_initial_index = self.lists.is_empty(); - self.lists.push(Self::add_index(is_initial_index, index)); - }, + if !self.flags.double_quotes.is_atom() && s.is_expandable() => + { + let is_initial_index = self.lists.is_empty(); + self.lists.push(Self::add_index(is_initial_index, index)); + } &Term::Constant(_, ref constant) => { - let code = self.constants.entry(constant.clone()) - .or_insert(Vec::new()); + let code = self.constants.entry(constant.clone()).or_insert(Vec::new()); let is_initial_index = code.is_empty(); code.push(Self::add_index(is_initial_index, index)); - }, + } _ => {} }; } - fn second_level_index(indices: IndexMap, prelude: &mut CodeDeque) - -> IndexMap - where Index: Eq + Hash + fn second_level_index( + indices: IndexMap, + prelude: &mut CodeDeque, + ) -> IndexMap + where + Index: Eq + Hash, { let mut index_locs = IndexMap::new(); @@ -111,9 +120,9 @@ impl CodeOffsets { no_constants && no_structures && no_lists } - fn flatten_index(index: IndexMap, len: usize) - -> IndexMap - where Index: Eq + Hash + fn flatten_index(index: IndexMap, len: usize) -> IndexMap + where + Index: Eq + Hash, { let mut flattened_index = IndexMap::new(); @@ -121,10 +130,10 @@ impl CodeOffsets { match int_index { IntIndex::External(offset) => { flattened_index.insert(key, offset + len + 1); - }, + } IntIndex::Internal(offset) => { flattened_index.insert(key, offset + 1); - }, + } _ => {} }; } @@ -132,18 +141,18 @@ impl CodeOffsets { flattened_index } - fn adjust_internal_index(index: IntIndex) -> IntIndex - { + fn adjust_internal_index(index: IntIndex) -> IntIndex { match index { IntIndex::Internal(o) => IntIndex::Internal(o + 1), IntIndex::External(o) => IntIndex::External(o), - _ => IntIndex::Fail + _ => IntIndex::Fail, } } - fn switch_on_constant(con_ind: IndexMap, prelude: &mut CodeDeque) - -> IntIndex - { + fn switch_on_constant( + con_ind: IndexMap, + prelude: &mut CodeDeque, + ) -> IntIndex { let con_ind = Self::second_level_index(con_ind, prelude); if con_ind.len() > 1 { @@ -154,16 +163,18 @@ impl CodeOffsets { IntIndex::Internal(1) } else { - con_ind.values().next() - .map(|index| Self::adjust_internal_index(*index)) - .unwrap_or(IntIndex::Fail) + con_ind + .values() + .next() + .map(|index| Self::adjust_internal_index(*index)) + .unwrap_or(IntIndex::Fail) } } - fn switch_on_structure(str_ind: IndexMap<(ClauseName, usize), ThirdLevelIndex>, - prelude: &mut CodeDeque) - -> IntIndex - { + fn switch_on_structure( + str_ind: IndexMap<(ClauseName, usize), ThirdLevelIndex>, + prelude: &mut CodeDeque, + ) -> IntIndex { let str_ind = Self::second_level_index(str_ind, prelude); if str_ind.len() > 1 { @@ -174,40 +185,43 @@ impl CodeOffsets { IntIndex::Internal(1) } else { - str_ind.values().next() - .map(|index| Self::adjust_internal_index(*index)) - .unwrap_or(IntIndex::Fail) + str_ind + .values() + .next() + .map(|index| Self::adjust_internal_index(*index)) + .unwrap_or(IntIndex::Fail) } } - fn switch_on_list(mut lists: ThirdLevelIndex, prelude: &mut CodeDeque) -> IntIndex - { + fn switch_on_list(mut lists: ThirdLevelIndex, prelude: &mut CodeDeque) -> IntIndex { if lists.len() > 1 { Self::cap_choice_seq_with_trust(&mut lists); prelude.extend(lists.into_iter().map(|i| Line::from(i))); IntIndex::Internal(0) } else { - lists.first() - .map(|i| IntIndex::External(i.offset())) - .unwrap_or(IntIndex::Fail) + lists + .first() + .map(|i| IntIndex::External(i.offset())) + .unwrap_or(IntIndex::Fail) } } - fn switch_on_str_offset_from(str_loc: IntIndex, prelude_len: usize, con_loc: IntIndex) - -> usize - { + fn switch_on_str_offset_from( + str_loc: IntIndex, + prelude_len: usize, + con_loc: IntIndex, + ) -> usize { match str_loc { IntIndex::External(o) => o + prelude_len + 1, IntIndex::Fail => 0, IntIndex::Internal(_) => match con_loc { IntIndex::Internal(_) => 2, - _ => 1 - } + _ => 1, + }, } } - fn switch_on_con_offset_from(con_loc: IntIndex, prelude_len: usize) -> usize - { + fn switch_on_con_offset_from(con_loc: IntIndex, prelude_len: usize) -> usize { match con_loc { IntIndex::External(offset) => offset + prelude_len + 1, IntIndex::Fail => 0, @@ -215,18 +229,19 @@ impl CodeOffsets { } } - fn switch_on_lst_offset_from(lst_loc: IntIndex, prelude_len: usize, lst_offset: usize) - -> usize - { + fn switch_on_lst_offset_from( + lst_loc: IntIndex, + prelude_len: usize, + lst_offset: usize, + ) -> usize { match lst_loc { IntIndex::External(o) => o + prelude_len + 1, IntIndex::Fail => 0, - IntIndex::Internal(_) => prelude_len - lst_offset + 1 + IntIndex::Internal(_) => prelude_len - lst_offset + 1, } } - pub fn add_indices(self, code: &mut Code, mut code_body: Code) - { + pub fn add_indices(self, code: &mut Code, mut code_body: Code) { if self.no_indices() { *code = code_body; return; @@ -244,10 +259,11 @@ impl CodeOffsets { for (index, line) in prelude.iter_mut().enumerate() { match line { - &mut Line::IndexedChoice(IndexedChoiceInstruction::Try(ref mut i)) + &mut Line::IndexedChoice(IndexedChoiceInstruction::Try(ref mut i)) | &mut Line::IndexedChoice(IndexedChoiceInstruction::Retry(ref mut i)) - | &mut Line::IndexedChoice(IndexedChoiceInstruction::Trust(ref mut i)) => - *i += prelude_length - index, + | &mut Line::IndexedChoice(IndexedChoiceInstruction::Trust(ref mut i)) => { + *i += prelude_length - index + } _ => {} } } @@ -256,10 +272,8 @@ impl CodeOffsets { let con_loc = Self::switch_on_con_offset_from(con_loc, prelude.len()); let lst_loc = Self::switch_on_lst_offset_from(lst_loc, prelude.len(), lst_offset); - let switch_instr = IndexingInstruction::SwitchOnTerm(prelude.len() + 1, - con_loc, - lst_loc, - str_loc); + let switch_instr = + IndexingInstruction::SwitchOnTerm(prelude.len() + 1, con_loc, lst_loc, str_loc); prelude.push_front(Line::from(switch_instr)); diff --git a/src/prolog/instructions.rs b/src/prolog/instructions.rs index 588d95e2..e71351bc 100644 --- a/src/prolog/instructions.rs +++ b/src/prolog/instructions.rs @@ -13,22 +13,17 @@ use std::collections::VecDeque; fn reg_type_into_functor(r: RegType) -> MachineStub { match r { - RegType::Temp(r) => - functor!("x", 1, [heap_integer!(Integer::from(r))]), - RegType::Perm(r) => - functor!("y", 1, [heap_integer!(Integer::from(r))]) + RegType::Temp(r) => functor!("x", 1, [heap_integer!(Integer::from(r))]), + RegType::Perm(r) => functor!("y", 1, [heap_integer!(Integer::from(r))]), } } impl Level { fn into_functor(self) -> MachineStub { match self { - Level::Root => - functor!("level", 1, [heap_atom!("root")]), - Level::Shallow => - functor!("level", 1, [heap_atom!("shallow")]), - Level::Deep => - functor!("level", 1, [heap_atom!("deep")]), + Level::Root => functor!("level", 1, [heap_atom!("root")]), + Level::Shallow => functor!("level", 1, [heap_atom!("shallow")]), + Level::Deep => functor!("level", 1, [heap_atom!("deep")]), } } } @@ -36,12 +31,11 @@ impl Level { impl ArithmeticTerm { fn into_functor(&self) -> MachineStub { match self { - &ArithmeticTerm::Reg(r) => - reg_type_into_functor(r), - &ArithmeticTerm::Interm(i) => - functor!("intermediate", 1, [heap_integer!(Integer::from(i))]), - &ArithmeticTerm::Number(ref n) => - vec![heap_con!(n.clone().to_constant())] + &ArithmeticTerm::Reg(r) => reg_type_into_functor(r), + &ArithmeticTerm::Interm(i) => { + functor!("intermediate", 1, [heap_integer!(Integer::from(i))]) + } + &ArithmeticTerm::Number(ref n) => vec![heap_con!(n.clone().to_constant())], } } } @@ -51,22 +45,25 @@ pub enum ChoiceInstruction { DefaultTrustMe, RetryMeElse(usize), TrustMe, - TryMeElse(usize) + TryMeElse(usize), } impl ChoiceInstruction { pub fn to_functor(&self) -> MachineStub { match self { - &ChoiceInstruction::TryMeElse(offset) => - functor!("try_me_else", 1, [heap_integer!(Integer::from(offset))]), - &ChoiceInstruction::RetryMeElse(offset) => - functor!("retry_me_else", 1, [heap_integer!(Integer::from(offset))]), - &ChoiceInstruction::TrustMe => - vec![heap_atom!("trust_me")], - &ChoiceInstruction::DefaultRetryMeElse(offset) => - functor!("default_retry_me_else", 1, [heap_integer!(Integer::from(offset))]), - &ChoiceInstruction::DefaultTrustMe => - vec![heap_atom!("default_trust_me")], + &ChoiceInstruction::TryMeElse(offset) => { + functor!("try_me_else", 1, [heap_integer!(Integer::from(offset))]) + } + &ChoiceInstruction::RetryMeElse(offset) => { + functor!("retry_me_else", 1, [heap_integer!(Integer::from(offset))]) + } + &ChoiceInstruction::TrustMe => vec![heap_atom!("trust_me")], + &ChoiceInstruction::DefaultRetryMeElse(offset) => functor!( + "default_retry_me_else", + 1, + [heap_integer!(Integer::from(offset))] + ), + &ChoiceInstruction::DefaultTrustMe => vec![heap_atom!("default_trust_me")], } } } @@ -75,7 +72,7 @@ pub enum CutInstruction { Cut(RegType), GetLevel(RegType), GetLevelAndUnify(RegType), - NeckCut + NeckCut, } impl CutInstruction { @@ -85,19 +82,18 @@ impl CutInstruction { let mut stub = functor!("cut", 1, [heap_str!(h + 2)]); stub.append(&mut reg_type_into_functor(r)); stub - }, + } &CutInstruction::GetLevel(r) => { let mut stub = functor!("get_level", 1, [heap_str!(h + 2)]); stub.append(&mut reg_type_into_functor(r)); stub - }, + } &CutInstruction::GetLevelAndUnify(r) => { let mut stub = functor!("get_level_and_unify", 1, [heap_str!(h + 2)]); stub.append(&mut reg_type_into_functor(r)); stub - }, - &CutInstruction::NeckCut => - vec![heap_atom!("neck_cut")] + } + &CutInstruction::NeckCut => vec![heap_atom!("neck_cut")], } } } @@ -105,7 +101,7 @@ impl CutInstruction { pub enum IndexedChoiceInstruction { Retry(usize), Trust(usize), - Try(usize) + Try(usize), } impl From for Line { @@ -119,18 +115,21 @@ impl IndexedChoiceInstruction { match self { &IndexedChoiceInstruction::Retry(offset) => offset, &IndexedChoiceInstruction::Trust(offset) => offset, - &IndexedChoiceInstruction::Try(offset) => offset + &IndexedChoiceInstruction::Try(offset) => offset, } } pub fn to_functor(&self) -> MachineStub { match self { - &IndexedChoiceInstruction::Try(offset) => - functor!("try", 1, [heap_integer!(Integer::from(offset))]), - &IndexedChoiceInstruction::Trust(offset) => - functor!("trust", 1, [heap_integer!(Integer::from(offset))]), - &IndexedChoiceInstruction::Retry(offset) => + &IndexedChoiceInstruction::Try(offset) => { + functor!("try", 1, [heap_integer!(Integer::from(offset))]) + } + &IndexedChoiceInstruction::Trust(offset) => { + functor!("trust", 1, [heap_integer!(Integer::from(offset))]) + } + &IndexedChoiceInstruction::Retry(offset) => { functor!("retry", 1, [heap_integer!(Integer::from(offset))]) + } } } } @@ -143,7 +142,7 @@ pub enum Line { Fact(FactInstruction), Indexing(IndexingInstruction), IndexedChoice(IndexedChoiceInstruction), - Query(QueryInstruction) + Query(QueryInstruction), } impl Line { @@ -152,7 +151,7 @@ impl Line { &Line::Cut(_) => true, &Line::Fact(_) => true, &Line::Query(_) => true, - _ => false + _ => false, } } @@ -165,7 +164,7 @@ impl Line { &Line::Fact(ref fact_instr) => fact_instr.to_functor(h), &Line::Indexing(ref indexing_instr) => indexing_instr.to_functor(), &Line::IndexedChoice(ref indexed_choice_instr) => indexed_choice_instr.to_functor(), - &Line::Query(ref query_instr) => query_instr.to_functor(h) + &Line::Query(ref query_instr) => query_instr.to_functor(h), } } } @@ -208,33 +207,46 @@ pub enum ArithmeticInstruction { Floor(ArithmeticTerm, usize), Neg(ArithmeticTerm, usize), Plus(ArithmeticTerm, usize), - BitwiseComplement(ArithmeticTerm, usize) + BitwiseComplement(ArithmeticTerm, usize), } -fn arith_instr_unary_functor(h: usize, name: &'static str, at: &ArithmeticTerm, t: usize) - -> MachineStub -{ +fn arith_instr_unary_functor( + h: usize, + name: &'static str, + at: &ArithmeticTerm, + t: usize, +) -> MachineStub { let at_stub = at.into_functor(); - let mut stub = functor!(name, 2, - [heap_cell!(h + 4), - heap_integer!(Integer::from(t))]); + let mut stub = functor!( + name, + 2, + [heap_cell!(h + 4), heap_integer!(Integer::from(t))] + ); stub.extend(at_stub.into_iter()); stub } -fn arith_instr_bin_functor(h: usize, name: &'static str, at_1: &ArithmeticTerm, - at_2: &ArithmeticTerm, t: usize) - -> MachineStub -{ +fn arith_instr_bin_functor( + h: usize, + name: &'static str, + at_1: &ArithmeticTerm, + at_2: &ArithmeticTerm, + t: usize, +) -> MachineStub { let at_1_stub = at_1.into_functor(); let at_2_stub = at_2.into_functor(); - let mut stub = functor!(name, 3, - [heap_cell!(h + 4), - heap_cell!(h + 4 + at_1_stub.len()), - heap_integer!(Integer::from(t))]); + let mut stub = functor!( + name, + 3, + [ + heap_cell!(h + 4), + heap_cell!(h + 4 + at_1_stub.len()), + heap_integer!(Integer::from(t)) + ] + ); stub.extend(at_1_stub.into_iter()); stub.extend(at_2_stub.into_iter()); @@ -245,80 +257,93 @@ fn arith_instr_bin_functor(h: usize, name: &'static str, at_1: &ArithmeticTerm, impl ArithmeticInstruction { pub fn to_functor(&self, h: usize) -> MachineStub { match self { - &ArithmeticInstruction::Add(ref at_1, ref at_2, t) => - arith_instr_bin_functor(h, "add", at_1, at_2, t), - &ArithmeticInstruction::Sub(ref at_1, ref at_2, t) => - arith_instr_bin_functor(h, "sub", at_1, at_2, t), - &ArithmeticInstruction::Mul(ref at_1, ref at_2, t) => - arith_instr_bin_functor(h, "mul", at_1, at_2, t), - &ArithmeticInstruction::IntPow(ref at_1, ref at_2, t) => - arith_instr_bin_functor(h, "int_pow", at_1, at_2, t), - &ArithmeticInstruction::Pow(ref at_1, ref at_2, t) => - arith_instr_bin_functor(h, "pow", at_1, at_2, t), - &ArithmeticInstruction::IDiv(ref at_1, ref at_2, t) => - arith_instr_bin_functor(h, "idiv", at_1, at_2, t), - &ArithmeticInstruction::Max(ref at_1, ref at_2, t) => - arith_instr_bin_functor(h, "max", at_1, at_2, t), - &ArithmeticInstruction::Min(ref at_1, ref at_2, t) => - arith_instr_bin_functor(h, "min", at_1, at_2, t), - &ArithmeticInstruction::IntFloorDiv(ref at_1, ref at_2, t) => - arith_instr_bin_functor(h, "int_floor_div", at_1, at_2, t), - &ArithmeticInstruction::RDiv(ref at_1, ref at_2, t) => - arith_instr_bin_functor(h, "rdiv", at_1, at_2, t), - &ArithmeticInstruction::Div(ref at_1, ref at_2, t) => - arith_instr_bin_functor(h, "div", at_1, at_2, t), - &ArithmeticInstruction::Shl(ref at_1, ref at_2, t) => - arith_instr_bin_functor(h, "shl", at_1, at_2, t), - &ArithmeticInstruction::Shr(ref at_1, ref at_2, t) => - arith_instr_bin_functor(h, "shr", at_1, at_2, t), - &ArithmeticInstruction::Xor(ref at_1, ref at_2, t) => - arith_instr_bin_functor(h, "xor", at_1, at_2, t), - &ArithmeticInstruction::And(ref at_1, ref at_2, t) => - arith_instr_bin_functor(h, "and", at_1, at_2, t), - &ArithmeticInstruction::Or(ref at_1, ref at_2, t) => - arith_instr_bin_functor(h, "or", at_1, at_2, t), - &ArithmeticInstruction::Mod(ref at_1, ref at_2, t) => - arith_instr_bin_functor(h, "mod", at_1, at_2, t), - &ArithmeticInstruction::Rem(ref at_1, ref at_2, t) => - arith_instr_bin_functor(h, "rem", at_1, at_2, t), - &ArithmeticInstruction::ATan2(ref at_1, ref at_2, t) => - arith_instr_bin_functor(h, "rem", at_1, at_2, t), - &ArithmeticInstruction::Cos(ref at, t) => - arith_instr_unary_functor(h, "cos", at, t), - &ArithmeticInstruction::Sin(ref at, t) => - arith_instr_unary_functor(h, "sin", at, t), - &ArithmeticInstruction::Tan(ref at, t) => - arith_instr_unary_functor(h, "tan", at, t), - &ArithmeticInstruction::Log(ref at, t) => - arith_instr_unary_functor(h, "log", at, t), - &ArithmeticInstruction::Exp(ref at, t) => - arith_instr_unary_functor(h, "exp", at, t), - &ArithmeticInstruction::ACos(ref at, t) => - arith_instr_unary_functor(h, "acos", at, t), - &ArithmeticInstruction::ASin(ref at, t) => - arith_instr_unary_functor(h, "asin", at, t), - &ArithmeticInstruction::ATan(ref at, t) => - arith_instr_unary_functor(h, "atan", at, t), - &ArithmeticInstruction::Sqrt(ref at, t) => - arith_instr_unary_functor(h, "sqrt", at, t), - &ArithmeticInstruction::Abs(ref at, t) => - arith_instr_unary_functor(h, "abs", at, t), - &ArithmeticInstruction::Float(ref at, t) => - arith_instr_unary_functor(h, "float", at, t), - &ArithmeticInstruction::Truncate(ref at, t) => - arith_instr_unary_functor(h, "truncate", at, t), - &ArithmeticInstruction::Round(ref at, t) => - arith_instr_unary_functor(h, "round", at, t), - &ArithmeticInstruction::Ceiling(ref at, t) => - arith_instr_unary_functor(h, "ceiling", at, t), - &ArithmeticInstruction::Floor(ref at, t) => - arith_instr_unary_functor(h, "floor", at, t), - &ArithmeticInstruction::Neg(ref at, t) => - arith_instr_unary_functor(h, "-", at, t), - &ArithmeticInstruction::Plus(ref at, t) => - arith_instr_unary_functor(h, "+", at, t), - &ArithmeticInstruction::BitwiseComplement(ref at, t) => - arith_instr_unary_functor(h, "\\", at, t), + &ArithmeticInstruction::Add(ref at_1, ref at_2, t) => { + arith_instr_bin_functor(h, "add", at_1, at_2, t) + } + &ArithmeticInstruction::Sub(ref at_1, ref at_2, t) => { + arith_instr_bin_functor(h, "sub", at_1, at_2, t) + } + &ArithmeticInstruction::Mul(ref at_1, ref at_2, t) => { + arith_instr_bin_functor(h, "mul", at_1, at_2, t) + } + &ArithmeticInstruction::IntPow(ref at_1, ref at_2, t) => { + arith_instr_bin_functor(h, "int_pow", at_1, at_2, t) + } + &ArithmeticInstruction::Pow(ref at_1, ref at_2, t) => { + arith_instr_bin_functor(h, "pow", at_1, at_2, t) + } + &ArithmeticInstruction::IDiv(ref at_1, ref at_2, t) => { + arith_instr_bin_functor(h, "idiv", at_1, at_2, t) + } + &ArithmeticInstruction::Max(ref at_1, ref at_2, t) => { + arith_instr_bin_functor(h, "max", at_1, at_2, t) + } + &ArithmeticInstruction::Min(ref at_1, ref at_2, t) => { + arith_instr_bin_functor(h, "min", at_1, at_2, t) + } + &ArithmeticInstruction::IntFloorDiv(ref at_1, ref at_2, t) => { + arith_instr_bin_functor(h, "int_floor_div", at_1, at_2, t) + } + &ArithmeticInstruction::RDiv(ref at_1, ref at_2, t) => { + arith_instr_bin_functor(h, "rdiv", at_1, at_2, t) + } + &ArithmeticInstruction::Div(ref at_1, ref at_2, t) => { + arith_instr_bin_functor(h, "div", at_1, at_2, t) + } + &ArithmeticInstruction::Shl(ref at_1, ref at_2, t) => { + arith_instr_bin_functor(h, "shl", at_1, at_2, t) + } + &ArithmeticInstruction::Shr(ref at_1, ref at_2, t) => { + arith_instr_bin_functor(h, "shr", at_1, at_2, t) + } + &ArithmeticInstruction::Xor(ref at_1, ref at_2, t) => { + arith_instr_bin_functor(h, "xor", at_1, at_2, t) + } + &ArithmeticInstruction::And(ref at_1, ref at_2, t) => { + arith_instr_bin_functor(h, "and", at_1, at_2, t) + } + &ArithmeticInstruction::Or(ref at_1, ref at_2, t) => { + arith_instr_bin_functor(h, "or", at_1, at_2, t) + } + &ArithmeticInstruction::Mod(ref at_1, ref at_2, t) => { + arith_instr_bin_functor(h, "mod", at_1, at_2, t) + } + &ArithmeticInstruction::Rem(ref at_1, ref at_2, t) => { + arith_instr_bin_functor(h, "rem", at_1, at_2, t) + } + &ArithmeticInstruction::ATan2(ref at_1, ref at_2, t) => { + arith_instr_bin_functor(h, "rem", at_1, at_2, t) + } + &ArithmeticInstruction::Cos(ref at, t) => arith_instr_unary_functor(h, "cos", at, t), + &ArithmeticInstruction::Sin(ref at, t) => arith_instr_unary_functor(h, "sin", at, t), + &ArithmeticInstruction::Tan(ref at, t) => arith_instr_unary_functor(h, "tan", at, t), + &ArithmeticInstruction::Log(ref at, t) => arith_instr_unary_functor(h, "log", at, t), + &ArithmeticInstruction::Exp(ref at, t) => arith_instr_unary_functor(h, "exp", at, t), + &ArithmeticInstruction::ACos(ref at, t) => arith_instr_unary_functor(h, "acos", at, t), + &ArithmeticInstruction::ASin(ref at, t) => arith_instr_unary_functor(h, "asin", at, t), + &ArithmeticInstruction::ATan(ref at, t) => arith_instr_unary_functor(h, "atan", at, t), + &ArithmeticInstruction::Sqrt(ref at, t) => arith_instr_unary_functor(h, "sqrt", at, t), + &ArithmeticInstruction::Abs(ref at, t) => arith_instr_unary_functor(h, "abs", at, t), + &ArithmeticInstruction::Float(ref at, t) => { + arith_instr_unary_functor(h, "float", at, t) + } + &ArithmeticInstruction::Truncate(ref at, t) => { + arith_instr_unary_functor(h, "truncate", at, t) + } + &ArithmeticInstruction::Round(ref at, t) => { + arith_instr_unary_functor(h, "round", at, t) + } + &ArithmeticInstruction::Ceiling(ref at, t) => { + arith_instr_unary_functor(h, "ceiling", at, t) + } + &ArithmeticInstruction::Floor(ref at, t) => { + arith_instr_unary_functor(h, "floor", at, t) + } + &ArithmeticInstruction::Neg(ref at, t) => arith_instr_unary_functor(h, "-", at, t), + &ArithmeticInstruction::Plus(ref at, t) => arith_instr_unary_functor(h, "+", at, t), + &ArithmeticInstruction::BitwiseComplement(ref at, t) => { + arith_instr_unary_functor(h, "\\", at, t) + } } } } @@ -329,34 +354,44 @@ pub enum ControlInstruction { CallClause(ClauseType, usize, usize, bool, bool), Deallocate, JmpBy(usize, usize, usize, bool), // arity, global_offset, perm_vars after threshold, last call. - Proceed + Proceed, } impl ControlInstruction { pub fn is_jump_instr(&self) -> bool { match self { - &ControlInstruction::CallClause(..) => true, + &ControlInstruction::CallClause(..) => true, &ControlInstruction::JmpBy(..) => true, - _ => false + _ => false, } } pub fn to_functor(&self) -> MachineStub { match self { - &ControlInstruction::Allocate(num_frames) => - functor!("allocate", 1, [heap_integer!(Integer::from(num_frames))]), - &ControlInstruction::CallClause(ref ct, arity, _, false, _) => - functor!("call", 2, [heap_con!(Constant::Atom(ct.name(), None)), - heap_integer!(Integer::from(arity))]), - &ControlInstruction::CallClause(ref ct, arity, _, true, _) => - functor!("execute", 2, [heap_con!(Constant::Atom(ct.name(), None)), - heap_integer!(Integer::from(arity))]), - &ControlInstruction::Deallocate => - vec![heap_atom!("deallocate")], - &ControlInstruction::JmpBy(_, offset, ..) => - functor!("jmp_by", 1, [heap_integer!(Integer::from(offset))]), - &ControlInstruction::Proceed => - vec![heap_atom!("proceed")] + &ControlInstruction::Allocate(num_frames) => { + functor!("allocate", 1, [heap_integer!(Integer::from(num_frames))]) + } + &ControlInstruction::CallClause(ref ct, arity, _, false, _) => functor!( + "call", + 2, + [ + heap_con!(Constant::Atom(ct.name(), None)), + heap_integer!(Integer::from(arity)) + ] + ), + &ControlInstruction::CallClause(ref ct, arity, _, true, _) => functor!( + "execute", + 2, + [ + heap_con!(Constant::Atom(ct.name(), None)), + heap_integer!(Integer::from(arity)) + ] + ), + &ControlInstruction::Deallocate => vec![heap_atom!("deallocate")], + &ControlInstruction::JmpBy(_, offset, ..) => { + functor!("jmp_by", 1, [heap_integer!(Integer::from(offset))]) + } + &ControlInstruction::Proceed => vec![heap_atom!("proceed")], } } } @@ -364,7 +399,7 @@ impl ControlInstruction { pub enum IndexingInstruction { SwitchOnTerm(usize, usize, usize, usize), SwitchOnConstant(usize, IndexMap), - SwitchOnStructure(usize, IndexMap<(ClauseName, usize), usize>) + SwitchOnStructure(usize, IndexMap<(ClauseName, usize), usize>), } impl From for Line { @@ -376,18 +411,26 @@ impl From for Line { impl IndexingInstruction { pub fn to_functor(&self) -> MachineStub { match self { - &IndexingInstruction::SwitchOnTerm(vars, constants, lists, structures) => - functor!("switch_on_term", 4, - [heap_integer!(Integer::from(vars)), - heap_integer!(Integer::from(constants)), - heap_integer!(Integer::from(lists)), - heap_integer!(Integer::from(structures))]), - &IndexingInstruction::SwitchOnConstant(constants, _) => - functor!("switch_on_constant", 1, - [heap_integer!(Integer::from(constants))]), - &IndexingInstruction::SwitchOnStructure(structures, _) => - functor!("switch_on_structure", 1, - [heap_integer!(Integer::from(structures))]) + &IndexingInstruction::SwitchOnTerm(vars, constants, lists, structures) => functor!( + "switch_on_term", + 4, + [ + heap_integer!(Integer::from(vars)), + heap_integer!(Integer::from(constants)), + heap_integer!(Integer::from(lists)), + heap_integer!(Integer::from(structures)) + ] + ), + &IndexingInstruction::SwitchOnConstant(constants, _) => functor!( + "switch_on_constant", + 1, + [heap_integer!(Integer::from(constants))] + ), + &IndexingInstruction::SwitchOnStructure(structures, _) => functor!( + "switch_on_structure", + 1, + [heap_integer!(Integer::from(structures))] + ), } } } @@ -403,79 +446,93 @@ pub enum FactInstruction { UnifyLocalValue(RegType), UnifyVariable(RegType), UnifyValue(RegType), - UnifyVoid(usize) + UnifyVoid(usize), } impl FactInstruction { pub fn to_functor(&self, h: usize) -> MachineStub { match self { &FactInstruction::GetConstant(lvl, ref constant, r) => { - let mut stub = functor!("get_constant", 3, - [heap_str!(h + 4), - heap_con!(constant.clone()), - heap_str!(h + 6)]); + let mut stub = functor!( + "get_constant", + 3, + [ + heap_str!(h + 4), + heap_con!(constant.clone()), + heap_str!(h + 6) + ] + ); stub.append(&mut lvl.into_functor()); stub.append(&mut reg_type_into_functor(r)); stub - }, + } &FactInstruction::GetList(lvl, r) => { - let mut stub = functor!("get_list", 2, - [heap_str!(h + 3), - heap_str!(h + 5)]); + let mut stub = functor!("get_list", 2, [heap_str!(h + 3), heap_str!(h + 5)]); stub.append(&mut lvl.into_functor()); stub.append(&mut reg_type_into_functor(r)); stub - }, + } &FactInstruction::GetStructure(ref ct, arity, r) => { - let mut stub = functor!("get_structure", 3, - [heap_con!(Constant::Atom(ct.name(), None)), - heap_integer!(Integer::from(arity)), - heap_str!(h + 4)]); + let mut stub = functor!( + "get_structure", + 3, + [ + heap_con!(Constant::Atom(ct.name(), None)), + heap_integer!(Integer::from(arity)), + heap_str!(h + 4) + ] + ); stub.append(&mut reg_type_into_functor(r)); stub - }, + } &FactInstruction::GetValue(r, arg) => { - let mut stub = functor!("get_value", 2, - [heap_str!(h + 3), - heap_integer!(Integer::from(arg))]); + let mut stub = functor!( + "get_value", + 2, + [heap_str!(h + 3), heap_integer!(Integer::from(arg))] + ); stub.append(&mut reg_type_into_functor(r)); stub - }, + } &FactInstruction::GetVariable(r, arg) => { - let mut stub = functor!("get_variable", 2, - [heap_str!(h + 3), - heap_integer!(Integer::from(arg))]); + let mut stub = functor!( + "get_variable", + 2, + [heap_str!(h + 3), heap_integer!(Integer::from(arg))] + ); stub.append(&mut reg_type_into_functor(r)); stub - }, - &FactInstruction::UnifyConstant(ref constant) => - functor!("unify_constant", 1, [heap_con!(constant.clone())]), + } + &FactInstruction::UnifyConstant(ref constant) => { + functor!("unify_constant", 1, [heap_con!(constant.clone())]) + } &FactInstruction::UnifyLocalValue(r) => { let mut stub = functor!("unify_local_value", 1, [heap_str!(h + 2)]); stub.append(&mut reg_type_into_functor(r)); stub - }, + } &FactInstruction::UnifyVariable(r) => { let mut stub = functor!("unify_variable", 1, [heap_str!(h + 2)]); stub.append(&mut reg_type_into_functor(r)); stub - }, + } &FactInstruction::UnifyValue(r) => { let mut stub = functor!("unify_value", 1, [heap_str!(h + 2)]); stub.append(&mut reg_type_into_functor(r)); stub - }, - &FactInstruction::UnifyVoid(vars) => + } + &FactInstruction::UnifyVoid(vars) => { functor!("unify_void", 1, [heap_integer!(Integer::from(vars))]) + } } } } @@ -493,92 +550,112 @@ pub enum QueryInstruction { SetLocalValue(RegType), SetVariable(RegType), SetValue(RegType), - SetVoid(usize) + SetVoid(usize), } impl QueryInstruction { pub fn to_functor(&self, h: usize) -> MachineStub { match self { - &QueryInstruction::PutUnsafeValue(norm, arg) => - functor!("put_unsafe_value", 2, - [heap_integer!(Integer::from(norm)), - heap_integer!(Integer::from(arg))]), + &QueryInstruction::PutUnsafeValue(norm, arg) => functor!( + "put_unsafe_value", + 2, + [ + heap_integer!(Integer::from(norm)), + heap_integer!(Integer::from(arg)) + ] + ), &QueryInstruction::PutConstant(lvl, ref constant, r) => { - let mut stub = functor!("put_constant", 3, - [heap_str!(h + 4), - heap_con!(constant.clone()), - heap_str!(h + 6)]); + let mut stub = functor!( + "put_constant", + 3, + [ + heap_str!(h + 4), + heap_con!(constant.clone()), + heap_str!(h + 6) + ] + ); stub.append(&mut lvl.into_functor()); stub.append(&mut reg_type_into_functor(r)); stub - }, + } &QueryInstruction::PutList(lvl, r) => { - let mut stub = functor!("put_list", 2, - [heap_str!(h + 3), - heap_str!(h + 5)]); + let mut stub = functor!("put_list", 2, [heap_str!(h + 3), heap_str!(h + 5)]); stub.append(&mut lvl.into_functor()); stub.append(&mut reg_type_into_functor(r)); stub - }, + } &QueryInstruction::PutStructure(ref ct, arity, r) => { - let mut stub = functor!("put_structure", 3, - [heap_con!(Constant::Atom(ct.name(), None)), - heap_integer!(Integer::from(arity)), - heap_str!(h + 4)]); + let mut stub = functor!( + "put_structure", + 3, + [ + heap_con!(Constant::Atom(ct.name(), None)), + heap_integer!(Integer::from(arity)), + heap_str!(h + 4) + ] + ); stub.append(&mut reg_type_into_functor(r)); stub - }, + } &QueryInstruction::PutValue(r, arg) => { - let mut stub = functor!("put_value", 2, - [heap_str!(h + 3), - heap_integer!(Integer::from(arg))]); + let mut stub = functor!( + "put_value", + 2, + [heap_str!(h + 3), heap_integer!(Integer::from(arg))] + ); stub.append(&mut reg_type_into_functor(r)); stub - }, + } &QueryInstruction::GetVariable(r, arg) => { - let mut stub = functor!("get_variable", 2, - [heap_str!(h + 3), - heap_integer!(Integer::from(arg))]); + let mut stub = functor!( + "get_variable", + 2, + [heap_str!(h + 3), heap_integer!(Integer::from(arg))] + ); stub.append(&mut reg_type_into_functor(r)); stub - }, + } &QueryInstruction::PutVariable(r, arg) => { - let mut stub = functor!("put_variable", 2, - [heap_str!(h + 3), - heap_integer!(Integer::from(arg))]); + let mut stub = functor!( + "put_variable", + 2, + [heap_str!(h + 3), heap_integer!(Integer::from(arg))] + ); stub.append(&mut reg_type_into_functor(r)); stub - }, - &QueryInstruction::SetConstant(ref constant) => - functor!("set_constant", 1, [heap_con!(constant.clone())]), + } + &QueryInstruction::SetConstant(ref constant) => { + functor!("set_constant", 1, [heap_con!(constant.clone())]) + } &QueryInstruction::SetLocalValue(r) => { let mut stub = functor!("set_local_value", 1, [heap_str!(h + 2)]); stub.append(&mut reg_type_into_functor(r)); stub - }, + } &QueryInstruction::SetVariable(r) => { let mut stub = functor!("set_variable", 1, [heap_str!(h + 2)]); stub.append(&mut reg_type_into_functor(r)); stub - }, + } &QueryInstruction::SetValue(r) => { let mut stub = functor!("set_value", 1, [heap_str!(h + 2)]); stub.append(&mut reg_type_into_functor(r)); stub - }, - &QueryInstruction::SetVoid(vars) => + } + &QueryInstruction::SetVoid(vars) => { functor!("set_void", 1, [heap_integer!(Integer::from(vars))]) + } } } } diff --git a/src/prolog/iterators.rs b/src/prolog/iterators.rs index 4c9c863a..96724665 100644 --- a/src/prolog/iterators.rs +++ b/src/prolog/iterators.rs @@ -16,17 +16,17 @@ pub enum TermRef<'a> { Cons(Level, &'a Cell, &'a Term, &'a Term), Constant(Level, &'a Cell, &'a Constant), Clause(Level, &'a Cell, ClauseType, &'a Vec>), - Var(Level, &'a Cell, Rc) + Var(Level, &'a Cell, Rc), } impl<'a> TermRef<'a> { pub fn level(self) -> Level { match self { TermRef::AnonVar(lvl) - | TermRef::Cons(lvl, ..) - | TermRef::Constant(lvl, ..) - | TermRef::Var(lvl, ..) - | TermRef::Clause(lvl, ..) => lvl + | TermRef::Cons(lvl, ..) + | TermRef::Constant(lvl, ..) + | TermRef::Var(lvl, ..) + | TermRef::Clause(lvl, ..) => lvl, } } } @@ -34,17 +34,22 @@ impl<'a> TermRef<'a> { pub enum TermIterState<'a> { AnonVar(Level), Constant(Level, &'a Cell, &'a Constant), - Clause(Level, usize, &'a Cell, ClauseType, &'a Vec>), + Clause( + Level, + usize, + &'a Cell, + ClauseType, + &'a Vec>, + ), InitialCons(Level, &'a Cell, &'a Term, &'a Term), FinalCons(Level, &'a Cell, &'a Term, &'a Term), - Var(Level, &'a Cell, Rc) + Var(Level, &'a Cell, Rc), } impl<'a> TermIterState<'a> { pub fn subterm_to_state(lvl: Level, term: &'a Term) -> TermIterState<'a> { match term { - &Term::AnonVar => - TermIterState::AnonVar(lvl), + &Term::AnonVar => TermIterState::AnonVar(lvl), &Term::Clause(ref cell, ref name, ref subterms, ref spec) => { let ct = if let Some(spec) = spec { ClauseType::Op(name.clone(), spec.clone(), CodeIndex::default()) @@ -53,13 +58,12 @@ impl<'a> TermIterState<'a> { }; TermIterState::Clause(lvl, 0, cell, ct, subterms) - }, - &Term::Cons(ref cell, ref head, ref tail) => - TermIterState::InitialCons(lvl, cell, head.as_ref(), tail.as_ref()), - &Term::Constant(ref cell, ref constant) => - TermIterState::Constant(lvl, cell, constant), - &Term::Var(ref cell, ref var) => - TermIterState::Var(lvl, cell, var.clone()) + } + &Term::Cons(ref cell, ref head, ref tail) => { + TermIterState::InitialCons(lvl, cell, head.as_ref(), tail.as_ref()) + } + &Term::Constant(ref cell, ref constant) => TermIterState::Constant(lvl, cell, constant), + &Term::Var(ref cell, ref var) => TermIterState::Var(lvl, cell, var.clone()), } } } @@ -70,11 +74,14 @@ pub struct QueryIterator<'a> { impl<'a> QueryIterator<'a> { fn push_subterm(&mut self, lvl: Level, term: &'a Term) { - self.state_stack.push(TermIterState::subterm_to_state(lvl, term)); + self.state_stack + .push(TermIterState::subterm_to_state(lvl, term)); } fn from_rule_head_clause(terms: &'a Vec>) -> Self { - let state_stack = terms.iter().rev() + let state_stack = terms + .iter() + .rev() .map(|bt| TermIterState::subterm_to_state(Level::Shallow, bt.as_ref())) .collect(); @@ -83,50 +90,74 @@ impl<'a> QueryIterator<'a> { fn from_term(term: &'a Term) -> Self { let state = match term { - &Term::AnonVar => - return QueryIterator { state_stack: vec![] }, - &Term::Clause(ref r, ref name, ref terms, ref fixity) => - TermIterState::Clause(Level::Root, 0, r, - ClauseType::from(name.clone(), terms.len(), fixity.clone()), - terms), - &Term::Cons(..) => - return QueryIterator { state_stack: vec![] }, - &Term::Constant(_, _) => - return QueryIterator { state_stack: vec![] }, - &Term::Var(ref cell, ref var) => - TermIterState::Var(Level::Root, cell, (*var).clone()) + &Term::AnonVar => { + return QueryIterator { + state_stack: vec![], + } + } + &Term::Clause(ref r, ref name, ref terms, ref fixity) => TermIterState::Clause( + Level::Root, + 0, + r, + ClauseType::from(name.clone(), terms.len(), fixity.clone()), + terms, + ), + &Term::Cons(..) => { + return QueryIterator { + state_stack: vec![], + } + } + &Term::Constant(_, _) => { + return QueryIterator { + state_stack: vec![], + } + } + &Term::Var(ref cell, ref var) => TermIterState::Var(Level::Root, cell, (*var).clone()), }; - QueryIterator { state_stack: vec![state] } + QueryIterator { + state_stack: vec![state], + } } fn new(term: &'a QueryTerm) -> Self { - match term { + match term { &QueryTerm::Clause(ref cell, ClauseType::CallN, ref terms, _) => { let state = TermIterState::Clause(Level::Root, 1, cell, ClauseType::CallN, terms); - QueryIterator { state_stack: vec![state] } - }, + QueryIterator { + state_stack: vec![state], + } + } &QueryTerm::Clause(ref cell, ref ct, ref terms, _) => { let state = TermIterState::Clause(Level::Root, 0, cell, ct.clone(), terms); - QueryIterator { state_stack: vec![state] } - }, + QueryIterator { + state_stack: vec![state], + } + } &QueryTerm::UnblockedCut(ref cell) => { let state = TermIterState::Var(Level::Root, cell, rc_atom!("!")); - QueryIterator { state_stack: vec![state] } - }, + QueryIterator { + state_stack: vec![state], + } + } &QueryTerm::GetLevelAndUnify(ref cell, ref var) => { let state = TermIterState::Var(Level::Root, cell, var.clone()); - QueryIterator { state_stack: vec![state] } - }, + QueryIterator { + state_stack: vec![state], + } + } &QueryTerm::Jump(ref vars) => { - let state_stack = vars.iter().rev().map(|t| { - TermIterState::subterm_to_state(Level::Shallow, t) - }).collect(); + let state_stack = vars + .iter() + .rev() + .map(|t| TermIterState::subterm_to_state(Level::Shallow, t)) + .collect(); QueryIterator { state_stack } - }, - &QueryTerm::BlockedCut => - QueryIterator { state_stack: vec![] }, + } + &QueryTerm::BlockedCut => QueryIterator { + state_stack: vec![], + }, } } } @@ -137,39 +168,46 @@ impl<'a> Iterator for QueryIterator<'a> { fn next(&mut self) -> Option { while let Some(iter_state) = self.state_stack.pop() { match iter_state { - TermIterState::AnonVar(lvl) => - return Some(TermRef::AnonVar(lvl)), + TermIterState::AnonVar(lvl) => return Some(TermRef::AnonVar(lvl)), TermIterState::Clause(lvl, child_num, cell, ct, child_terms) => { if child_num == child_terms.len() { match ct { - ClauseType::CallN => - self.push_subterm(Level::Shallow, child_terms[0].as_ref()), - ClauseType::Named(..) | ClauseType::Op(..) => + ClauseType::CallN => { + self.push_subterm(Level::Shallow, child_terms[0].as_ref()) + } + ClauseType::Named(..) | ClauseType::Op(..) => { return match lvl { Level::Root => None, - lvl => Some(TermRef::Clause(lvl, cell, ct, child_terms)) - }, - _ => - return None + lvl => Some(TermRef::Clause(lvl, cell, ct, child_terms)), + } + } + _ => return None, }; } else { - self.state_stack.push(TermIterState::Clause(lvl, child_num + 1, - cell, ct, child_terms)); + self.state_stack.push(TermIterState::Clause( + lvl, + child_num + 1, + cell, + ct, + child_terms, + )); self.push_subterm(lvl.child_level(), child_terms[child_num].as_ref()); } - }, + } TermIterState::InitialCons(lvl, cell, head, tail) => { - self.state_stack.push(TermIterState::FinalCons(lvl, cell, head, tail)); + self.state_stack + .push(TermIterState::FinalCons(lvl, cell, head, tail)); self.push_subterm(lvl.child_level(), tail); self.push_subterm(lvl.child_level(), head); - }, - TermIterState::FinalCons(lvl, cell, head, tail) => - return Some(TermRef::Cons(lvl, cell, head, tail)), - TermIterState::Constant(lvl, cell, constant) => - return Some(TermRef::Constant(lvl, cell, constant)), - TermIterState::Var(lvl, cell, var) => - return Some(TermRef::Var(lvl, cell, var)) + } + TermIterState::FinalCons(lvl, cell, head, tail) => { + return Some(TermRef::Cons(lvl, cell, head, tail)) + } + TermIterState::Constant(lvl, cell, constant) => { + return Some(TermRef::Constant(lvl, cell, constant)) + } + TermIterState::Var(lvl, cell, var) => return Some(TermRef::Var(lvl, cell, var)), }; } @@ -179,39 +217,52 @@ impl<'a> Iterator for QueryIterator<'a> { pub struct FactIterator<'a> { state_queue: VecDeque>, - iterable_root: bool + iterable_root: bool, } impl<'a> FactIterator<'a> { fn push_subterm(&mut self, lvl: Level, term: &'a Term) { - self.state_queue.push_back(TermIterState::subterm_to_state(lvl, term)); + self.state_queue + .push_back(TermIterState::subterm_to_state(lvl, term)); } pub fn from_rule_head_clause(terms: &'a Vec>) -> Self { - let state_queue = terms.iter() + let state_queue = terms + .iter() .map(|bt| TermIterState::subterm_to_state(Level::Shallow, bt.as_ref())) .collect(); - FactIterator { state_queue, iterable_root: false } + FactIterator { + state_queue, + iterable_root: false, + } } fn new(term: &'a Term, iterable_root: bool) -> Self { let states = match term { - &Term::AnonVar => - vec![TermIterState::AnonVar(Level::Root)], + &Term::AnonVar => vec![TermIterState::AnonVar(Level::Root)], &Term::Clause(ref cell, ref name, ref terms, ref fixity) => { let ct = ClauseType::from(name.clone(), terms.len(), fixity.clone()); vec![TermIterState::Clause(Level::Root, 0, cell, ct, terms)] - }, - &Term::Cons(ref cell, ref head, ref tail) => - vec![TermIterState::InitialCons(Level::Root, cell, head.as_ref(), tail.as_ref())], - &Term::Constant(ref cell, ref constant) => - vec![TermIterState::Constant(Level::Root, cell, constant)], - &Term::Var(ref cell, ref var) => + } + &Term::Cons(ref cell, ref head, ref tail) => vec![TermIterState::InitialCons( + Level::Root, + cell, + head.as_ref(), + tail.as_ref(), + )], + &Term::Constant(ref cell, ref constant) => { + vec![TermIterState::Constant(Level::Root, cell, constant)] + } + &Term::Var(ref cell, ref var) => { vec![TermIterState::Var(Level::Root, cell, var.clone())] + } }; - FactIterator { state_queue: VecDeque::from(states), iterable_root } + FactIterator { + state_queue: VecDeque::from(states), + iterable_root, + } } } @@ -221,8 +272,7 @@ impl<'a> Iterator for FactIterator<'a> { fn next(&mut self) -> Option { while let Some(state) = self.state_queue.pop_front() { match state { - TermIterState::AnonVar(lvl) => - return Some(TermRef::AnonVar(lvl)), + TermIterState::AnonVar(lvl) => return Some(TermRef::AnonVar(lvl)), TermIterState::Clause(lvl, _, cell, ct, child_terms) => { for child_term in child_terms { self.push_subterm(lvl.child_level(), child_term); @@ -230,19 +280,19 @@ impl<'a> Iterator for FactIterator<'a> { match lvl { Level::Root if !self.iterable_root => continue, - _ => return Some(TermRef::Clause(lvl, cell, ct, child_terms)) + _ => return Some(TermRef::Clause(lvl, cell, ct, child_terms)), }; - }, + } TermIterState::InitialCons(lvl, cell, head, tail) => { self.push_subterm(Level::Deep, head); self.push_subterm(Level::Deep, tail); return Some(TermRef::Cons(lvl, cell, head, tail)); - }, - TermIterState::Constant(lvl, cell, constant) => - return Some(TermRef::Constant(lvl, cell, constant)), - TermIterState::Var(lvl, cell, var) => - return Some(TermRef::Var(lvl, cell, var)), + } + TermIterState::Constant(lvl, cell, constant) => { + return Some(TermRef::Constant(lvl, cell, constant)) + } + TermIterState::Var(lvl, cell, var) => return Some(TermRef::Var(lvl, cell, var)), _ => {} } } @@ -261,7 +311,7 @@ pub fn breadth_first_iter(term: &Term, iterable_root: bool) -> FactIterator { pub enum ChunkedTerm<'a> { HeadClause(ClauseName, &'a Vec>), - BodyTerm(&'a QueryTerm) + BodyTerm(&'a QueryTerm), } pub fn query_term_post_order_iter<'a>(query_term: &'a QueryTerm) -> QueryIterator<'a> { @@ -271,15 +321,13 @@ pub fn query_term_post_order_iter<'a>(query_term: &'a QueryTerm) -> QueryIterato impl<'a> ChunkedTerm<'a> { pub fn post_order_iter(&self) -> QueryIterator<'a> { match self { - &ChunkedTerm::BodyTerm(ref qt) => - QueryIterator::new(qt), - &ChunkedTerm::HeadClause(_, terms) => - QueryIterator::from_rule_head_clause(terms) + &ChunkedTerm::BodyTerm(ref qt) => QueryIterator::new(qt), + &ChunkedTerm::HeadClause(_, terms) => QueryIterator::from_rule_head_clause(terms), } } } -fn contains_cut_var<'a, Iter: Iterator>(terms: Iter) -> bool { +fn contains_cut_var<'a, Iter: Iterator>(terms: Iter) -> bool { for term in terms { if let &Term::Var(_, ref var) = term { if var.as_str() == "!" { @@ -291,28 +339,26 @@ fn contains_cut_var<'a, Iter: Iterator>(terms: Iter) -> bool { false } -pub struct ChunkedIterator<'a> -{ +pub struct ChunkedIterator<'a> { pub chunk_num: usize, - iter: Box> + 'a>, + iter: Box> + 'a>, deep_cut_encountered: bool, - cut_var_in_head: bool + cut_var_in_head: bool, } -type ChunkedIteratorItem<'a> = (usize, usize, Vec>); +type ChunkedIteratorItem<'a> = (usize, usize, Vec>); type RuleBodyIteratorItem<'a> = (usize, usize, Vec<&'a QueryTerm>); -impl<'a> ChunkedIterator<'a> -{ - pub fn rule_body_iter(self) -> Box> + 'a> - { +impl<'a> ChunkedIterator<'a> { + pub fn rule_body_iter(self) -> Box> + 'a> { Box::new(self.filter_map(|(cn, lt_arity, terms)| { - let filtered_terms: Vec<_> = terms.into_iter().filter_map(|ct| { - match ct { - ChunkedTerm::BodyTerm(qt) => Some(qt), - _ => None - } - }).collect(); + let filtered_terms: Vec<_> = terms + .into_iter() + .filter_map(|ct| match ct { + ChunkedTerm::BodyTerm(qt) => Some(qt), + _ => None, + }) + .collect(); if filtered_terms.is_empty() { None @@ -322,18 +368,16 @@ impl<'a> ChunkedIterator<'a> })) } - pub fn from_term_sequence(terms: &'a [QueryTerm]) -> Self - { + pub fn from_term_sequence(terms: &'a [QueryTerm]) -> Self { ChunkedIterator { chunk_num: 0, iter: Box::new(terms.iter().map(|t| ChunkedTerm::BodyTerm(t))), deep_cut_encountered: false, - cut_var_in_head: false + cut_var_in_head: false, } } - pub fn from_rule_body(p1: &'a QueryTerm, clauses: &'a Vec) -> Self - { + pub fn from_rule_body(p1: &'a QueryTerm, clauses: &'a Vec) -> Self { let inner_iter = Box::new(once(ChunkedTerm::BodyTerm(p1))); let iter = inner_iter.chain(clauses.iter().map(|t| ChunkedTerm::BodyTerm(t))); @@ -341,13 +385,15 @@ impl<'a> ChunkedIterator<'a> chunk_num: 0, iter: Box::new(iter), deep_cut_encountered: false, - cut_var_in_head: false + cut_var_in_head: false, } } - pub fn from_rule(rule: &'a Rule) -> Self - { - let &Rule { head: (ref name, ref args, ref p1), ref clauses } = rule; + pub fn from_rule(rule: &'a Rule) -> Self { + let &Rule { + head: (ref name, ref args, ref p1), + ref clauses, + } = rule; let iter = once(ChunkedTerm::HeadClause(name.clone(), args)); let inner_iter = Box::new(once(ChunkedTerm::BodyTerm(p1))); @@ -357,7 +403,7 @@ impl<'a> ChunkedIterator<'a> chunk_num: 0, iter: Box::new(iter), deep_cut_encountered: false, - cut_var_in_head: false + cut_var_in_head: false, } } @@ -365,10 +411,9 @@ impl<'a> ChunkedIterator<'a> self.deep_cut_encountered } - fn take_chunk(&mut self, term: ChunkedTerm<'a>) -> (usize, usize, Vec>) - { - let mut arity = 0; - let mut item = Some(term); + fn take_chunk(&mut self, term: ChunkedTerm<'a>) -> (usize, usize, Vec>) { + let mut arity = 0; + let mut item = Some(term); let mut result = Vec::new(); while let Some(term) = item { @@ -379,7 +424,7 @@ impl<'a> ChunkedIterator<'a> } result.push(term); - }, + } ChunkedTerm::BodyTerm(&QueryTerm::Jump(ref vars)) => { result.push(term); arity = vars.len(); @@ -389,30 +434,35 @@ impl<'a> ChunkedIterator<'a> } break; - }, + } ChunkedTerm::BodyTerm(&QueryTerm::BlockedCut) => { result.push(term); if self.chunk_num > 0 { self.deep_cut_encountered = true; } - }, + } ChunkedTerm::BodyTerm(&QueryTerm::GetLevelAndUnify(..)) => { self.deep_cut_encountered = true; - + result.push(term); arity = 1; break; - }, - ChunkedTerm::BodyTerm(&QueryTerm::UnblockedCut(..)) => - result.push(term), - ChunkedTerm::BodyTerm(&QueryTerm::Clause(_, ClauseType::Inlined(_), ..)) => - result.push(term), - ChunkedTerm::BodyTerm(&QueryTerm::Clause(_, ClauseType::CallN, ref subterms, _)) => { + } + ChunkedTerm::BodyTerm(&QueryTerm::UnblockedCut(..)) => result.push(term), + ChunkedTerm::BodyTerm(&QueryTerm::Clause(_, ClauseType::Inlined(_), ..)) => { + result.push(term) + } + ChunkedTerm::BodyTerm(&QueryTerm::Clause( + _, + ClauseType::CallN, + ref subterms, + _, + )) => { result.push(term); arity = subterms.len() + 1; break; - }, + } ChunkedTerm::BodyTerm(qt) => { result.push(term); arity = qt.arity(); @@ -430,8 +480,7 @@ impl<'a> ChunkedIterator<'a> } } -impl<'a> Iterator for ChunkedIterator<'a> -{ +impl<'a> Iterator for ChunkedIterator<'a> { // the chunk number, last term arity, and vector of references. type Item = ChunkedIteratorItem<'a>; diff --git a/src/prolog/machine/and_stack.rs b/src/prolog/machine/and_stack.rs index 40318a12..e32d6b33 100644 --- a/src/prolog/machine/and_stack.rs +++ b/src/prolog/machine/and_stack.rs @@ -10,7 +10,7 @@ pub struct Frame { pub e: usize, pub cp: LocalCodePtr, pub interrupt_cp: LocalCodePtr, - perms: Vec + perms: Vec, } impl Frame { @@ -20,7 +20,7 @@ impl Frame { e: e, cp: cp, interrupt_cp: LocalCodePtr::default(), - perms: (1 .. n+1).map(|i| Addr::StackCell(fr, i)).collect() + perms: (1..n + 1).map(|i| Addr::StackCell(fr, i)).collect(), } } @@ -41,7 +41,7 @@ impl AndStack { pub(crate) fn take(&mut self) -> Self { AndStack(mem::replace(&mut self.0, vec![])) } - + pub fn push(&mut self, global_index: usize, e: usize, cp: LocalCodePtr, n: usize) { let len = self.0.len(); self.0.push(Frame::new(global_index, len, e, cp, n)); @@ -61,7 +61,7 @@ impl AndStack { if len < n { self[fr].perms.reserve(n - len); - for i in len .. n { + for i in len..n { self[fr].perms.push(Addr::StackCell(fr, i)); } } diff --git a/src/prolog/machine/attributed_variables.rs b/src/prolog/machine/attributed_variables.rs index b0bf2bba..118bb082 100644 --- a/src/prolog/machine/attributed_variables.rs +++ b/src/prolog/machine/attributed_variables.rs @@ -4,7 +4,7 @@ use indexmap::IndexSet; use std::vec::IntoIter; -pub static VERIFY_ATTRS: &str = include_str!("attributed_variables.pl"); +pub static VERIFY_ATTRS: &str = include_str!("attributed_variables.pl"); pub static PROJECT_ATTRS: &str = include_str!("project_attributes.pl"); pub(super) type Bindings = Vec<(usize, Addr)>; @@ -26,7 +26,7 @@ impl AttrVarInitializer { bindings: vec![], cp: LocalCodePtr::default(), verify_attrs_loc, - project_attrs_loc + project_attrs_loc, } } @@ -38,8 +38,7 @@ impl AttrVarInitializer { } impl MachineState { - pub(super) fn push_attr_var_binding(&mut self, h: usize, addr: Addr) - { + pub(super) fn push_attr_var_binding(&mut self, h: usize, addr: Addr) { if self.attr_var_init.bindings.is_empty() { self.attr_var_init.cp = self.p.local(); self.p = CodePtr::VerifyAttrInterrupt(self.attr_var_init.verify_attrs_loc); @@ -49,17 +48,24 @@ impl MachineState { } fn populate_var_and_value_lists(&mut self) -> (Addr, Addr) { - let iter = self.attr_var_init.bindings.iter().map(|(ref h, _)| Addr::AttrVar(*h)); + let iter = self + .attr_var_init + .bindings + .iter() + .map(|(ref h, _)| Addr::AttrVar(*h)); let var_list_addr = Addr::HeapCell(self.heap.to_list(iter)); - let iter = self.attr_var_init.bindings.iter().map(|(_, ref addr)| addr.clone()); + let iter = self + .attr_var_init + .bindings + .iter() + .map(|(_, ref addr)| addr.clone()); let value_list_addr = Addr::HeapCell(self.heap.to_list(iter)); (var_list_addr, value_list_addr) } - fn verify_attributes(&mut self) - { + fn verify_attributes(&mut self) { for (h, _) in &self.attr_var_init.bindings { self.heap[*h] = HeapCellValue::Addr(Addr::AttrVar(*h)); } @@ -70,15 +76,14 @@ impl MachineState { self[temp_v!(2)] = value_list_addr; } - pub(super) - fn gather_attr_vars_created_since(&self, b: usize) -> IntoIter - { - let mut attr_vars: Vec<_> = self.attr_var_init.attr_var_queue[b ..] - .iter().filter_map(|h| - match self.store(self.deref(Addr::HeapCell(*h))) { - Addr::AttrVar(h) => Some(Addr::AttrVar(h)), - _ => None - }).collect(); + pub(super) fn gather_attr_vars_created_since(&self, b: usize) -> IntoIter { + let mut attr_vars: Vec<_> = self.attr_var_init.attr_var_queue[b..] + .iter() + .filter_map(|h| match self.store(self.deref(Addr::HeapCell(*h))) { + Addr::AttrVar(h) => Some(Addr::AttrVar(h)), + _ => None, + }) + .collect(); attr_vars.sort_unstable_by(|a1, a2| self.compare_term_test(a1, a2)); @@ -86,8 +91,7 @@ impl MachineState { attr_vars.into_iter() } - fn populate_project_attr_lists(&mut self) -> (Addr, Addr) - { + fn populate_project_attr_lists(&mut self) -> (Addr, Addr) { let mut query_vars = IndexSet::new(); let attr_vars = self.gather_attr_vars_created_since(0); @@ -98,23 +102,22 @@ impl MachineState { match value { HeapCellValue::Addr(Addr::HeapCell(h)) => { query_vars.insert(Addr::HeapCell(h)); - }, + } HeapCellValue::Addr(Addr::StackCell(fr, sc)) => { query_vars.insert(Addr::StackCell(fr, sc)); - }, + } _ => {} }; } } let query_var_list = Addr::HeapCell(self.heap.to_list(query_vars.into_iter())); - let attr_var_list = Addr::HeapCell(self.heap.to_list(attr_vars)); + let attr_var_list = Addr::HeapCell(self.heap.to_list(attr_vars)); (query_var_list, attr_var_list) } - pub(super) - fn verify_attr_interrupt(&mut self, p: usize) { + pub(super) fn verify_attr_interrupt(&mut self, p: usize) { let rs = MAX_ARITY; // store temp vars in perm vars slots along with self.b0 and @@ -127,7 +130,7 @@ impl MachineState { let e = self.e; self.and_stack[e].interrupt_cp = self.attr_var_init.cp; - for i in 1 .. rs + 1 { + for i in 1..rs + 1 { self.and_stack[e][i] = self[RegType::Temp(i)].clone(); } @@ -141,8 +144,7 @@ impl MachineState { self.p = CodePtr::Local(LocalCodePtr::DirEntry(p)); } - fn print_attribute_goals_string(&mut self, op_dir: &OpDir) -> String - { + fn print_attribute_goals_string(&mut self, op_dir: &OpDir) -> String { let mut attr_goals = mem::replace(&mut self.attr_var_init.attribute_goals, vec![]); if attr_goals.is_empty() { @@ -174,9 +176,7 @@ impl MachineState { } impl Machine { - pub - fn attribute_goals(&mut self) -> String - { + pub fn attribute_goals(&mut self) -> String { let p = self.machine_st.attr_var_init.project_attrs_loc; let (query_vars, attr_vars) = self.machine_st.populate_project_attr_lists(); @@ -186,9 +186,14 @@ impl Machine { self.machine_st[temp_v!(2)] = attr_vars; self.machine_st.p = CodePtr::Local(LocalCodePtr::DirEntry(p)); - self.machine_st.query_stepper(&mut self.indices, &mut self.policies, &mut self.code_repo, - &mut readline::input_stream()); - - self.machine_st.print_attribute_goals_string(&self.indices.op_dir) + self.machine_st.query_stepper( + &mut self.indices, + &mut self.policies, + &mut self.code_repo, + &mut readline::input_stream(), + ); + + self.machine_st + .print_attribute_goals_string(&self.indices.op_dir) } } diff --git a/src/prolog/machine/code_repo.rs b/src/prolog/machine/code_repo.rs index dce28eaa..36bf9c41 100644 --- a/src/prolog/machine/code_repo.rs +++ b/src/prolog/machine/code_repo.rs @@ -17,7 +17,7 @@ pub struct CodeRepo { pub(super) term_expanders: Code, pub(super) code: Code, pub(super) in_situ_code: Code, - pub(super) term_dir: TermDir + pub(super) term_dir: TermDir, } impl CodeRepo { @@ -29,36 +29,51 @@ impl CodeRepo { term_expanders: Code::new(), code: Code::new(), in_situ_code: Code::new(), - term_dir: TermDir::new() + term_dir: TermDir::new(), } } - + #[inline] pub fn term_dir_entry_len(&self, key: PredicateKey) -> (usize, usize) { - self.term_dir.get(&key) + self.term_dir + .get(&key) .map(|entry| ((entry.0).0.len(), entry.1.len())) - .unwrap_or((0,0)) + .unwrap_or((0, 0)) } #[inline] - pub fn truncate_terms(&mut self, key: PredicateKey, len: usize, queue_len: usize) - -> (Predicate, VecDeque) - { - self.term_dir.get_mut(&key) - .map(|entry| (Predicate((entry.0).0.drain(len ..).collect()), - entry.1.drain(queue_len ..).collect())) + pub fn truncate_terms( + &mut self, + key: PredicateKey, + len: usize, + queue_len: usize, + ) -> (Predicate, VecDeque) { + self.term_dir + .get_mut(&key) + .map(|entry| { + ( + Predicate((entry.0).0.drain(len..).collect()), + entry.1.drain(queue_len..).collect(), + ) + }) .unwrap_or((Predicate::new(), VecDeque::from(vec![]))) } - pub fn add_in_situ_result(&mut self, result: &CompiledResult, in_situ_code_dir: &mut InSituCodeDir, - flags: MachineFlags) - -> Result<(), SessionError> - { + pub fn add_in_situ_result( + &mut self, + result: &CompiledResult, + in_situ_code_dir: &mut InSituCodeDir, + flags: MachineFlags, + ) -> Result<(), SessionError> { let (ref decl, ref queue) = result; - let (name, arity) = decl.0.first().and_then(|cl| { - let arity = cl.arity(); - cl.name().map(|name| (name, arity)) - }).ok_or(SessionError::NamelessEntry)?; + let (name, arity) = decl + .0 + .first() + .and_then(|cl| { + let arity = cl.arity(); + cl.name().map(|name| (name, arity)) + }) + .ok_or(SessionError::NamelessEntry)?; let p = self.in_situ_code.len(); in_situ_code_dir.insert((name, arity), p); @@ -74,53 +89,57 @@ impl CodeRepo { } #[inline] - pub(super) - fn size_of_cached_query(&self) -> usize { + pub(super) fn size_of_cached_query(&self) -> usize { self.cached_query.len() } - pub(super) - fn lookup_instr<'a>(&'a self, last_call: bool, p: &CodePtr) -> Option> - { + pub(super) fn lookup_instr<'a>( + &'a self, + last_call: bool, + p: &CodePtr, + ) -> Option> { match p { - &CodePtr::Local(LocalCodePtr::UserGoalExpansion(p)) => + &CodePtr::Local(LocalCodePtr::UserGoalExpansion(p)) => { if p < self.goal_expanders.len() { Some(RefOrOwned::Borrowed(&self.goal_expanders[p])) } else { None - }, - &CodePtr::Local(LocalCodePtr::UserTermExpansion(p)) => + } + } + &CodePtr::Local(LocalCodePtr::UserTermExpansion(p)) => { if p < self.term_expanders.len() { Some(RefOrOwned::Borrowed(&self.term_expanders[p])) } else { None - }, - &CodePtr::Local(LocalCodePtr::TopLevel(_, p)) => + } + } + &CodePtr::Local(LocalCodePtr::TopLevel(_, p)) => { if p < self.cached_query.len() { Some(RefOrOwned::Borrowed(&self.cached_query[p])) } else { None - }, - &CodePtr::Local(LocalCodePtr::InSituDirEntry(p)) => - Some(RefOrOwned::Borrowed(&self.in_situ_code[p])), - &CodePtr::Local(LocalCodePtr::DirEntry(p)) => - Some(RefOrOwned::Borrowed(&self.code[p])), - &CodePtr::REPL(..) => - None, + } + } + &CodePtr::Local(LocalCodePtr::InSituDirEntry(p)) => { + Some(RefOrOwned::Borrowed(&self.in_situ_code[p])) + } + &CodePtr::Local(LocalCodePtr::DirEntry(p)) => Some(RefOrOwned::Borrowed(&self.code[p])), + &CodePtr::REPL(..) => None, &CodePtr::BuiltInClause(ref built_in, _) => { - let call_clause = call_clause!(ClauseType::BuiltIn(built_in.clone()), - built_in.arity(), - 0, last_call); + let call_clause = call_clause!( + ClauseType::BuiltIn(built_in.clone()), + built_in.arity(), + 0, + last_call + ); Some(RefOrOwned::Owned(call_clause)) - }, + } &CodePtr::CallN(arity, _) => { let call_clause = call_clause!(ClauseType::CallN, arity, 0, last_call); Some(RefOrOwned::Owned(call_clause)) - }, - &CodePtr::VerifyAttrInterrupt(p) => - Some(RefOrOwned::Borrowed(&self.code[p])), - &CodePtr::DynamicTransaction(..) => - None + } + &CodePtr::VerifyAttrInterrupt(p) => Some(RefOrOwned::Borrowed(&self.code[p])), + &CodePtr::DynamicTransaction(..) => None, } } } diff --git a/src/prolog/machine/compile.rs b/src/prolog/machine/compile.rs index 1d11df51..071d8f49 100644 --- a/src/prolog/machine/compile.rs +++ b/src/prolog/machine/compile.rs @@ -2,15 +2,15 @@ use prolog_parser::ast::*; use prolog_parser::parser::get_desc; use prolog_parser::tabled_rc::TabledData; -use prolog::instructions::*; use prolog::codegen::*; use prolog::debray_allocator::*; use prolog::forms::*; -use prolog::machine::*; +use prolog::instructions::*; use prolog::machine::machine_errors::*; use prolog::machine::machine_indices::*; -use prolog::machine::term_expansion::{ExpansionAdditionResult}; +use prolog::machine::term_expansion::ExpansionAdditionResult; use prolog::machine::toplevel::*; +use prolog::machine::*; use indexmap::{IndexMap, IndexSet}; @@ -25,28 +25,19 @@ use std::path::PathBuf; fn print_code(code: &Code) { for clause in code { match clause { - &Line::Arithmetic(ref arith) => - println!("{}", arith), - &Line::Fact(ref fact_instr) => - println!("{}", fact_instr), - &Line::Cut(ref cut) => - println!("{}", cut), - &Line::Choice(ref choice) => - println!("{}", choice), - &Line::Control(ref control) => - println!("{}", control), - &Line::IndexedChoice(ref choice) => - println!("{}", choice), - &Line::Indexing(ref indexing) => - println!("{}", indexing), - &Line::Query(ref query_instr) => - println!("{}", query_instr) + &Line::Arithmetic(ref arith) => println!("{}", arith), + &Line::Fact(ref fact_instr) => println!("{}", fact_instr), + &Line::Cut(ref cut) => println!("{}", cut), + &Line::Choice(ref choice) => println!("{}", choice), + &Line::Control(ref control) => println!("{}", control), + &Line::IndexedChoice(ref choice) => println!("{}", choice), + &Line::Indexing(ref indexing) => println!("{}", indexing), + &Line::Query(ref query_instr) => println!("{}", query_instr), } } } -fn fix_filename(atom_tbl: TabledData, filename: &str) -> Result -{ +fn fix_filename(atom_tbl: TabledData, filename: &str) -> Result { let mut path = PathBuf::from(filename); if !path.is_file() { @@ -63,8 +54,7 @@ fn fix_filename(atom_tbl: TabledData, filename: &str) -> Result Result -{ +fn load_module_from_file(wam: &mut Machine, filename: &str) -> Result { let path = fix_filename(wam.indices.atom_tbl.clone(), filename)?; let file_handle = File::open(&path).or_else(|_| { @@ -94,52 +84,53 @@ fn load_module_from_file(wam: &mut Machine, filename: &str) -> Result Err(e), - _ => Ok(module_name) + _ => Ok(module_name), } } pub type PredicateCompileQueue = (Predicate, VecDeque); // throw errors if declaration or query found. -fn compile_relation(tl: &TopLevel, non_counted_bt: bool, flags: MachineFlags) - -> Result -{ +fn compile_relation( + tl: &TopLevel, + non_counted_bt: bool, + flags: MachineFlags, +) -> Result { let mut cg = CodeGenerator::::new(non_counted_bt, flags); match tl { - &TopLevel::Declaration(_) | &TopLevel::Query(_) => - Err(ParserError::ExpectedRel), - &TopLevel::Predicate(ref clauses) => - cg.compile_predicate(&clauses.0), - &TopLevel::Fact(ref fact) => - Ok(cg.compile_fact(fact)), - &TopLevel::Rule(ref rule) => - cg.compile_rule(rule) + &TopLevel::Declaration(_) | &TopLevel::Query(_) => Err(ParserError::ExpectedRel), + &TopLevel::Predicate(ref clauses) => cg.compile_predicate(&clauses.0), + &TopLevel::Fact(ref fact) => Ok(cg.compile_fact(fact)), + &TopLevel::Rule(ref rule) => cg.compile_rule(rule), } } // set first jmp_by_call or jmp_by_index instruction to code.len() - // idx, where idx is the place it occurs. It only does this to the // *first* uninitialized jmp index it encounters, then returns. -fn set_first_index(code: &mut Code) -{ +fn set_first_index(code: &mut Code) { let code_len = code.len(); for (idx, line) in code.iter_mut().enumerate() { match line { - &mut Line::Control(ControlInstruction::JmpBy(_, ref mut offset, ..)) if *offset == 0 => { + &mut Line::Control(ControlInstruction::JmpBy(_, ref mut offset, ..)) + if *offset == 0 => + { *offset = code_len - idx; break; - }, + } _ => {} }; } } -pub fn compile_appendix(code: &mut Code, queue: &VecDeque, non_counted_bt: bool, - flags: MachineFlags) - -> Result<(), ParserError> -{ +pub fn compile_appendix( + code: &mut Code, + queue: &VecDeque, + non_counted_bt: bool, + flags: MachineFlags, +) -> Result<(), ParserError> { for tl in queue.iter() { set_first_index(code); code.append(&mut compile_relation(tl, non_counted_bt, flags)?); @@ -149,11 +140,13 @@ pub fn compile_appendix(code: &mut Code, queue: &VecDeque, non_counted } impl CodeRepo { - pub fn compile_hook(&mut self, hook: CompileTimeHook, flags: MachineFlags) - -> Result<(), ParserError> - { + pub fn compile_hook( + &mut self, + hook: CompileTimeHook, + flags: MachineFlags, + ) -> Result<(), ParserError> { let key = (hook.name(), hook.arity()); - + match self.term_dir.get(&key) { Some(preds) => { let mut cg = CodeGenerator::::new(false, flags); @@ -162,20 +155,24 @@ impl CodeRepo { compile_appendix(&mut code, &preds.1, false, flags)?; Ok(match hook { - CompileTimeHook::UserTermExpansion | CompileTimeHook::TermExpansion => - self.term_expanders = code, - CompileTimeHook::UserGoalExpansion | CompileTimeHook::GoalExpansion => + CompileTimeHook::UserTermExpansion | CompileTimeHook::TermExpansion => { + self.term_expanders = code + } + CompileTimeHook::UserGoalExpansion | CompileTimeHook::GoalExpansion => { self.goal_expanders = code + } }) - }, - None => Ok(()) + } + None => Ok(()), } } } -fn compile_query(terms: Vec, queue: VecDeque, flags: MachineFlags) - -> Result<(Code, AllocVarDict), ParserError> -{ +fn compile_query( + terms: Vec, + queue: VecDeque, + flags: MachineFlags, +) -> Result<(Code, AllocVarDict), ParserError> { // count backtracking inferences. let mut cg = CodeGenerator::::new(false, flags); let mut code = try!(cg.compile_query(&terms)); @@ -184,9 +181,11 @@ fn compile_query(terms: Vec, queue: VecDeque, flags: Machin Ok((code, cg.take_vars())) } -fn compile_decl(wam: &mut Machine, compiler: &mut ListingCompiler, decl: Declaration) - -> Result -{ +fn compile_decl( + wam: &mut Machine, + compiler: &mut ListingCompiler, + decl: Declaration, +) -> Result { let flags = wam.machine_flags(); let mut indices = default_index_store!(wam.indices.atom_tbl.clone()); @@ -195,14 +194,14 @@ fn compile_decl(wam: &mut Machine, compiler: &mut ListingCompiler, decl: Declara Ok(indices) } -pub fn compile_term(wam: &mut Machine, packet: TopLevelPacket) -> EvalSession -{ +pub fn compile_term(wam: &mut Machine, packet: TopLevelPacket) -> EvalSession { match packet { - TopLevelPacket::Query(terms, queue) => + TopLevelPacket::Query(terms, queue) => { match compile_query(terms, queue, wam.machine_flags()) { Ok((code, vars)) => wam.submit_query(code, vars), - Err(e) => EvalSession::from(e) - }, + Err(e) => EvalSession::from(e), + } + } TopLevelPacket::Decl(TopLevel::Declaration(decl), _) => { let mut compiler = ListingCompiler::new(&wam.code_repo); let indices = try_eval_session!(compile_decl(wam, &mut compiler, decl)); @@ -211,13 +210,12 @@ pub fn compile_term(wam: &mut Machine, packet: TopLevelPacket) -> EvalSession add_toplevel_code(wam, vec![], indices); EvalSession::EntrySuccess - }, - _ => EvalSession::from(SessionError::UserPrompt) + } + _ => EvalSession::from(SessionError::UserPrompt), } } -fn update_module_indices(wam: &Machine, module_name: ClauseName, mut indices: IndexStore) -{ +fn update_module_indices(wam: &Machine, module_name: ClauseName, mut indices: IndexStore) { match wam.indices.modules.get(&module_name) { Some(module) => { let code_dir = mem::replace(&mut indices.code_dir, CodeDir::new()); @@ -232,49 +230,61 @@ fn update_module_indices(wam: &Machine, module_name: ClauseName, mut indices: In } match wam.indices.code_dir.get(&key) { - Some(idx) => if idx.0.borrow().1 == module_name { - set_code_index!(idx, p, module_name.clone()); - }, + Some(idx) => { + if idx.0.borrow().1 == module_name { + set_code_index!(idx, p, module_name.clone()); + } + } _ => {} } } - }, - _ => unreachable!() + } + _ => unreachable!(), }; } -fn add_hooks_to_mockup(code_repo: &mut CodeRepo, hook: CompileTimeHook, - expansions: (Predicate, VecDeque)) -{ +fn add_hooks_to_mockup( + code_repo: &mut CodeRepo, + hook: CompileTimeHook, + expansions: (Predicate, VecDeque), +) { let key = (hook.name(), hook.arity()); - let preds = code_repo.term_dir.entry(key.clone()) + let preds = code_repo + .term_dir + .entry(key.clone()) .or_insert((Predicate::new(), VecDeque::from(vec![]))); (preds.0).0.extend((expansions.0).0.into_iter()); preds.1.extend(expansions.1.into_iter()); } -fn setup_module_expansions(wam: &mut Machine, module_name: ClauseName) -{ +fn setup_module_expansions(wam: &mut Machine, module_name: ClauseName) { match wam.indices.modules.get(&module_name) { Some(module) => { let term_expansions = module.term_expansions.clone(); let goal_expansions = module.goal_expansions.clone(); - add_hooks_to_mockup(&mut wam.code_repo, CompileTimeHook::TermExpansion, - term_expansions); - add_hooks_to_mockup(&mut wam.code_repo, CompileTimeHook::GoalExpansion, - goal_expansions); - }, - _ => unreachable!() + add_hooks_to_mockup( + &mut wam.code_repo, + CompileTimeHook::TermExpansion, + term_expansions, + ); + add_hooks_to_mockup( + &mut wam.code_repo, + CompileTimeHook::GoalExpansion, + goal_expansions, + ); + } + _ => unreachable!(), } } -pub(super) -fn compile_into_module(wam: &mut Machine, module_name: ClauseName, - src: ParsingStream, name: ClauseName) - -> EvalSession -{ +pub(super) fn compile_into_module( + wam: &mut Machine, + module_name: ClauseName, + src: ParsingStream, + name: ClauseName, +) -> EvalSession { let mut indices = default_index_store!(wam.atom_tbl_of(&name)); try_eval_session!(setup_indices(wam, module_name.clone(), &mut indices)); @@ -289,21 +299,25 @@ fn compile_into_module(wam: &mut Machine, module_name: ClauseName, } } -fn compile_into_module_impl(wam: &mut Machine, compiler: &mut ListingCompiler, - module_name: ClauseName, src: ParsingStream, - mut indices: IndexStore) - -> Result<(), SessionError> -{ +fn compile_into_module_impl( + wam: &mut Machine, + compiler: &mut ListingCompiler, + module_name: ClauseName, + src: ParsingStream, + mut indices: IndexStore, +) -> Result<(), SessionError> { setup_module_expansions(wam, module_name.clone()); let flags = wam.machine_flags(); - wam.code_repo.compile_hook(CompileTimeHook::TermExpansion, flags)?; - wam.code_repo.compile_hook(CompileTimeHook::GoalExpansion, flags)?; + wam.code_repo + .compile_hook(CompileTimeHook::TermExpansion, flags)?; + wam.code_repo + .compile_hook(CompileTimeHook::GoalExpansion, flags)?; let results = compiler.gather_items(wam, src, &mut indices)?; - let module_code = compiler.generate_code(results.worker_results, wam, - &mut indices.code_dir, 0)?; + let module_code = + compiler.generate_code(results.worker_results, wam, &mut indices.code_dir, 0)?; let mut clause_code_generator = ClauseCodeGenerator::new(module_code.len()); clause_code_generator.generate_clause_code(results.dynamic_clause_map, wam)?; @@ -321,39 +335,53 @@ pub struct GatherResult { pub(crate) worker_results: Vec, toplevel_results: Vec, toplevel_indices: IndexStore, - addition_results: ExpansionAdditionResult + addition_results: ExpansionAdditionResult, } pub struct ClauseCodeGenerator { len_offset: usize, code: Code, - pi_to_loc: IndexMap + pi_to_loc: IndexMap, } impl ClauseCodeGenerator { #[inline] fn new(len_offset: usize) -> Self { - ClauseCodeGenerator { len_offset, code: vec![], pi_to_loc: IndexMap::new() } + ClauseCodeGenerator { + len_offset, + code: vec![], + pi_to_loc: IndexMap::new(), + } } - fn generate_clause_code(&mut self, dynamic_clause_map: DynamicClauseMap, wam: &Machine) - -> Result<(), SessionError> - { + fn generate_clause_code( + &mut self, + dynamic_clause_map: DynamicClauseMap, + wam: &Machine, + ) -> Result<(), SessionError> { for ((name, arity), heads_and_tails) in dynamic_clause_map { if heads_and_tails.is_empty() { continue; } - let predicate = Predicate(heads_and_tails.into_iter().map(|(head, tail)| { - let clause = Term::Clause(Cell::default(), clause_name!("clause"), - vec![Box::new(head), Box::new(tail)], - None); - PredicateClause::Fact(clause) - }).collect()); + let predicate = Predicate( + heads_and_tails + .into_iter() + .map(|(head, tail)| { + let clause = Term::Clause( + Cell::default(), + clause_name!("clause"), + vec![Box::new(head), Box::new(tail)], + None, + ); + PredicateClause::Fact(clause) + }) + .collect(), + ); let p = self.code.len() + wam.code_repo.code.len() + self.len_offset; - let mut decl_code = compile_relation(&TopLevel::Predicate(predicate), false, - wam.machine_flags())?; + let mut decl_code = + compile_relation(&TopLevel::Predicate(predicate), false, wam.machine_flags())?; compile_appendix(&mut decl_code, &VecDeque::new(), false, wam.machine_flags())?; @@ -368,8 +396,11 @@ impl ClauseCodeGenerator { wam.code_repo.code.extend(self.code.into_iter()); for ((name, arity), p) in self.pi_to_loc { - let entry = wam.indices.dynamic_code_dir.entry((name.owning_module(), name, arity)) - .or_insert(DynamicPredicateInfo::default()); + let entry = wam + .indices + .dynamic_code_dir + .entry((name.owning_module(), name, arity)) + .or_insert(DynamicPredicateInfo::default()); entry.clauses_subsection_p = p; } @@ -381,40 +412,42 @@ pub struct ListingCompiler { module: Option, user_term_dir: TermDir, orig_term_expansion_lens: (usize, usize), - orig_goal_expansion_lens: (usize, usize) + orig_goal_expansion_lens: (usize, usize), } -fn add_toplevel_code(wam: &mut Machine, code: Code, mut indices: IndexStore) -{ +fn add_toplevel_code(wam: &mut Machine, code: Code, mut indices: IndexStore) { let code_dir = mem::replace(&mut indices.code_dir, CodeDir::new()); - let op_dir = mem::replace(&mut indices.op_dir, OpDir::new()); + let op_dir = mem::replace(&mut indices.op_dir, OpDir::new()); wam.add_batched_code(code, code_dir); wam.add_batched_ops(op_dir); } #[inline] -fn add_module_code(wam: &mut Machine, mut module: Module, code: Code, mut indices: IndexStore) -{ +fn add_module_code(wam: &mut Machine, mut module: Module, code: Code, mut indices: IndexStore) { let code_dir = mem::replace(&mut indices.code_dir, CodeDir::new()); - let op_dir = mem::replace(&mut indices.op_dir, OpDir::new()); + let op_dir = mem::replace(&mut indices.op_dir, OpDir::new()); module.code_dir.extend(code_dir); module.op_dir.extend(op_dir.into_iter()); for (name, arity) in indices.code_dir.keys().cloned() { if name.owning_module() == module.module_decl.name { - wam.indices.dynamic_code_dir.remove(&(name.owning_module(), name, arity)); + wam.indices + .dynamic_code_dir + .remove(&(name.owning_module(), name, arity)); } } wam.add_module(module, code); } -fn add_non_module_code(wam: &mut Machine, dynamic_clause_map: DynamicClauseMap, code: Code, - indices: IndexStore) - -> Result<(), SessionError> -{ +fn add_non_module_code( + wam: &mut Machine, + dynamic_clause_map: DynamicClauseMap, + code: Code, + indices: IndexStore, +) -> Result<(), SessionError> { wam.check_toplevel_code(&indices)?; let mut clause_code_generator = ClauseCodeGenerator::new(code.len()); @@ -433,8 +466,10 @@ impl ListingCompiler { non_counted_bt_preds: IndexSet::new(), module: None, user_term_dir: TermDir::new(), - orig_term_expansion_lens: code_repo.term_dir_entry_len((clause_name!("term_expansion"), 2)), - orig_goal_expansion_lens: code_repo.term_dir_entry_len((clause_name!("goal_expansion"), 2)), + orig_term_expansion_lens: code_repo + .term_dir_entry_len((clause_name!("term_expansion"), 2)), + orig_goal_expansion_lens: code_repo + .term_dir_entry_len((clause_name!("goal_expansion"), 2)), } } @@ -442,8 +477,7 @@ impl ListingCompiler { Replace calls to self with a localized index cell, not available to the global CodeIndex. This is done to implement logical update semantics for dynamic database updates. */ - fn localize_self_calls(&mut self, name: ClauseName, arity: usize, code: &mut Code, p: usize) - { + fn localize_self_calls(&mut self, name: ClauseName, arity: usize, code: &mut Code, p: usize) { let self_idx = CodeIndex::default(); set_code_index!(self_idx, IndexPtr::Index(p), self.get_module_name()); @@ -451,33 +485,43 @@ impl ListingCompiler { if let &mut Line::Control(ControlInstruction::CallClause(ref mut ct, ..)) = instr { match ct { &mut ClauseType::Named(ref ct_name, ct_arity, ref mut idx) - if ct_name == &name && arity == ct_arity => { - *idx = self_idx.clone(); - }, + if ct_name == &name && arity == ct_arity => + { + *idx = self_idx.clone(); + } &mut ClauseType::Op(ref op_name, ref shared_op_desc, ref mut idx) - if op_name == &name && shared_op_desc.arity() == arity => { - *idx = self_idx.clone(); - }, + if op_name == &name && shared_op_desc.arity() == arity => + { + *idx = self_idx.clone(); + } _ => {} } } } } - fn use_module(&mut self, submodule: ClauseName, code_repo: &mut CodeRepo, flags: MachineFlags, - wam_indices: &mut IndexStore, indices: &mut IndexStore) - -> Result<(), SessionError> - { + fn use_module( + &mut self, + submodule: ClauseName, + code_repo: &mut CodeRepo, + flags: MachineFlags, + wam_indices: &mut IndexStore, + indices: &mut IndexStore, + ) -> Result<(), SessionError> { let module_name = self.get_module_name(); if let Some(mut submodule) = wam_indices.take_module(submodule) { - unwind_protect!(indices.use_module(code_repo, flags, &submodule), - wam_indices.insert_module(submodule)); + unwind_protect!( + indices.use_module(code_repo, flags, &submodule), + wam_indices.insert_module(submodule) + ); if let &mut Some(ref mut module) = &mut self.module { module.remove_module(module_name, &submodule); - unwind_protect!(module.use_module(code_repo, flags, &submodule), - wam_indices.insert_module(submodule)); + unwind_protect!( + module.use_module(code_repo, flags, &submodule), + wam_indices.insert_module(submodule) + ); } else { submodule.inserted_expansions = true; wam_indices.remove_module(clause_name!("user"), &submodule); @@ -489,21 +533,29 @@ impl ListingCompiler { } } - fn use_qualified_module(&mut self, submodule: ClauseName, code_repo: &mut CodeRepo, - flags: MachineFlags, exports: &Vec, - wam_indices: &mut IndexStore, indices: &mut IndexStore) - -> Result<(), SessionError> - { + fn use_qualified_module( + &mut self, + submodule: ClauseName, + code_repo: &mut CodeRepo, + flags: MachineFlags, + exports: &Vec, + wam_indices: &mut IndexStore, + indices: &mut IndexStore, + ) -> Result<(), SessionError> { let module_name = self.get_module_name(); if let Some(mut submodule) = wam_indices.take_module(submodule) { - unwind_protect!(indices.use_qualified_module(code_repo, flags, &submodule, exports), - wam_indices.insert_module(submodule)); + unwind_protect!( + indices.use_qualified_module(code_repo, flags, &submodule, exports), + wam_indices.insert_module(submodule) + ); if let &mut Some(ref mut module) = &mut self.module { module.remove_module(module_name, &submodule); - unwind_protect!(module.use_qualified_module(code_repo, flags, &submodule, exports), - wam_indices.insert_module(submodule)); + unwind_protect!( + module.use_qualified_module(code_repo, flags, &submodule, exports), + wam_indices.insert_module(submodule) + ); } else { submodule.inserted_expansions = true; wam_indices.remove_module(clause_name!("user"), &submodule); @@ -517,29 +569,39 @@ impl ListingCompiler { #[inline] fn get_module_name(&self) -> ClauseName { - self.module.as_ref() + self.module + .as_ref() .map(|module| module.module_decl.name.clone()) .unwrap_or(ClauseName::BuiltIn("user")) } - pub(crate) - fn generate_code(&mut self, decls: Vec, wam: &Machine, - code_dir: &mut CodeDir, code_offset: usize) - -> Result - { + pub(crate) fn generate_code( + &mut self, + decls: Vec, + wam: &Machine, + code_dir: &mut CodeDir, + code_offset: usize, + ) -> Result { let mut code = vec![]; for (decl, queue) in decls { - let (name, arity) = decl.predicate_indicator().ok_or(SessionError::NamelessEntry)?; + let (name, arity) = decl + .predicate_indicator() + .ok_or(SessionError::NamelessEntry)?; let non_counted_bt = self.non_counted_bt_preds.contains(&(name.clone(), arity)); let p = code.len() + wam.code_repo.code.len() + code_offset; - let mut decl_code = compile_relation(&TopLevel::Predicate(decl), non_counted_bt, - wam.machine_flags())?; + let mut decl_code = compile_relation( + &TopLevel::Predicate(decl), + non_counted_bt, + wam.machine_flags(), + )?; compile_appendix(&mut decl_code, &queue, non_counted_bt, wam.machine_flags())?; - let idx = code_dir.entry((name.clone(), arity)).or_insert(CodeIndex::default()); + let idx = code_dir + .entry((name.clone(), arity)) + .or_insert(CodeIndex::default()); set_code_index!(idx, IndexPtr::Index(p), self.get_module_name()); self.localize_self_calls(name, arity, &mut decl_code, p); @@ -553,17 +615,25 @@ impl ListingCompiler { self.non_counted_bt_preds.insert((name, arity)); } - fn add_term_dir_terms(&mut self, hook: CompileTimeHook, code_repo: &mut CodeRepo, - key: PredicateKey, clause: PredicateClause, queue: VecDeque) - -> (usize, usize) - { - let preds = code_repo.term_dir.entry(key.clone()) + fn add_term_dir_terms( + &mut self, + hook: CompileTimeHook, + code_repo: &mut CodeRepo, + key: PredicateKey, + clause: PredicateClause, + queue: VecDeque, + ) -> (usize, usize) { + let preds = code_repo + .term_dir + .entry(key.clone()) .or_insert((Predicate::new(), VecDeque::from(vec![]))); let (mut len, mut queue_len) = ((preds.0).0.len(), preds.1.len()); if self.module.is_some() && hook.has_module_scope() { - let module_preds = self.user_term_dir.entry(key.clone()) + let module_preds = self + .user_term_dir + .entry(key.clone()) .or_insert((Predicate::new(), VecDeque::from(vec![]))); if let Some(ref mut module) = &mut self.module { @@ -576,7 +646,9 @@ impl ListingCompiler { (preds.0).0.extend((module_preds.0).0.iter().cloned()); preds.1.extend(module_preds.1.iter().cloned()); } else { - let module_preds = self.user_term_dir.entry(key.clone()) + let module_preds = self + .user_term_dir + .entry(key.clone()) .or_insert((Predicate::new(), VecDeque::from(vec![]))); len += 1; @@ -592,38 +664,56 @@ impl ListingCompiler { (len, queue_len) } - fn process_decl(&mut self, decl: Declaration, wam: &mut Machine, indices: &mut IndexStore, - flags: MachineFlags) - -> Result<(), SessionError> - { + fn process_decl( + &mut self, + decl: Declaration, + wam: &mut Machine, + indices: &mut IndexStore, + flags: MachineFlags, + ) -> Result<(), SessionError> { match decl { Declaration::EndOfFile => Ok(()), Declaration::Hook(hook, clause, queue) => { let key = (hook.name(), hook.arity()); - let (len, queue_len) = self.add_term_dir_terms(hook, &mut wam.code_repo, - key.clone(), clause, queue); + let (len, queue_len) = + self.add_term_dir_terms(hook, &mut wam.code_repo, key.clone(), clause, queue); - let result = wam.code_repo.compile_hook(hook, flags).map_err(SessionError::from); + let result = wam + .code_repo + .compile_hook(hook, flags) + .map_err(SessionError::from); wam.code_repo.truncate_terms(key, len, queue_len); result - }, - Declaration::NonCountedBacktracking(name, arity) => - Ok(self.add_non_counted_bt_flag(name, arity)), + } + Declaration::NonCountedBacktracking(name, arity) => { + Ok(self.add_non_counted_bt_flag(name, arity)) + } Declaration::Op(op_decl) => { - let spec = get_desc(op_decl.name(), composite_op!(self.module.is_some(), - &wam.indices.op_dir, - &mut indices.op_dir)); + let spec = get_desc( + op_decl.name(), + composite_op!( + self.module.is_some(), + &wam.indices.op_dir, + &mut indices.op_dir + ), + ); op_decl.submit(self.get_module_name(), spec, &mut indices.op_dir) - }, - Declaration::UseModule(ModuleSource::Library(name)) => - self.use_module(name, &mut wam.code_repo, flags, &mut wam.indices, - indices), - Declaration::UseQualifiedModule(ModuleSource::Library(name), exports) => - self.use_qualified_module(name, &mut wam.code_repo, flags, &exports, - &mut wam.indices, indices), - Declaration::Module(module_decl) => + } + Declaration::UseModule(ModuleSource::Library(name)) => { + self.use_module(name, &mut wam.code_repo, flags, &mut wam.indices, indices) + } + Declaration::UseQualifiedModule(ModuleSource::Library(name), exports) => self + .use_qualified_module( + name, + &mut wam.code_repo, + flags, + &exports, + &mut wam.indices, + indices, + ), + Declaration::Module(module_decl) => { if self.module.is_none() { let module_name = module_decl.name.clone(); let atom_tbl = TabledData::new(module_name.to_rc()); @@ -631,38 +721,53 @@ impl ListingCompiler { Ok(self.module = Some(Module::new(module_decl, atom_tbl))) } else { Err(SessionError::from(ParserError::InvalidModuleDecl)) - }, + } + } Declaration::UseModule(ModuleSource::File(filename)) => { let name = load_module_from_file(wam, filename.as_str())?; self.use_module(name, &mut wam.code_repo, flags, &mut wam.indices, indices) - }, + } Declaration::UseQualifiedModule(ModuleSource::File(filename), exports) => { let name = load_module_from_file(wam, filename.as_str())?; - self.use_qualified_module(name, &mut wam.code_repo, flags, &exports, - &mut wam.indices, indices) - }, - Declaration::Dynamic(..) => Ok(()) + self.use_qualified_module( + name, + &mut wam.code_repo, + flags, + &exports, + &mut wam.indices, + indices, + ) + } + Declaration::Dynamic(..) => Ok(()), } } - fn process_and_commit_decl(&mut self, decl: Declaration, - worker: &mut TopLevelBatchWorker, - indices: &mut IndexStore, flags: MachineFlags) - -> Result<(), SessionError> - { + fn process_and_commit_decl( + &mut self, + decl: Declaration, + worker: &mut TopLevelBatchWorker, + indices: &mut IndexStore, + flags: MachineFlags, + ) -> Result<(), SessionError> { let mut update_expansion_lengths = false; match &decl { &Declaration::Dynamic(ref name, arity) => { - worker.dynamic_clause_map.entry((name.clone(), arity)).or_insert(vec![]); - }, - &Declaration::Hook(hook, _, ref queue) if self.module.is_none() => - worker.term_stream.incr_expansion_lens(hook.user_scope(), 1, queue.len()), - &Declaration::Hook(hook, _, ref queue) if !hook.has_module_scope() => - worker.term_stream.incr_expansion_lens(hook, 1, queue.len()), + worker + .dynamic_clause_map + .entry((name.clone(), arity)) + .or_insert(vec![]); + } + &Declaration::Hook(hook, _, ref queue) if self.module.is_none() => worker + .term_stream + .incr_expansion_lens(hook.user_scope(), 1, queue.len()), + &Declaration::Hook(hook, _, ref queue) if !hook.has_module_scope() => { + worker.term_stream.incr_expansion_lens(hook, 1, queue.len()) + } &Declaration::UseModule(ModuleSource::File(_)) - | &Declaration::UseQualifiedModule(ModuleSource::File(_), _) => - update_expansion_lengths = true, + | &Declaration::UseQualifiedModule(ModuleSource::File(_), _) => { + update_expansion_lengths = true + } _ => {} }; @@ -675,13 +780,14 @@ impl ListingCompiler { result } - pub(crate) - fn gather_items(&mut self, wam: &mut Machine, mut src: ParsingStream, - indices: &mut IndexStore) - -> Result - { - let flags = wam.machine_flags(); - let atom_tbl = indices.atom_tbl.clone(); + pub(crate) fn gather_items( + &mut self, + wam: &mut Machine, + mut src: ParsingStream, + indices: &mut IndexStore, + ) -> Result { + let flags = wam.machine_flags(); + let atom_tbl = indices.atom_tbl.clone(); let mut worker = TopLevelBatchWorker::new(&mut src, atom_tbl.clone(), flags, wam); let mut toplevel_results = vec![]; @@ -712,12 +818,11 @@ impl ListingCompiler { dynamic_clause_map: worker.dynamic_clause_map, toplevel_results, toplevel_indices, - addition_results + addition_results, }) } - fn drop_expansions(&self, flags: MachineFlags, code_repo: &mut CodeRepo) - { + fn drop_expansions(&self, flags: MachineFlags, code_repo: &mut CodeRepo) { let (te_len, te_queue_len) = self.orig_term_expansion_lens; let (ge_len, ge_queue_len) = self.orig_goal_expansion_lens; @@ -729,15 +834,24 @@ impl ListingCompiler { } } -fn compile_work_impl(compiler: &mut ListingCompiler, wam: &mut Machine, - mut indices: IndexStore, mut results: GatherResult) - -> EvalSession -{ - let module_code = try_eval_session!(compiler.generate_code(results.worker_results, wam, - &mut indices.code_dir, 0)); - let toplvl_code = try_eval_session!(compiler.generate_code(results.toplevel_results, wam, - &mut results.toplevel_indices.code_dir, - module_code.len())); +fn compile_work_impl( + compiler: &mut ListingCompiler, + wam: &mut Machine, + mut indices: IndexStore, + mut results: GatherResult, +) -> EvalSession { + let module_code = try_eval_session!(compiler.generate_code( + results.worker_results, + wam, + &mut indices.code_dir, + 0 + )); + let toplvl_code = try_eval_session!(compiler.generate_code( + results.toplevel_results, + wam, + &mut results.toplevel_indices.code_dir, + module_code.len() + )); if let Some(ref mut module) = &mut compiler.module { module.user_term_expansions = results.addition_results.take_term_expansions(); @@ -746,42 +860,55 @@ fn compile_work_impl(compiler: &mut ListingCompiler, wam: &mut Machine, let flags = wam.machine_flags(); - try_eval_session!(wam.code_repo.compile_hook(CompileTimeHook::UserTermExpansion, flags)); - try_eval_session!(wam.code_repo.compile_hook(CompileTimeHook::UserGoalExpansion, flags)); + try_eval_session!(wam + .code_repo + .compile_hook(CompileTimeHook::UserTermExpansion, flags)); + try_eval_session!(wam + .code_repo + .compile_hook(CompileTimeHook::UserGoalExpansion, flags)); if let Some(module) = compiler.module.take() { - let mut clause_code_generator = ClauseCodeGenerator::new(module_code.len() + toplvl_code.len()); + let mut clause_code_generator = + ClauseCodeGenerator::new(module_code.len() + toplvl_code.len()); try_eval_session!(wam.check_toplevel_code(&results.toplevel_indices)); - try_eval_session!(clause_code_generator.generate_clause_code(results.dynamic_clause_map, - wam)); + try_eval_session!( + clause_code_generator.generate_clause_code(results.dynamic_clause_map, wam) + ); add_module_code(wam, module, module_code, indices); add_toplevel_code(wam, toplvl_code, results.toplevel_indices); clause_code_generator.add_clause_code(wam); } else { - try_eval_session!(add_non_module_code(wam, results.dynamic_clause_map, module_code, - indices)); + try_eval_session!(add_non_module_code( + wam, + results.dynamic_clause_map, + module_code, + indices + )); } EvalSession::EntrySuccess } -fn compile_work(compiler: &mut ListingCompiler, wam: &mut Machine, - src: ParsingStream, mut indices: IndexStore) - -> EvalSession -{ +fn compile_work( + compiler: &mut ListingCompiler, + wam: &mut Machine, + src: ParsingStream, + mut indices: IndexStore, +) -> EvalSession { let results = try_eval_session!(compiler.gather_items(wam, src, &mut indices)); compile_work_impl(compiler, wam, indices, results) } /* This is a truncated version of compile_user_module, used for - compiling code composing special forms, ie. the code that calls - M:verify_attributes on attributed variables. */ -pub fn compile_special_form(wam: &mut Machine, src: ParsingStream) - -> Result -{ +compiling code composing special forms, ie. the code that calls +M:verify_attributes on attributed variables. */ +pub fn compile_special_form( + wam: &mut Machine, + src: ParsingStream, +) -> Result { let mut indices = default_index_store!(wam.indices.atom_tbl.clone()); setup_indices(wam, clause_name!("builtins"), &mut indices)?; @@ -792,27 +919,29 @@ pub fn compile_special_form(wam: &mut Machine, src: ParsingStream) } #[inline] -pub -fn compile_listing(wam: &mut Machine, src: ParsingStream, indices: IndexStore) - -> EvalSession -{ +pub fn compile_listing( + wam: &mut Machine, + src: ParsingStream, + indices: IndexStore, +) -> EvalSession { let mut compiler = ListingCompiler::new(&wam.code_repo); match compile_work(&mut compiler, wam, src, indices) { EvalSession::Error(e) => { compiler.drop_expansions(wam.machine_flags(), &mut wam.code_repo); EvalSession::Error(e) - }, - result => result + } + result => result, } } -pub(super) -fn setup_indices(wam: &mut Machine, module: ClauseName, indices: &mut IndexStore) - -> Result<(), SessionError> -{ +pub(super) fn setup_indices( + wam: &mut Machine, + module: ClauseName, + indices: &mut IndexStore, +) -> Result<(), SessionError> { if let Some(module) = wam.indices.take_module(module) { - let flags = wam.machine_flags(); + let flags = wam.machine_flags(); let result = indices.use_module(&mut wam.code_repo, flags, &module); wam.indices.insert_module(module); diff --git a/src/prolog/machine/copier.rs b/src/prolog/machine/copier.rs index 5a9d0772..4fd58f63 100644 --- a/src/prolog/machine/copier.rs +++ b/src/prolog/machine/copier.rs @@ -5,8 +5,7 @@ use std::ops::IndexMut; type Trail = Vec<(Ref, HeapCellValue)>; -pub(crate) trait CopierTarget: IndexMut -{ +pub(crate) trait CopierTarget: IndexMut { fn threshold(&self) -> usize; fn push(&mut self, HeapCellValue); fn store(&self, Addr) -> Addr; @@ -14,9 +13,7 @@ pub(crate) trait CopierTarget: IndexMut fn stack(&mut self) -> &mut AndStack; } -pub(crate) -fn copy_term(target: T, addr: Addr) -{ +pub(crate) fn copy_term(target: T, addr: Addr) { let mut copy_term_state = CopyTermState::new(target); copy_term_state.copy_term_impl(addr); } @@ -25,16 +22,16 @@ struct CopyTermState { trail: Trail, scan: usize, old_h: usize, - target: T + target: T, } impl CopyTermState { fn new(target: T) -> Self { CopyTermState { trail: vec![], - scan: 0, + scan: 0, old_h: target.threshold(), - target + target, } } @@ -44,24 +41,28 @@ impl CopyTermState { &mut self.target[scan] } - fn reinstantiate_var(&mut self, addr: Addr, threshold: usize) - { + fn reinstantiate_var(&mut self, addr: Addr, threshold: usize) { match addr { Addr::HeapCell(h) => { self.target[threshold] = HeapCellValue::Addr(Addr::HeapCell(threshold)); self.target[h] = HeapCellValue::Addr(Addr::HeapCell(threshold)); - self.trail.push((Ref::HeapCell(h), HeapCellValue::Addr(Addr::HeapCell(h)))); - }, + self.trail + .push((Ref::HeapCell(h), HeapCellValue::Addr(Addr::HeapCell(h)))); + } Addr::StackCell(fr, sc) => { self.target[threshold] = HeapCellValue::Addr(Addr::HeapCell(threshold)); self.target.stack()[fr][sc] = Addr::HeapCell(threshold); - self.trail.push((Ref::StackCell(fr, sc), HeapCellValue::Addr(Addr::StackCell(fr, sc)))); - }, + self.trail.push(( + Ref::StackCell(fr, sc), + HeapCellValue::Addr(Addr::StackCell(fr, sc)), + )); + } Addr::AttrVar(h) => { self.target[threshold] = HeapCellValue::Addr(Addr::AttrVar(threshold)); self.target[h] = HeapCellValue::Addr(Addr::AttrVar(threshold)); - self.trail.push((Ref::AttrVar(h), HeapCellValue::Addr(Addr::AttrVar(h)))); - }, + self.trail + .push((Ref::AttrVar(h), HeapCellValue::Addr(Addr::AttrVar(h)))); + } _ => {} } } @@ -93,16 +94,19 @@ impl CopyTermState { let rd = self.target.store(self.target.deref(ra)); match rd.clone() { - Addr::AttrVar(h) | Addr::HeapCell(h) if h >= self.old_h => - self.target[threshold] = HeapCellValue::Addr(rd), - ra @ Addr::AttrVar(_) | ra @ Addr::HeapCell(..) | ra @ Addr::StackCell(..) => + Addr::AttrVar(h) | Addr::HeapCell(h) if h >= self.old_h => { + self.target[threshold] = HeapCellValue::Addr(rd) + } + ra @ Addr::AttrVar(_) | ra @ Addr::HeapCell(..) | ra @ Addr::StackCell(..) => { if ra == rd { self.reinstantiate_var(ra, threshold); } else { self.target[threshold] = HeapCellValue::Addr(ra); - }, + } + } _ => { - self.trail.push((Ref::HeapCell(addr), self.target[addr].clone())); + self.trail + .push((Ref::HeapCell(addr), self.target[addr].clone())); self.target[addr] = HeapCellValue::Addr(Addr::Lis(threshold)) } }; @@ -120,23 +124,24 @@ impl CopyTermState { Addr::AttrVar(h) | Addr::HeapCell(h) if h >= self.old_h => { *self.value_at_scan() = HeapCellValue::Addr(rd); self.scan += 1; - }, + } Addr::AttrVar(h) if addr == rd => { let threshold = self.target.threshold(); - self.target.push(HeapCellValue::Addr(Addr::AttrVar(threshold))); + self.target + .push(HeapCellValue::Addr(Addr::AttrVar(threshold))); let list_val = self.target[h + 1].clone(); self.target.push(list_val); self.reinstantiate_var(addr, threshold); *self.value_at_scan() = HeapCellValue::Addr(Addr::AttrVar(threshold)); - }, + } _ if addr == rd => { let scan = self.scan; self.reinstantiate_var(addr, scan); self.scan += 1; - }, - _ => *self.value_at_scan() = HeapCellValue::Addr(rd) + } + _ => *self.value_at_scan() = HeapCellValue::Addr(rd), } } @@ -148,18 +153,22 @@ impl CopyTermState { *self.value_at_scan() = HeapCellValue::Addr(Addr::Str(threshold)); self.target[addr] = HeapCellValue::Addr(Addr::Str(threshold)); - self.trail.push((Ref::HeapCell(addr), - HeapCellValue::NamedStr(arity, name.clone(), fixity.clone()))); + self.trail.push(( + Ref::HeapCell(addr), + HeapCellValue::NamedStr(arity, name.clone(), fixity.clone()), + )); - self.target.push(HeapCellValue::NamedStr(arity, name, fixity)); + self.target + .push(HeapCellValue::NamedStr(arity, name, fixity)); - for i in 0 .. arity { + for i in 0..arity { let hcv = self.target[addr + 1 + i].clone(); self.target.push(hcv); } - }, - HeapCellValue::Addr(Addr::Str(addr)) => - *self.value_at_scan() = HeapCellValue::Addr(Addr::Str(addr)), + } + HeapCellValue::Addr(Addr::Str(addr)) => { + *self.value_at_scan() = HeapCellValue::Addr(Addr::Str(addr)) + } _ => {} } @@ -172,21 +181,15 @@ impl CopyTermState { while self.scan < self.target.threshold() { match self.value_at_scan().clone() { - HeapCellValue::NamedStr(..) => - self.scan += 1, - HeapCellValue::Addr(addr) => - match addr { - Addr::Lis(addr) => - self.copy_list(addr), - addr @ Addr::AttrVar(_) - | addr @ Addr::HeapCell(_) - | addr @ Addr::StackCell(..) => - self.copy_var(addr), - Addr::Str(addr) => - self.copy_structure(addr), - Addr::Con(_) | Addr::DBRef(_) => - self.scan += 1 - } + HeapCellValue::NamedStr(..) => self.scan += 1, + HeapCellValue::Addr(addr) => match addr { + Addr::Lis(addr) => self.copy_list(addr), + addr @ Addr::AttrVar(_) + | addr @ Addr::HeapCell(_) + | addr @ Addr::StackCell(..) => self.copy_var(addr), + Addr::Str(addr) => self.copy_structure(addr), + Addr::Con(_) | Addr::DBRef(_) => self.scan += 1, + }, } } @@ -194,12 +197,10 @@ impl CopyTermState { } fn unwind_trail(&mut self) { - for (r, value) in self.trail.drain(0 ..) { + for (r, value) in self.trail.drain(0..) { match r { - Ref::AttrVar(h) | Ref::HeapCell(h) => - self.target[h] = value, - Ref::StackCell(fr, sc) => - self.target.stack()[fr][sc] = value.as_addr(0) + Ref::AttrVar(h) | Ref::HeapCell(h) => self.target[h] = value, + Ref::StackCell(fr, sc) => self.target.stack()[fr][sc] = value.as_addr(0), } } } diff --git a/src/prolog/machine/dynamic_database.rs b/src/prolog/machine/dynamic_database.rs index d2dff3ba..361ab1e6 100644 --- a/src/prolog/machine/dynamic_database.rs +++ b/src/prolog/machine/dynamic_database.rs @@ -1,24 +1,26 @@ use prolog_parser::ast::*; use prolog::heap_print::*; -use prolog::machine::*; use prolog::machine::compile::*; use prolog::machine::machine_errors::*; +use prolog::machine::*; use std::io::Read; impl Machine { - pub(super) - fn atom_tbl_of(&self, name: &ClauseName) -> TabledData { + pub(super) fn atom_tbl_of(&self, name: &ClauseName) -> TabledData { match name { &ClauseName::User(ref rc) => rc.table.clone(), - _ => self.indices.atom_tbl() + _ => self.indices.atom_tbl(), } } - fn compile_into_machine(&mut self, src: ParsingStream, name: ClauseName, arity: usize) - -> EvalSession - { + fn compile_into_machine( + &mut self, + src: ParsingStream, + name: ClauseName, + arity: usize, + ) -> EvalSession { match name.owning_module().as_str() { "user" => match self.indices.code_dir.get(&(name.clone(), arity)).cloned() { Some(idx) => { @@ -26,37 +28,38 @@ impl Machine { match module.as_str() { "user" => compile_user_module(self, src), - _ => compile_into_module(self, module, src, name) + _ => compile_into_module(self, module, src, name), } - }, - None => compile_user_module(self, src) + } + None => compile_user_module(self, src), }, - _ => compile_into_module(self, name.owning_module(), src, name) + _ => compile_into_module(self, name.owning_module(), src, name), } } - fn get_predicate_key(&self, name: RegType, arity: RegType) -> PredicateKey - { - let name = self.machine_st[name].clone(); + fn get_predicate_key(&self, name: RegType, arity: RegType) -> PredicateKey { + let name = self.machine_st[name].clone(); let arity = self.machine_st[arity].clone(); let name = match self.machine_st.store(self.machine_st.deref(name)) { Addr::Con(Constant::Atom(name, _)) => name, - _ => unreachable!() + _ => unreachable!(), }; let arity = match self.machine_st.store(self.machine_st.deref(arity)) { - Addr::Con(Constant::Integer(arity)) => - arity.to_usize().unwrap(), - _ => unreachable!() + Addr::Con(Constant::Integer(arity)) => arity.to_usize().unwrap(), + _ => unreachable!(), }; (name, arity) } - fn print_new_dynamic_clause(&self, addrs: VecDeque, name: ClauseName, arity: usize) - -> String - { + fn print_new_dynamic_clause( + &self, + addrs: VecDeque, + name: ClauseName, + arity: usize, + ) -> String { let mut output = PrinterOutputter::new(); output.append(format!(":- dynamic({}/{}). ", name.as_str(), arity).as_str()); @@ -71,8 +74,7 @@ impl Machine { output.result() } - fn abolish_dynamic_clause(&mut self, name: RegType, arity: RegType) - { + fn abolish_dynamic_clause(&mut self, name: RegType, arity: RegType) { let (name, arity) = self.get_predicate_key(name, arity); if let Some(idx) = self.indices.code_dir.get(&(name.clone(), arity)) { @@ -80,27 +82,26 @@ impl Machine { } self.indices.remove_code_index((name.clone(), arity)); - self.indices.remove_clause_subsection(name.owning_module(), name, arity); + self.indices + .remove_clause_subsection(name.owning_module(), name, arity); } - fn abolish_dynamic_clause_in_module(&mut self, name: RegType, arity: RegType, module: RegType) - { + fn abolish_dynamic_clause_in_module(&mut self, name: RegType, arity: RegType, module: RegType) { let (name, arity) = self.get_predicate_key(name, arity); let module_addr = self.machine_st[module].clone(); let module_name = match self.machine_st.store(self.machine_st.deref(module_addr)) { - Addr::Con(Constant::Atom(module, _)) => - match self.indices.modules.get_mut(&module) { - Some(ref mut module) => { - module.code_dir.remove(&(name.clone(), arity)); - module.module_decl.name.clone() - }, - _ => { - self.machine_st.fail = true; - return; - } - }, - _ => unreachable!() + Addr::Con(Constant::Atom(module, _)) => match self.indices.modules.get_mut(&module) { + Some(ref mut module) => { + module.code_dir.remove(&(name.clone(), arity)); + module.module_decl.name.clone() + } + _ => { + self.machine_st.fail = true; + return; + } + }, + _ => unreachable!(), }; if let Some(idx) = self.indices.code_dir.get(&(name.clone(), arity)) { @@ -110,30 +111,38 @@ impl Machine { } self.indices.remove_code_index((name.clone(), arity)); - self.indices.remove_clause_subsection(module_name, name, arity); + self.indices + .remove_clause_subsection(module_name, name, arity); } - fn handle_eval_result_from_dynamic_compile(&mut self, pred_str: String, name: ClauseName, - arity: usize, src: ClauseName) - { + fn handle_eval_result_from_dynamic_compile( + &mut self, + pred_str: String, + name: ClauseName, + arity: usize, + src: ClauseName, + ) { let machine_st = mem::replace(&mut self.machine_st, MachineState::new()); let result = self.compile_into_machine(parsing_stream(pred_str.as_bytes()), name, arity); self.machine_st = machine_st; if let EvalSession::Error(err) = result { - let h = self.machine_st.heap.h; + let h = self.machine_st.heap.h; let stub = MachineError::functor_stub(src, 1); - let err = MachineError::session_error(h, err); - let err = self.machine_st.error_form(err, stub); + let err = MachineError::session_error(h, err); + let err = self.machine_st.error_form(err, stub); self.machine_st.throw_exception(err); } } - fn recompile_dynamic_predicate_impl(&mut self, place: DynamicAssertPlace, name: ClauseName, - arity: usize) - { + fn recompile_dynamic_predicate_impl( + &mut self, + place: DynamicAssertPlace, + name: ClauseName, + arity: usize, + ) { let stub = MachineError::functor_stub(place.predicate_name(), 1); let pred_str = match self.machine_st.try_from_list(temp_v!(2), stub) { Ok(addrs) => { @@ -142,26 +151,23 @@ impl Machine { place.push_to_queue(&mut addrs, added_clause); self.print_new_dynamic_clause(addrs, name.clone(), arity) - }, - Err(err) => - return self.machine_st.throw_exception(err) + } + Err(err) => return self.machine_st.throw_exception(err), }; self.handle_eval_result_from_dynamic_compile(pred_str, name, arity, place.predicate_name()); } - fn set_module_atom_tbl(&mut self, module_addr: Addr, name: &mut ClauseName) -> bool - { + fn set_module_atom_tbl(&mut self, module_addr: Addr, name: &mut ClauseName) -> bool { let atom_tbl = match self.machine_st.store(self.machine_st.deref(module_addr)) { - Addr::Con(Constant::Atom(module, _)) => - match self.indices.modules.get(&module) { - Some(ref module) => module.atom_tbl.clone(), - None => { - self.machine_st.fail = true; - return false; - } - }, - _ => unreachable!() + Addr::Con(Constant::Atom(module, _)) => match self.indices.modules.get(&module) { + Some(ref module) => module.atom_tbl.clone(), + None => { + self.machine_st.fail = true; + return false; + } + }, + _ => unreachable!(), }; if let &mut ClauseName::User(ref mut rc) = name { @@ -171,8 +177,7 @@ impl Machine { true } - fn recompile_dynamic_predicate_in_module(&mut self, place: DynamicAssertPlace) - { + fn recompile_dynamic_predicate_in_module(&mut self, place: DynamicAssertPlace) { let (mut name, arity) = self.get_predicate_key(temp_v!(3), temp_v!(4)); let module_addr = self.machine_st[temp_v!(5)].clone(); @@ -181,18 +186,16 @@ impl Machine { } } - fn recompile_dynamic_predicate(&mut self, place: DynamicAssertPlace) - { + fn recompile_dynamic_predicate(&mut self, place: DynamicAssertPlace) { let (name, arity) = self.get_predicate_key(temp_v!(3), temp_v!(4)); self.recompile_dynamic_predicate_impl(place, name, arity); } - fn retract_from_dynamic_predicate_in_module(&mut self) - { + fn retract_from_dynamic_predicate_in_module(&mut self) { let index = self.machine_st[temp_v!(3)].clone(); let index = match self.machine_st.store(self.machine_st.deref(index)) { Addr::Con(Constant::Integer(n)) => n.to_usize().unwrap(), - _ => unreachable!() + _ => unreachable!(), }; let (mut name, arity) = self.get_predicate_key(temp_v!(1), temp_v!(2)); @@ -206,28 +209,29 @@ impl Machine { addrs.remove(index); if addrs.is_empty() { - self.abolish_dynamic_clause_in_module(temp_v!(1), temp_v!(2), - temp_v!(5)); + self.abolish_dynamic_clause_in_module(temp_v!(1), temp_v!(2), temp_v!(5)); return; } self.print_new_dynamic_clause(addrs, name.clone(), arity) - }, - Err(err) => - return self.machine_st.throw_exception(err) + } + Err(err) => return self.machine_st.throw_exception(err), }; - self.handle_eval_result_from_dynamic_compile(pred_str, name, arity, - clause_name!("retract")); + self.handle_eval_result_from_dynamic_compile( + pred_str, + name, + arity, + clause_name!("retract"), + ); } } - fn retract_from_dynamic_predicate(&mut self) - { + fn retract_from_dynamic_predicate(&mut self) { let index = self.machine_st[temp_v!(3)].clone(); let index = match self.machine_st.store(self.machine_st.deref(index)) { Addr::Con(Constant::Integer(n)) => n.to_usize().unwrap(), - _ => unreachable!() + _ => unreachable!(), }; let (name, arity) = self.get_predicate_key(temp_v!(1), temp_v!(2)); @@ -244,31 +248,36 @@ impl Machine { } self.print_new_dynamic_clause(addrs, name.clone(), arity) - }, - Err(err) => - return self.machine_st.throw_exception(err) + } + Err(err) => return self.machine_st.throw_exception(err), }; - self.handle_eval_result_from_dynamic_compile(pred_str, name, arity, - clause_name!("retract")); + self.handle_eval_result_from_dynamic_compile( + pred_str, + name, + arity, + clause_name!("retract"), + ); } - pub(super) - fn dynamic_transaction(&mut self, trans_type: DynamicTransactionType, p: LocalCodePtr) - { + pub(super) fn dynamic_transaction( + &mut self, + trans_type: DynamicTransactionType, + p: LocalCodePtr, + ) { match trans_type { - DynamicTransactionType::Abolish => - self.abolish_dynamic_clause(temp_v!(1), temp_v!(2)), - DynamicTransactionType::Assert(place) => - self.recompile_dynamic_predicate(place), - DynamicTransactionType::ModuleAbolish => - self.abolish_dynamic_clause_in_module(temp_v!(1), temp_v!(2), temp_v!(3)), - DynamicTransactionType::ModuleAssert(place) => - self.recompile_dynamic_predicate_in_module(place), - DynamicTransactionType::ModuleRetract => - self.retract_from_dynamic_predicate_in_module(), - DynamicTransactionType::Retract => - self.retract_from_dynamic_predicate() + DynamicTransactionType::Abolish => self.abolish_dynamic_clause(temp_v!(1), temp_v!(2)), + DynamicTransactionType::Assert(place) => self.recompile_dynamic_predicate(place), + DynamicTransactionType::ModuleAbolish => { + self.abolish_dynamic_clause_in_module(temp_v!(1), temp_v!(2), temp_v!(3)) + } + DynamicTransactionType::ModuleAssert(place) => { + self.recompile_dynamic_predicate_in_module(place) + } + DynamicTransactionType::ModuleRetract => { + self.retract_from_dynamic_predicate_in_module() + } + DynamicTransactionType::Retract => self.retract_from_dynamic_predicate(), } self.machine_st.p = CodePtr::Local(p); diff --git a/src/prolog/machine/heap.rs b/src/prolog/machine/heap.rs index ba0a9eac..c1c36681 100644 --- a/src/prolog/machine/heap.rs +++ b/src/prolog/machine/heap.rs @@ -12,8 +12,10 @@ pub struct Heap { impl Heap { pub fn with_capacity(cap: usize) -> Self { - Heap { heap: Vec::with_capacity(cap), - h: 0 } + Heap { + heap: Vec::with_capacity(cap), + h: 0, + } } #[inline] @@ -29,7 +31,7 @@ impl Heap { Heap { heap: mem::replace(&mut self.heap, vec![]), - h + h, } } @@ -61,13 +63,13 @@ impl Heap { self.h = 0; } - pub fn to_list>(&mut self, values: Iter) -> usize { + pub fn to_list>(&mut self, values: Iter) -> usize { let head_addr = self.h; for value in values { let h = self.h; - self.push(HeapCellValue::Addr(Addr::Lis(h+1))); + self.push(HeapCellValue::Addr(Addr::Lis(h + 1))); self.push(HeapCellValue::Addr(value)); } @@ -75,7 +77,7 @@ impl Heap { head_addr } - pub fn extend>(&mut self, iter: Iter) { + pub fn extend>(&mut self, iter: Iter) { for hcv in iter { self.push(hcv); } diff --git a/src/prolog/machine/machine_errors.rs b/src/prolog/machine/machine_errors.rs index b9f630e9..e8eb479b 100644 --- a/src/prolog/machine/machine_errors.rs +++ b/src/prolog/machine/machine_errors.rs @@ -10,63 +10,115 @@ pub(crate) type MachineStub = Vec; #[derive(Clone, Copy)] enum ErrorProvenance { Constructed, // if constructed, offset the addresses. - Received // otherwise, preserve the addresses. + Received, // otherwise, preserve the addresses. } pub(super) struct MachineError { stub: MachineStub, location: Option<(usize, usize)>, // line_num, col_num - from: ErrorProvenance + from: ErrorProvenance, } impl MachineError { pub(super) fn functor_stub(name: ClauseName, arity: usize) -> MachineStub { let name = HeapCellValue::Addr(Addr::Con(Constant::Atom(name, None))); - functor!("/", 2, [name, heap_integer!(Integer::from(arity))], SharedOpDesc::new(400, YFX)) + functor!( + "/", + 2, + [name, heap_integer!(Integer::from(arity))], + SharedOpDesc::new(400, YFX) + ) } pub(super) fn evaluation_error(eval_error: EvalError) -> Self { let stub = functor!("evaluation_error", 1, [heap_atom!(eval_error.as_str())]); - MachineError { stub, location: None, from: ErrorProvenance::Received } + MachineError { + stub, + location: None, + from: ErrorProvenance::Received, + } } pub(super) fn type_error(valid_type: ValidType, culprit: Addr) -> Self { - let stub = functor!("type_error", 2, [heap_atom!(valid_type.as_str()), - HeapCellValue::Addr(culprit)]); - - MachineError { stub, location: None, from: ErrorProvenance::Received } + let stub = functor!( + "type_error", + 2, + [ + heap_atom!(valid_type.as_str()), + HeapCellValue::Addr(culprit) + ] + ); + + MachineError { + stub, + location: None, + from: ErrorProvenance::Received, + } } - pub(super) - fn module_resolution_error(h: usize, mod_name: ClauseName, name: ClauseName, arity: usize) -> Self - { + pub(super) fn module_resolution_error( + h: usize, + mod_name: ClauseName, + name: ClauseName, + arity: usize, + ) -> Self { let mod_name = HeapCellValue::Addr(Addr::Con(Constant::Atom(mod_name, None))); let name = HeapCellValue::Addr(Addr::Con(Constant::Atom(name, None))); - let mut stub = functor!("evaluation_error", 1, [HeapCellValue::Addr(Addr::HeapCell(h + 2))]); - - stub.append(&mut functor!("/", 2, [HeapCellValue::Addr(Addr::HeapCell(h + 2 + 3)), - heap_integer!(Integer::from(arity))], - SharedOpDesc::new(400, YFX))); - stub.append(&mut functor!(":", 2, [mod_name, name], SharedOpDesc::new(600, XFY))); - - MachineError { stub, location: None, from: ErrorProvenance::Constructed } + let mut stub = functor!( + "evaluation_error", + 1, + [HeapCellValue::Addr(Addr::HeapCell(h + 2))] + ); + + stub.append(&mut functor!( + "/", + 2, + [ + HeapCellValue::Addr(Addr::HeapCell(h + 2 + 3)), + heap_integer!(Integer::from(arity)) + ], + SharedOpDesc::new(400, YFX) + )); + stub.append(&mut functor!( + ":", + 2, + [mod_name, name], + SharedOpDesc::new(600, XFY) + )); + + MachineError { + stub, + location: None, + from: ErrorProvenance::Constructed, + } } - pub(super) fn existence_error(h: usize, err: ExistenceError) -> Self - { + pub(super) fn existence_error(h: usize, err: ExistenceError) -> Self { match err { ExistenceError::Procedure(name, arity) => { - let mut stub = functor!("existence_error", 2, [heap_atom!("procedure"), heap_str!(3 + h)]); + let mut stub = functor!( + "existence_error", + 2, + [heap_atom!("procedure"), heap_str!(3 + h)] + ); stub.append(&mut Self::functor_stub(name, arity)); - MachineError { stub, location: None, from: ErrorProvenance::Constructed } - }, + MachineError { + stub, + location: None, + from: ErrorProvenance::Constructed, + } + } ExistenceError::Module(name) => { let name = HeapCellValue::Addr(Addr::Con(Constant::Atom(name, None))); let stub = functor!("existence_error", 2, [heap_atom!("module"), name]); - MachineError { stub, location: None, from: ErrorProvenance::Constructed } + MachineError { + stub, + location: None, + from: ErrorProvenance::Constructed, + } } } } @@ -75,31 +127,37 @@ impl MachineError { match err { SessionError::ParserError(err) => Self::syntax_error(h, err), SessionError::CannotOverwriteBuiltIn(pred_str) - | SessionError::CannotOverwriteImport(pred_str) => - Self::permission_error(PermissionError::Modify, "private_procedure", pred_str), - SessionError::InvalidFileName(filename) => - Self::existence_error(h, ExistenceError::Module(filename)), - SessionError::ModuleDoesNotContainExport => - Self::permission_error(PermissionError::Access, - "private_procedure", - clause_name!("module_does_not_contain_claimed_export")), - SessionError::ModuleNotFound => - Self::permission_error(PermissionError::Access, - "private_procedure", - clause_name!("module_does_not_exist")), - SessionError::NoModuleDeclaration(name) => - Self::existence_error(h, ExistenceError::Module(name)), - SessionError::OpIsInfixAndPostFix(op) => - Self::permission_error(PermissionError::Create, - "operator", - op), - _ => unreachable!() + | SessionError::CannotOverwriteImport(pred_str) => { + Self::permission_error(PermissionError::Modify, "private_procedure", pred_str) + } + SessionError::InvalidFileName(filename) => { + Self::existence_error(h, ExistenceError::Module(filename)) + } + SessionError::ModuleDoesNotContainExport => Self::permission_error( + PermissionError::Access, + "private_procedure", + clause_name!("module_does_not_contain_claimed_export"), + ), + SessionError::ModuleNotFound => Self::permission_error( + PermissionError::Access, + "private_procedure", + clause_name!("module_does_not_exist"), + ), + SessionError::NoModuleDeclaration(name) => { + Self::existence_error(h, ExistenceError::Module(name)) + } + SessionError::OpIsInfixAndPostFix(op) => { + Self::permission_error(PermissionError::Create, "operator", op) + } + _ => unreachable!(), } } - pub(super) - fn permission_error(err: PermissionError, index_str: &'static str, pred_str: ClauseName) -> Self - { + pub(super) fn permission_error( + err: PermissionError, + index_str: &'static str, + pred_str: ClauseName, + ) -> Self { let pred_str = HeapCellValue::Addr(Addr::Con(Constant::Atom(pred_str, None))); let err = vec![heap_atom!(err.as_str()), heap_atom!(index_str), pred_str]; @@ -107,22 +165,33 @@ impl MachineError { stub.extend(err.into_iter()); - MachineError { stub, location: None, from: ErrorProvenance::Constructed } + MachineError { + stub, + location: None, + from: ErrorProvenance::Constructed, + } } fn arithmetic_error(h: usize, err: ArithmeticError) -> Self { match err { - ArithmeticError::UninstantiatedVar => - Self::instantiation_error(), + ArithmeticError::UninstantiatedVar => Self::instantiation_error(), ArithmeticError::NonEvaluableFunctor(name, arity) => { let name = HeapCellValue::Addr(Addr::Con(name)); - let culprit = functor!("/", 2, [name, heap_integer!(Integer::from(arity))], - SharedOpDesc::new(400, YFX)); - - let mut stub = Self::type_error(ValidType::Evaluable, Addr::HeapCell(3+h)).stub; + let culprit = functor!( + "/", + 2, + [name, heap_integer!(Integer::from(arity))], + SharedOpDesc::new(400, YFX) + ); + + let mut stub = Self::type_error(ValidType::Evaluable, Addr::HeapCell(3 + h)).stub; stub.extend(culprit.into_iter()); - MachineError { stub, location: None, from: ErrorProvenance::Constructed } + MachineError { + stub, + location: None, + from: ErrorProvenance::Constructed, + } } } } @@ -143,36 +212,53 @@ impl MachineError { stub.extend(err.into_iter()); - MachineError { stub, location, from: ErrorProvenance::Constructed } + MachineError { + stub, + location, + from: ErrorProvenance::Constructed, + } } pub(super) fn domain_error(error: DomainError, culprit: Addr) -> Self { - let stub = functor!("domain_error", 2, [heap_atom!(error.as_str()), - HeapCellValue::Addr(culprit)]); - MachineError { stub, location: None, from: ErrorProvenance::Received } + let stub = functor!( + "domain_error", + 2, + [heap_atom!(error.as_str()), HeapCellValue::Addr(culprit)] + ); + MachineError { + stub, + location: None, + from: ErrorProvenance::Received, + } } pub(super) fn instantiation_error() -> Self { let stub = functor!("instantiation_error"); - MachineError { stub, location: None, from: ErrorProvenance::Received } + MachineError { + stub, + location: None, + from: ErrorProvenance::Received, + } } pub(super) fn representation_error(flag: RepFlag) -> Self { let stub = functor!("representation_error", 1, [heap_atom!(flag.as_str())]); - MachineError { stub, location: None, from: ErrorProvenance::Received } + MachineError { + stub, + location: None, + from: ErrorProvenance::Received, + } } - fn into_iter(self, offset: usize) -> Box> { + fn into_iter(self, offset: usize) -> Box> { match self.from { - ErrorProvenance::Constructed => - Box::new(self.stub.into_iter().map(move |hcv| { - match hcv { - HeapCellValue::Addr(addr) => HeapCellValue::Addr(addr + offset), - hcv => hcv - } - })), - ErrorProvenance::Received => - Box::new(self.stub.into_iter()) + ErrorProvenance::Constructed => { + Box::new(self.stub.into_iter().map(move |hcv| match hcv { + HeapCellValue::Addr(addr) => HeapCellValue::Addr(addr + offset), + hcv => hcv, + })) + } + ErrorProvenance::Received => Box::new(self.stub.into_iter()), } } @@ -193,7 +279,7 @@ impl PermissionError { match self { PermissionError::Access => "access", PermissionError::Create => "create", - PermissionError::Modify => "modify" + PermissionError::Modify => "modify", } } } @@ -203,21 +289,21 @@ impl PermissionError { pub enum ValidType { Atom, Atomic, -// Boolean, -// Byte, + // Boolean, + // Byte, Callable, Character, Compound, Evaluable, Float, -// InByte, -// InCharacter, + // InByte, + // InCharacter, Integer, List, -// Number, + // Number, Pair, -// PredicateIndicator, -// Variable + // PredicateIndicator, + // Variable } impl ValidType { @@ -225,34 +311,34 @@ impl ValidType { match self { ValidType::Atom => "atom", ValidType::Atomic => "atomic", -// ValidType::Boolean => "boolean", -// ValidType::Byte => "byte", + // ValidType::Boolean => "boolean", + // ValidType::Byte => "byte", ValidType::Callable => "callable", ValidType::Character => "character", ValidType::Compound => "compound", ValidType::Evaluable => "evaluable", ValidType::Float => "float", -// ValidType::InByte => "in_byte", -// ValidType::InCharacter => "in_character", + // ValidType::InByte => "in_byte", + // ValidType::InCharacter => "in_character", ValidType::Integer => "integer", ValidType::List => "list", -// ValidType::Number => "number", + // ValidType::Number => "number", ValidType::Pair => "pair", -// ValidType::PredicateIndicator => "predicate_indicator", -// ValidType::Variable => "variable" + // ValidType::PredicateIndicator => "predicate_indicator", + // ValidType::Variable => "variable" } } } #[derive(Clone, Copy)] pub enum DomainError { - NotLessThanZero + NotLessThanZero, } impl DomainError { pub fn as_str(self) -> &'static str { match self { - DomainError::NotLessThanZero => "not_less_than_zero" + DomainError::NotLessThanZero => "not_less_than_zero", } } } @@ -262,10 +348,10 @@ impl DomainError { pub enum RepFlag { Character, CharacterCode, -// InCharacterCode, + // InCharacterCode, MaxArity, -// MaxInteger, -// MinInteger + // MaxInteger, + // MinInteger } impl RepFlag { @@ -273,10 +359,10 @@ impl RepFlag { match self { RepFlag::Character => "character", RepFlag::CharacterCode => "character_code", -// RepFlag::InCharacterCode => "in_character_code", + // RepFlag::InCharacterCode => "in_character_code", RepFlag::MaxArity => "max_arity", -// RepFlag::MaxInteger => "max_integer", -// RepFlag::MinInteger => "min_integer" + // RepFlag::MaxInteger => "max_integer", + // RepFlag::MinInteger => "min_integer" } } } @@ -286,7 +372,7 @@ impl RepFlag { pub enum EvalError { FloatOverflow, Undefined, -// Underflow, + // Underflow, ZeroDivisor, } @@ -295,7 +381,7 @@ impl EvalError { match self { EvalError::FloatOverflow => "float_overflow", EvalError::Undefined => "undefined", -// EvalError::FloatUnderflow => "underflow", + // EvalError::FloatUnderflow => "underflow", EvalError::ZeroDivisor => "zero_divisor", } } @@ -306,30 +392,33 @@ pub(super) enum CycleSearchResult { EmptyList, NotList, PartialList(usize, usize), // the list length (up to max), and an offset into the heap. - ProperList(usize), // the list length. + ProperList(usize), // the list length. String(usize, StringList), // the number of elements iterated, the string tail. - UntouchedList(usize) // the address of an uniterated Addr::Lis(address). + UntouchedList(usize), // the address of an uniterated Addr::Lis(address). } impl MachineState { // see 8.4.3 of Draft Technical Corrigendum 2. pub(super) fn check_sort_errors(&self) -> CallResult { - let stub = MachineError::functor_stub(clause_name!("sort"), 2); - let list = self.store(self.deref(self[temp_v!(1)].clone())); + let stub = MachineError::functor_stub(clause_name!("sort"), 2); + let list = self.store(self.deref(self[temp_v!(1)].clone())); let sorted = self.store(self.deref(self[temp_v!(2)].clone())); match self.detect_cycles(list.clone()) { - CycleSearchResult::PartialList(..) => - return Err(self.error_form(MachineError::instantiation_error(), stub)), - CycleSearchResult::NotList => - return Err(self.error_form(MachineError::type_error(ValidType::List, list), stub)), + CycleSearchResult::PartialList(..) => { + return Err(self.error_form(MachineError::instantiation_error(), stub)) + } + CycleSearchResult::NotList => { + return Err(self.error_form(MachineError::type_error(ValidType::List, list), stub)) + } _ => {} }; match self.detect_cycles(sorted.clone()) { - CycleSearchResult::NotList if !sorted.is_ref() => - Err(self.error_form(MachineError::type_error(ValidType::List, sorted), stub)), - _ => Ok(()) + CycleSearchResult::NotList if !sorted.is_ref() => { + Err(self.error_form(MachineError::type_error(ValidType::List, sorted), stub)) + } + _ => Ok(()), } } @@ -337,8 +426,9 @@ impl MachineState { let stub = MachineError::functor_stub(clause_name!("keysort"), 2); match self.detect_cycles(list.clone()) { - CycleSearchResult::NotList if !list.is_ref() => - Err(self.error_form(MachineError::type_error(ValidType::List, list), stub)), + CycleSearchResult::NotList if !list.is_ref() => { + Err(self.error_form(MachineError::type_error(ValidType::List, list), stub)) + } _ => { let mut addr = list; @@ -349,12 +439,18 @@ impl MachineState { match self.heap[new_l].clone() { HeapCellValue::Addr(Addr::Str(l)) => new_l = l, HeapCellValue::NamedStr(2, ref name, Some(_)) - if name.as_str() == "-" => break, + if name.as_str() == "-" => + { + break + } HeapCellValue::Addr(Addr::HeapCell(_)) => break, HeapCellValue::Addr(Addr::StackCell(..)) => break, - _ => return Err(self.error_form(MachineError::type_error(ValidType::Pair, - Addr::HeapCell(l)), - stub)) + _ => { + return Err(self.error_form( + MachineError::type_error(ValidType::Pair, Addr::HeapCell(l)), + stub, + )) + } }; } @@ -368,16 +464,18 @@ impl MachineState { // see 8.4.4 of Draft Technical Corrigendum 2. pub(super) fn check_keysort_errors(&self) -> CallResult { - let stub = MachineError::functor_stub(clause_name!("keysort"), 2); - let pairs = self.store(self.deref(self[temp_v!(1)].clone())); + let stub = MachineError::functor_stub(clause_name!("keysort"), 2); + let pairs = self.store(self.deref(self[temp_v!(1)].clone())); let sorted = self.store(self.deref(self[temp_v!(2)].clone())); match self.detect_cycles(pairs.clone()) { - CycleSearchResult::PartialList(..) => - Err(self.error_form(MachineError::instantiation_error(), stub)), - CycleSearchResult::NotList => - Err(self.error_form(MachineError::type_error(ValidType::List, pairs), stub)), - _ => Ok(()) + CycleSearchResult::PartialList(..) => { + Err(self.error_form(MachineError::instantiation_error(), stub)) + } + CycleSearchResult::NotList => { + Err(self.error_form(MachineError::type_error(ValidType::List, pairs), stub)) + } + _ => Ok(()), }?; self.check_for_list_pairs(sorted) @@ -388,18 +486,25 @@ impl MachineState { let err_len = err.len(); let h = self.heap.h; - let mut stub = vec![HeapCellValue::NamedStr(2, clause_name!("error"), None), - HeapCellValue::Addr(Addr::HeapCell(h + 3)), - HeapCellValue::Addr(Addr::HeapCell(h + 3 + err_len))]; + let mut stub = vec![ + HeapCellValue::NamedStr(2, clause_name!("error"), None), + HeapCellValue::Addr(Addr::HeapCell(h + 3)), + HeapCellValue::Addr(Addr::HeapCell(h + 3 + err_len)), + ]; stub.extend(err.into_iter(3)); if let Some((line_num, _)) = location { let colon_op_desc = Some(SharedOpDesc::new(600, XFY)); - stub.extend(vec![HeapCellValue::NamedStr(2, clause_name!(":"), colon_op_desc), - HeapCellValue::Addr(Addr::HeapCell(h + 6 + err_len)), - heap_integer!(Integer::from(line_num))].into_iter()); + stub.extend( + vec![ + HeapCellValue::NamedStr(2, clause_name!(":"), colon_op_desc), + HeapCellValue::Addr(Addr::HeapCell(h + 6 + err_len)), + heap_integer!(Integer::from(line_num)), + ] + .into_iter(), + ); } stub.extend(src.into_iter()); @@ -423,7 +528,7 @@ impl MachineState { pub enum ExistenceError { Module(ClauseName), - Procedure(ClauseName, usize) + Procedure(ClauseName, usize), } pub enum SessionError { @@ -436,7 +541,7 @@ pub enum SessionError { NoModuleDeclaration(ClauseName), OpIsInfixAndPostFix(ClauseName), ParserError(ParserError), - UserPrompt + UserPrompt, } pub enum EvalSession { diff --git a/src/prolog/machine/machine_indices.rs b/src/prolog/machine/machine_indices.rs index f1b4b39c..cb2586a6 100644 --- a/src/prolog/machine/machine_indices.rs +++ b/src/prolog/machine/machine_indices.rs @@ -22,7 +22,13 @@ pub type OssifiedOpDir = BTreeMap; #[derive(Clone, PartialEq, Eq, Hash)] pub enum DBRef { NamedPred(ClauseName, usize, Option), - Op(usize, Specifier, ClauseName, Rc, SharedOpDesc) + Op( + usize, + Specifier, + ClauseName, + Rc, + SharedOpDesc, + ), } #[derive(Clone, PartialEq, Eq, Hash)] @@ -33,22 +39,22 @@ pub enum Addr { Lis(usize), HeapCell(usize), StackCell(usize, usize), - Str(usize) + Str(usize), } #[derive(Clone, Copy, Hash, Eq, PartialEq)] pub enum Ref { AttrVar(usize), HeapCell(usize), - StackCell(usize, usize) + StackCell(usize, usize), } impl Ref { pub fn as_addr(self) -> Addr { match self { - Ref::AttrVar(h) => Addr::AttrVar(h), - Ref::HeapCell(h) => Addr::HeapCell(h), - Ref::StackCell(fr, sc) => Addr::StackCell(fr, sc) + Ref::AttrVar(h) => Addr::AttrVar(h), + Ref::HeapCell(h) => Addr::HeapCell(h), + Ref::StackCell(fr, sc) => Addr::StackCell(fr, sc), } } } @@ -63,25 +69,23 @@ impl PartialEq for Addr { impl PartialOrd for Addr { fn partial_cmp(&self, r: &Ref) -> Option { match self { - &Addr::StackCell(fr, sc) => - match *r { - Ref::AttrVar(_) | Ref::HeapCell(_) => - Some(Ordering::Greater), - Ref::StackCell(fr1, sc1) => - if fr1 < fr || (fr1 == fr && sc1 < sc) { - Some(Ordering::Greater) - } else if fr1 == fr && sc1 == sc { - Some(Ordering::Equal) - } else { - Some(Ordering::Less) - } - }, - &Addr::HeapCell(h) | &Addr::AttrVar(h) => - match r { - &Ref::StackCell(..) => Some(Ordering::Less), - &Ref::AttrVar(h1) | &Ref::HeapCell(h1) => h.partial_cmp(&h1) - }, - _ => None + &Addr::StackCell(fr, sc) => match *r { + Ref::AttrVar(_) | Ref::HeapCell(_) => Some(Ordering::Greater), + Ref::StackCell(fr1, sc1) => { + if fr1 < fr || (fr1 == fr && sc1 < sc) { + Some(Ordering::Greater) + } else if fr1 == fr && sc1 == sc { + Some(Ordering::Equal) + } else { + Some(Ordering::Less) + } + } + }, + &Addr::HeapCell(h) | &Addr::AttrVar(h) => match r { + &Ref::StackCell(..) => Some(Ordering::Less), + &Ref::AttrVar(h1) | &Ref::HeapCell(h1) => h.partial_cmp(&h1), + }, + _ => None, } } } @@ -90,7 +94,7 @@ impl Addr { pub fn is_ref(&self) -> bool { match self { &Addr::AttrVar(_) | &Addr::HeapCell(_) | &Addr::StackCell(_, _) => true, - _ => false + _ => false, } } @@ -99,14 +103,14 @@ impl Addr { &Addr::AttrVar(h) => Some(Ref::AttrVar(h)), &Addr::HeapCell(h) => Some(Ref::HeapCell(h)), &Addr::StackCell(fr, sc) => Some(Ref::StackCell(fr, sc)), - _ => None + _ => None, } } pub fn is_protected(&self, e: usize) -> bool { match self { &Addr::StackCell(addr, _) if addr >= e => false, - _ => true + _ => true, } } } @@ -120,7 +124,7 @@ impl Add for Addr { Addr::AttrVar(h) => Addr::AttrVar(h + rhs), Addr::HeapCell(h) => Addr::HeapCell(h + rhs), Addr::Str(s) => Addr::Str(s + rhs), - _ => self + _ => self, } } } @@ -135,7 +139,7 @@ impl Sub for Addr { Addr::AttrVar(h) => Addr::AttrVar(h + rhs.abs() as usize), Addr::HeapCell(h) => Addr::HeapCell(h + rhs.abs() as usize), Addr::Str(s) => Addr::Str(s + rhs.abs() as usize), - _ => self + _ => self, } } else { self.sub(rhs as usize) @@ -152,7 +156,7 @@ impl Sub for Addr { Addr::AttrVar(h) => Addr::AttrVar(h - rhs), Addr::HeapCell(h) => Addr::HeapCell(h - rhs), Addr::Str(s) => Addr::Str(s - rhs), - _ => self + _ => self, } } } @@ -166,9 +170,9 @@ impl SubAssign for Addr { impl From for Addr { fn from(r: Ref) -> Self { match r { - Ref::AttrVar(h) => Addr::AttrVar(h), - Ref::HeapCell(h) => Addr::HeapCell(h), - Ref::StackCell(fr, sc) => Addr::StackCell(fr, sc) + Ref::AttrVar(h) => Addr::AttrVar(h), + Ref::HeapCell(h) => Addr::HeapCell(h), + Ref::StackCell(fr, sc) => Addr::StackCell(fr, sc), } } } @@ -176,7 +180,7 @@ impl From for Addr { #[derive(Clone)] pub enum TrailRef { Ref(Ref), - AttrVarLink(usize, Addr) + AttrVarLink(usize, Addr), } impl From for TrailRef { @@ -195,7 +199,7 @@ impl HeapCellValue { pub fn as_addr(&self, focus: usize) -> Addr { match self { &HeapCellValue::Addr(ref a) => a.clone(), - &HeapCellValue::NamedStr(_, _, _) => Addr::Str(focus) + &HeapCellValue::NamedStr(_, _, _) => Addr::Str(focus), } } } @@ -229,14 +233,17 @@ impl CodeIndex { pub fn local(&self) -> Option { match self.0.borrow().0 { IndexPtr::Index(i) => Some(i), - _ => None + _ => None, } } } impl Default for CodeIndex { fn default() -> Self { - CodeIndex(Rc::new(RefCell::new((IndexPtr::Undefined, clause_name!(""))))) + CodeIndex(Rc::new(RefCell::new(( + IndexPtr::Undefined, + clause_name!(""), + )))) } } @@ -248,23 +255,24 @@ impl From<(usize, ClauseName)> for CodeIndex { #[derive(Clone, Copy, PartialEq)] pub enum DynamicAssertPlace { - Back, Front + Back, + Front, } impl DynamicAssertPlace { #[inline] pub fn predicate_name(self) -> ClauseName { match self { - DynamicAssertPlace::Back => clause_name!("assertz"), - DynamicAssertPlace::Front => clause_name!("asserta") + DynamicAssertPlace::Back => clause_name!("assertz"), + DynamicAssertPlace::Front => clause_name!("asserta"), } } #[inline] pub fn push_to_queue(self, addrs: &mut VecDeque, new_addr: Addr) { match self { - DynamicAssertPlace::Back => addrs.push_back(new_addr), - DynamicAssertPlace::Front => addrs.push_front(new_addr) + DynamicAssertPlace::Back => addrs.push_back(new_addr), + DynamicAssertPlace::Front => addrs.push_front(new_addr), } } } @@ -276,34 +284,33 @@ pub enum DynamicTransactionType { ModuleAbolish, ModuleAssert(DynamicAssertPlace), ModuleRetract, - Retract // dynamic index of the clause to remove. + Retract, // dynamic index of the clause to remove. } #[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq)] pub enum REPLCodePtr { CompileBatch, - SubmitQueryAndPrintResults + SubmitQueryAndPrintResults, } #[derive(Clone, PartialEq)] pub enum CodePtr { BuiltInClause(BuiltInClauseType, LocalCodePtr), // local is the successor call. - CallN(usize, LocalCodePtr), // arity, local. + CallN(usize, LocalCodePtr), // arity, local. Local(LocalCodePtr), DynamicTransaction(DynamicTransactionType, LocalCodePtr), // the type of transaction, the return pointer. - REPL(REPLCodePtr, LocalCodePtr), // the REPL code, the return pointer. - VerifyAttrInterrupt(usize) // location of the verify attribute interrupt code in the CodeDir. + REPL(REPLCodePtr, LocalCodePtr), // the REPL code, the return pointer. + VerifyAttrInterrupt(usize), // location of the verify attribute interrupt code in the CodeDir. } impl CodePtr { pub fn local(&self) -> LocalCodePtr { match self { &CodePtr::BuiltInClause(_, ref local) - | &CodePtr::CallN(_, ref local) - | &CodePtr::Local(ref local) => local.clone(), + | &CodePtr::CallN(_, ref local) + | &CodePtr::Local(ref local) => local.clone(), &CodePtr::VerifyAttrInterrupt(p) => LocalCodePtr::DirEntry(p), - &CodePtr::REPL(_, p) - | &CodePtr::DynamicTransaction(_, p) => p + &CodePtr::REPL(_, p) | &CodePtr::DynamicTransaction(_, p) => p, } } } @@ -314,7 +321,7 @@ pub enum LocalCodePtr { InSituDirEntry(usize), TopLevel(usize, usize), // chunk_num, offset. UserGoalExpansion(usize), - UserTermExpansion(usize) + UserTermExpansion(usize), } impl LocalCodePtr { @@ -330,7 +337,7 @@ impl PartialOrd for CodePtr { fn partial_cmp(&self, other: &CodePtr) -> Option { match (self, other) { (&CodePtr::Local(ref l1), &CodePtr::Local(ref l2)) => l1.partial_cmp(l2), - _ => Some(Ordering::Greater) + _ => Some(Ordering::Greater), } } } @@ -339,14 +346,14 @@ impl PartialOrd for LocalCodePtr { fn partial_cmp(&self, other: &LocalCodePtr) -> Option { match (self, other) { (&LocalCodePtr::InSituDirEntry(p1), &LocalCodePtr::InSituDirEntry(ref p2)) - | (&LocalCodePtr::DirEntry(p1), &LocalCodePtr::DirEntry(ref p2)) - | (&LocalCodePtr::UserTermExpansion(p1), &LocalCodePtr::UserTermExpansion(ref p2)) - | (&LocalCodePtr::UserGoalExpansion(p1), &LocalCodePtr::UserGoalExpansion(ref p2)) - | (&LocalCodePtr::TopLevel(_, p1), &LocalCodePtr::TopLevel(_, ref p2)) => - p1.partial_cmp(p2), - (_, &LocalCodePtr::TopLevel(_, _)) => - Some(Ordering::Less), - _ => Some(Ordering::Greater) + | (&LocalCodePtr::DirEntry(p1), &LocalCodePtr::DirEntry(ref p2)) + | (&LocalCodePtr::UserTermExpansion(p1), &LocalCodePtr::UserTermExpansion(ref p2)) + | (&LocalCodePtr::UserGoalExpansion(p1), &LocalCodePtr::UserGoalExpansion(ref p2)) + | (&LocalCodePtr::TopLevel(_, p1), &LocalCodePtr::TopLevel(_, ref p2)) => { + p1.partial_cmp(p2) + } + (_, &LocalCodePtr::TopLevel(_, _)) => Some(Ordering::Less), + _ => Some(Ordering::Greater), } } } @@ -381,10 +388,10 @@ impl AddAssign for LocalCodePtr { fn add_assign(&mut self, rhs: usize) { match self { &mut LocalCodePtr::InSituDirEntry(ref mut p) - | &mut LocalCodePtr::UserGoalExpansion(ref mut p) - | &mut LocalCodePtr::UserTermExpansion(ref mut p) - | &mut LocalCodePtr::DirEntry(ref mut p) - | &mut LocalCodePtr::TopLevel(_, ref mut p) => *p += rhs + | &mut LocalCodePtr::UserGoalExpansion(ref mut p) + | &mut LocalCodePtr::UserTermExpansion(ref mut p) + | &mut LocalCodePtr::DirEntry(ref mut p) + | &mut LocalCodePtr::TopLevel(_, ref mut p) => *p += rhs, } } } @@ -395,10 +402,12 @@ impl Add for CodePtr { fn add(self, rhs: usize) -> Self::Output { match self { p @ CodePtr::REPL(..) - | p @ CodePtr::VerifyAttrInterrupt(_) - | p @ CodePtr::DynamicTransaction(..) => p, + | p @ CodePtr::VerifyAttrInterrupt(_) + | p @ CodePtr::DynamicTransaction(..) => p, CodePtr::Local(local) => CodePtr::Local(local + rhs), - CodePtr::CallN(_, local) | CodePtr::BuiltInClause(_, local) => CodePtr::Local(local + rhs) + CodePtr::CallN(_, local) | CodePtr::BuiltInClause(_, local) => { + CodePtr::Local(local + rhs) + } } } } @@ -406,14 +415,14 @@ impl Add for CodePtr { impl AddAssign for CodePtr { fn add_assign(&mut self, rhs: usize) { match self { - &mut CodePtr::VerifyAttrInterrupt(_) => {}, + &mut CodePtr::VerifyAttrInterrupt(_) => {} &mut CodePtr::Local(ref mut local) => *local += rhs, - _ => *self = CodePtr::Local(self.local() + rhs) + _ => *self = CodePtr::Local(self.local() + rhs), } } } -pub type HeapVarDict = IndexMap, Addr>; +pub type HeapVarDict = IndexMap, Addr>; pub type AllocVarDict = IndexMap, VarData>; #[derive(Clone)] @@ -423,11 +432,13 @@ pub struct DynamicPredicateInfo { impl Default for DynamicPredicateInfo { fn default() -> Self { - DynamicPredicateInfo { clauses_subsection_p: 0 } + DynamicPredicateInfo { + clauses_subsection_p: 0, + } } } -pub type InSituCodeDir = IndexMap; +pub type InSituCodeDir = IndexMap; // key type: module name, predicate indicator. pub type DynamicCodeDir = IndexMap<(ClauseName, ClauseName, usize), DynamicPredicateInfo>; @@ -444,42 +455,41 @@ pub struct IndexStore { } impl IndexStore { - pub fn predicate_exists(&self, name: ClauseName, module: ClauseName, arity: usize, - op_spec: Option) - -> bool - { + pub fn predicate_exists( + &self, + name: ClauseName, + module: ClauseName, + arity: usize, + op_spec: Option, + ) -> bool { match self.modules.get(&module) { - Some(module) => - match ClauseType::from(name, arity, op_spec) { - ClauseType::Named(name, arity, _) => - module.code_dir.contains_key(&(name, arity)), - ClauseType::Op(name, spec, ..) => - module.code_dir.contains_key(&(name, spec.arity())), - _ => - true - }, - None => - match ClauseType::from(name, arity, op_spec) { - ClauseType::Named(name, arity, _) => - self.code_dir.contains_key(&(name, arity)), - ClauseType::Op(name, spec, ..) => - self.code_dir.contains_key(&(name, spec.arity())), - _ => - true + Some(module) => match ClauseType::from(name, arity, op_spec) { + ClauseType::Named(name, arity, _) => module.code_dir.contains_key(&(name, arity)), + ClauseType::Op(name, spec, ..) => { + module.code_dir.contains_key(&(name, spec.arity())) } + _ => true, + }, + None => match ClauseType::from(name, arity, op_spec) { + ClauseType::Named(name, arity, _) => self.code_dir.contains_key(&(name, arity)), + ClauseType::Op(name, spec, ..) => self.code_dir.contains_key(&(name, spec.arity())), + _ => true, + }, } } #[inline] - pub fn remove_clause_subsection(&mut self, module: ClauseName, name: ClauseName, arity: usize) - { + pub fn remove_clause_subsection(&mut self, module: ClauseName, name: ClauseName, arity: usize) { self.dynamic_code_dir.remove(&(module, name, arity)); } #[inline] - pub fn get_clause_subsection(&self, module: ClauseName, name: ClauseName, arity: usize) - -> Option - { + pub fn get_clause_subsection( + &self, + module: ClauseName, + name: ClauseName, + arity: usize, + ) -> Option { self.dynamic_code_dir.get(&(module, name, arity)).cloned() } @@ -503,7 +513,7 @@ impl IndexStore { in_situ_code_dir: InSituCodeDir::new(), op_dir: default_op_dir(), modules: ModuleDir::new(), -// parsing_stream: readline::parsing_stream(String::new()) + // parsing_stream: readline::parsing_stream(String::new()) } } @@ -518,21 +528,30 @@ impl IndexStore { } #[inline] - fn get_internal(&self, name: ClauseName, arity: usize, in_mod: ClauseName) -> Option - { - self.modules.get(&in_mod) + fn get_internal( + &self, + name: ClauseName, + arity: usize, + in_mod: ClauseName, + ) -> Option { + self.modules + .get(&in_mod) .and_then(|ref module| module.code_dir.get(&(name, arity))) .cloned() } pub(super) fn get_cleaner_sites(&self) -> (usize, usize) { - let r_w_h = clause_name!("run_cleaners_with_handling"); + let r_w_h = clause_name!("run_cleaners_with_handling"); let r_wo_h = clause_name!("run_cleaners_without_handling"); let non_iso = clause_name!("non_iso"); - let r_w_h = self.get_internal(r_w_h, 0, non_iso.clone()).and_then(|item| item.local()); - let r_wo_h = self.get_internal(r_wo_h, 1, non_iso).and_then(|item| item.local()); + let r_w_h = self + .get_internal(r_w_h, 0, non_iso.clone()) + .and_then(|item| item.local()); + let r_wo_h = self + .get_internal(r_wo_h, 1, non_iso) + .and_then(|item| item.local()); if let Some(r_w_h) = r_w_h { if let Some(r_wo_h) = r_wo_h { @@ -552,36 +571,38 @@ pub enum CompileTimeHook { GoalExpansion, TermExpansion, UserGoalExpansion, - UserTermExpansion + UserTermExpansion, } impl CompileTimeHook { pub fn name(self) -> ClauseName { match self { - CompileTimeHook::UserGoalExpansion - | CompileTimeHook::GoalExpansion => clause_name!("goal_expansion"), - CompileTimeHook::UserTermExpansion - | CompileTimeHook::TermExpansion => clause_name!("term_expansion") + CompileTimeHook::UserGoalExpansion | CompileTimeHook::GoalExpansion => { + clause_name!("goal_expansion") + } + CompileTimeHook::UserTermExpansion | CompileTimeHook::TermExpansion => { + clause_name!("term_expansion") + } } } #[inline] pub fn arity(self) -> usize { match self { - CompileTimeHook::UserGoalExpansion - | CompileTimeHook::GoalExpansion => 2, - CompileTimeHook::UserTermExpansion - | CompileTimeHook::TermExpansion => 2 + CompileTimeHook::UserGoalExpansion | CompileTimeHook::GoalExpansion => 2, + CompileTimeHook::UserTermExpansion | CompileTimeHook::TermExpansion => 2, } } #[inline] pub fn user_scope(self) -> Self { match self { - CompileTimeHook::UserGoalExpansion | CompileTimeHook::GoalExpansion => - CompileTimeHook::UserGoalExpansion, - CompileTimeHook::UserTermExpansion | CompileTimeHook::TermExpansion => - CompileTimeHook::UserTermExpansion, + CompileTimeHook::UserGoalExpansion | CompileTimeHook::GoalExpansion => { + CompileTimeHook::UserGoalExpansion + } + CompileTimeHook::UserTermExpansion | CompileTimeHook::TermExpansion => { + CompileTimeHook::UserTermExpansion + } } } @@ -589,30 +610,31 @@ impl CompileTimeHook { pub fn has_module_scope(self) -> bool { match self { CompileTimeHook::UserTermExpansion | CompileTimeHook::UserGoalExpansion => false, - _ => true + _ => true, } } } pub enum RefOrOwned<'a, T: 'a> { Borrowed(&'a T), - Owned(T) + Owned(T), } impl<'a, T> RefOrOwned<'a, T> { pub fn as_ref(&'a self) -> &'a T { match self { &RefOrOwned::Borrowed(r) => r, - &RefOrOwned::Owned(ref r) => r + &RefOrOwned::Owned(ref r) => r, } } pub fn to_owned(self) -> T - where T: Clone + where + T: Clone, { match self { RefOrOwned::Borrowed(item) => item.clone(), - RefOrOwned::Owned(item) => item + RefOrOwned::Owned(item) => item, } } } diff --git a/src/prolog/machine/machine_state.rs b/src/prolog/machine/machine_state.rs index 7e6ad97b..166e2c43 100644 --- a/src/prolog/machine/machine_state.rs +++ b/src/prolog/machine/machine_state.rs @@ -17,7 +17,7 @@ use prolog::rug::Integer; use downcast::Any; use std::cmp::Ordering; -use std::io::{Write, stdout}; +use std::io::{stdout, Write}; use std::mem; use std::ops::{Index, IndexMut}; @@ -28,7 +28,10 @@ pub(super) struct Ball { impl Ball { pub(super) fn new() -> Self { - Ball { boundary: 0, stub: MachineStub::new() } + Ball { + boundary: 0, + stub: MachineStub::new(), + } } pub(super) fn reset(&mut self) { @@ -42,13 +45,13 @@ impl Ball { Ball { boundary, - stub: mem::replace(&mut self.stub, vec![]) + stub: mem::replace(&mut self.stub, vec![]), } } } pub(super) struct CopyTerm<'a> { - state: &'a mut MachineState + state: &'a mut MachineState, } impl<'a> CopyTerm<'a> { @@ -102,10 +105,18 @@ pub(super) struct CopyBallTerm<'a> { } impl<'a> CopyBallTerm<'a> { - pub(super) fn new(and_stack: &'a mut AndStack, heap: &'a mut Heap, stub: &'a mut MachineStub) -> Self - { + pub(super) fn new( + and_stack: &'a mut AndStack, + heap: &'a mut Heap, + stub: &'a mut MachineStub, + ) -> Self { let hb = heap.len(); - CopyBallTerm { and_stack, heap, heap_boundary: hb, stub } + CopyBallTerm { + and_stack, + heap, + heap_boundary: hb, + stub, + } } } @@ -145,15 +156,15 @@ impl<'a> CopierTarget for CopyBallTerm<'a> { fn store(&self, addr: Addr) -> Addr { match addr { - Addr::HeapCell(h) | Addr::AttrVar(h) if h < self.heap_boundary => - self.heap[h].as_addr(h), + Addr::HeapCell(h) | Addr::AttrVar(h) if h < self.heap_boundary => { + self.heap[h].as_addr(h) + } Addr::HeapCell(h) | Addr::AttrVar(h) => { let index = h - self.heap_boundary; self.stub[index].as_addr(h) - }, - Addr::StackCell(fr, sc) => - self.and_stack[fr][sc].clone(), - addr => addr + } + Addr::StackCell(fr, sc) => self.and_stack[fr][sc].clone(), + addr => addr, } } @@ -167,7 +178,7 @@ impl<'a> CopierTarget for CopyBallTerm<'a> { } return addr; - }; + } } fn stack(&mut self) -> &mut AndStack { @@ -206,7 +217,7 @@ pub type Registers = Vec; #[derive(Clone, Copy)] pub(super) enum MachineMode { Read, - Write + Write, } pub struct MachineState { @@ -235,97 +246,85 @@ pub struct MachineState { pub(super) interms: Vec, // intermediate numbers. pub(super) last_call: bool, pub(crate) heap_locs: HeapVarDict, - pub(crate) flags: MachineFlags + pub(crate) flags: MachineFlags, } impl MachineState { - pub(super) - fn try_char_list(&self, addrs: Vec) -> Result - { + pub(super) fn try_char_list(&self, addrs: Vec) -> Result { let mut chars = String::new(); let mut iter = addrs.iter(); while let Some(addr) = iter.next() { match addr { - &Addr::Con(Constant::String(ref s)) - if self.flags.double_quotes.is_chars() => { - chars += s.borrow().as_str(); - - if iter.next().is_some() { - return Err(MachineError::type_error(ValidType::Character, addr.clone())); - } - }, - &Addr::Con(Constant::Char(c)) => - chars.push(c), - &Addr::Con(Constant::Atom(ref name, _)) - if name.as_str().len() == 1 => { - chars += name.as_str(); - }, - _ => - return Err(MachineError::type_error(ValidType::Character, addr.clone())) + &Addr::Con(Constant::String(ref s)) if self.flags.double_quotes.is_chars() => { + chars += s.borrow().as_str(); + + if iter.next().is_some() { + return Err(MachineError::type_error(ValidType::Character, addr.clone())); + } + } + &Addr::Con(Constant::Char(c)) => chars.push(c), + &Addr::Con(Constant::Atom(ref name, _)) if name.as_str().len() == 1 => { + chars += name.as_str(); + } + _ => return Err(MachineError::type_error(ValidType::Character, addr.clone())), } } Ok(chars) } - pub(super) - fn try_code_list(&self, addrs: Vec) -> Result, MachineError> - { + pub(super) fn try_code_list(&self, addrs: Vec) -> Result, MachineError> { let mut codes = vec![]; - let mut iter = addrs.iter(); + let mut iter = addrs.iter(); while let Some(addr) = iter.next() { match addr { - &Addr::Con(Constant::String(ref s)) - if self.flags.double_quotes.is_codes() => { - codes.extend(s.borrow().chars().map(|c| c as u8)); - - if iter.next().is_some() { - return Err(MachineError::representation_error(RepFlag::CharacterCode)); - } - }, - &Addr::Con(Constant::CharCode(c)) => - codes.push(c), - &Addr::Con(Constant::Integer(ref n)) => + &Addr::Con(Constant::String(ref s)) if self.flags.double_quotes.is_codes() => { + codes.extend(s.borrow().chars().map(|c| c as u8)); + + if iter.next().is_some() { + return Err(MachineError::representation_error(RepFlag::CharacterCode)); + } + } + &Addr::Con(Constant::CharCode(c)) => codes.push(c), + &Addr::Con(Constant::Integer(ref n)) => { if let Some(c) = n.to_u8() { codes.push(c); } else { return Err(MachineError::representation_error(RepFlag::CharacterCode)); - }, - _ => - return Err(MachineError::representation_error(RepFlag::CharacterCode)) + } + } + _ => return Err(MachineError::representation_error(RepFlag::CharacterCode)), } } Ok(codes) } - - fn call_at_index(&mut self, arity: usize, p: usize) - { + + fn call_at_index(&mut self, arity: usize, p: usize) { self.cp.assign_if_local(self.p.clone() + 1); self.num_of_args = arity; self.b0 = self.b; self.p = dir_entry!(p); } - pub(super) - fn execute_at_index(&mut self, arity: usize, p: usize) - { + pub(super) fn execute_at_index(&mut self, arity: usize, p: usize) { self.num_of_args = arity; self.b0 = self.b; self.p = dir_entry!(p); } - pub(super) - fn module_lookup(&mut self, indices: &IndexStore, key: PredicateKey, module_name: ClauseName, - last_call: bool) - -> CallResult - { + pub(super) fn module_lookup( + &mut self, + indices: &IndexStore, + key: PredicateKey, + module_name: ClauseName, + last_call: bool, + ) -> CallResult { let (name, arity) = key; - if let Some(ref idx) = indices.get_code_index((name.clone(), arity), module_name.clone()) - { + if let Some(ref idx) = indices.get_code_index((name.clone(), arity), module_name.clone()) { if let IndexPtr::Index(compiled_tl_index) = idx.0.borrow().0 { if last_call { self.execute_at_index(arity, compiled_tl_index); @@ -345,25 +344,29 @@ impl MachineState { } } -fn try_in_situ_lookup(name: ClauseName, arity: usize, indices: &IndexStore) -> Option -{ +fn try_in_situ_lookup(name: ClauseName, arity: usize, indices: &IndexStore) -> Option { match indices.in_situ_code_dir.get(&(name.clone(), arity)) { Some(p) => Some(*p), None => match indices.code_dir.get(&(name, arity)) { - Some(ref idx) => if let &IndexPtr::Index(p) = &idx.0.borrow().0 { - Some(p) - } else { - None - }, - _ => None - } + Some(ref idx) => { + if let &IndexPtr::Index(p) = &idx.0.borrow().0 { + Some(p) + } else { + None + } + } + _ => None, + }, } } -fn try_in_situ(machine_st: &mut MachineState, name: ClauseName, arity: usize, - indices: &IndexStore, last_call: bool) - -> CallResult -{ +fn try_in_situ( + machine_st: &mut MachineState, + name: ClauseName, + arity: usize, + indices: &IndexStore, + last_call: bool, +) -> CallResult { if let Some(p) = try_in_situ_lookup(name.clone(), arity, indices) { if last_call { machine_st.execute_at_index(arity, p); @@ -385,21 +388,20 @@ fn try_in_situ(machine_st: &mut MachineState, name: ClauseName, arity: usize, pub(crate) type CallResult = Result<(), Vec>; pub(crate) trait CallPolicy: Any { - fn retry_me_else(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult - { + fn retry_me_else(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult { let b = machine_st.b - 1; let n = machine_st.or_stack[b].num_args(); - for i in 1 .. n + 1 { + for i in 1..n + 1 { machine_st.registers[i] = machine_st.or_stack[b][i].clone(); } - machine_st.e = machine_st.or_stack[b].e; + machine_st.e = machine_st.or_stack[b].e; machine_st.cp = machine_st.or_stack[b].cp.clone(); machine_st.or_stack[b].bp = machine_st.p.clone() + offset; - let old_tr = machine_st.or_stack[b].tr; + let old_tr = machine_st.or_stack[b].tr; let curr_tr = machine_st.tr; machine_st.unwind_trail(old_tr, curr_tr); @@ -407,7 +409,7 @@ pub(crate) trait CallPolicy: Any { machine_st.trail.truncate(machine_st.tr); - let old_pstr_tr = machine_st.or_stack[b].pstr_tr; + let old_pstr_tr = machine_st.or_stack[b].pstr_tr; let curr_pstr_tr = machine_st.pstr_tr; machine_st.unwind_pstr_trail(old_pstr_tr, curr_pstr_tr); @@ -418,7 +420,10 @@ pub(crate) trait CallPolicy: Any { machine_st.heap.truncate(machine_st.or_stack[b].h); let attr_var_init_b = machine_st.or_stack[b].attr_var_init_b; - machine_st.attr_var_init.attr_var_queue.truncate(attr_var_init_b); + machine_st + .attr_var_init + .attr_var_queue + .truncate(attr_var_init_b); machine_st.hb = machine_st.heap.h; machine_st.p += 1; @@ -426,21 +431,20 @@ pub(crate) trait CallPolicy: Any { Ok(()) } - fn retry(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult - { + fn retry(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult { let b = machine_st.b - 1; let n = machine_st.or_stack[b].num_args(); - for i in 1 .. n + 1 { + for i in 1..n + 1 { machine_st.registers[i] = machine_st.or_stack[b][i].clone(); } - machine_st.e = machine_st.or_stack[b].e; + machine_st.e = machine_st.or_stack[b].e; machine_st.cp = machine_st.or_stack[b].cp.clone(); machine_st.or_stack[b].bp = machine_st.p.clone() + 1; - let old_tr = machine_st.or_stack[b].tr; + let old_tr = machine_st.or_stack[b].tr; let curr_tr = machine_st.tr; machine_st.unwind_trail(old_tr, curr_tr); @@ -448,7 +452,7 @@ pub(crate) trait CallPolicy: Any { machine_st.trail.truncate(machine_st.tr); - let old_pstr_tr = machine_st.or_stack[b].pstr_tr; + let old_pstr_tr = machine_st.or_stack[b].pstr_tr; let curr_pstr_tr = machine_st.pstr_tr; machine_st.unwind_pstr_trail(old_pstr_tr, curr_pstr_tr); @@ -459,7 +463,10 @@ pub(crate) trait CallPolicy: Any { machine_st.heap.truncate(machine_st.or_stack[b].h); let attr_var_init_b = machine_st.or_stack[b].attr_var_init_b; - machine_st.attr_var_init.attr_var_queue.truncate(attr_var_init_b); + machine_st + .attr_var_init + .attr_var_queue + .truncate(attr_var_init_b); machine_st.hb = machine_st.heap.h; machine_st.p += offset; @@ -467,19 +474,18 @@ pub(crate) trait CallPolicy: Any { Ok(()) } - fn trust(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult - { + fn trust(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult { let b = machine_st.b - 1; let n = machine_st.or_stack[b].num_args(); - for i in 1 .. n + 1 { + for i in 1..n + 1 { machine_st.registers[i] = machine_st.or_stack[b][i].clone(); } - machine_st.e = machine_st.or_stack[b].e; + machine_st.e = machine_st.or_stack[b].e; machine_st.cp = machine_st.or_stack[b].cp.clone(); - let old_tr = machine_st.or_stack[b].tr; + let old_tr = machine_st.or_stack[b].tr; let curr_tr = machine_st.tr; machine_st.unwind_trail(old_tr, curr_tr); @@ -487,7 +493,7 @@ pub(crate) trait CallPolicy: Any { machine_st.trail.truncate(machine_st.tr); - let old_pstr_tr = machine_st.or_stack[b].pstr_tr; + let old_pstr_tr = machine_st.or_stack[b].pstr_tr; let curr_pstr_tr = machine_st.pstr_tr; machine_st.unwind_pstr_trail(old_pstr_tr, curr_pstr_tr); @@ -498,7 +504,10 @@ pub(crate) trait CallPolicy: Any { machine_st.heap.truncate(machine_st.or_stack[b].h); let attr_var_init_b = machine_st.or_stack[b].attr_var_init_b; - machine_st.attr_var_init.attr_var_queue.truncate(attr_var_init_b); + machine_st + .attr_var_init + .attr_var_queue + .truncate(attr_var_init_b); machine_st.b = machine_st.or_stack[b].b; machine_st.or_stack.truncate(machine_st.b); @@ -509,19 +518,18 @@ pub(crate) trait CallPolicy: Any { Ok(()) } - fn trust_me(&mut self, machine_st: &mut MachineState) -> CallResult - { + fn trust_me(&mut self, machine_st: &mut MachineState) -> CallResult { let b = machine_st.b - 1; let n = machine_st.or_stack[b].num_args(); - for i in 1 .. n + 1 { + for i in 1..n + 1 { machine_st.registers[i] = machine_st.or_stack[b][i].clone(); } - machine_st.e = machine_st.or_stack[b].e; + machine_st.e = machine_st.or_stack[b].e; machine_st.cp = machine_st.or_stack[b].cp.clone(); - let old_tr = machine_st.or_stack[b].tr; + let old_tr = machine_st.or_stack[b].tr; let curr_tr = machine_st.tr; machine_st.unwind_trail(old_tr, curr_tr); @@ -529,7 +537,7 @@ pub(crate) trait CallPolicy: Any { machine_st.trail.truncate(machine_st.tr); - let old_pstr_tr = machine_st.or_stack[b].pstr_tr; + let old_pstr_tr = machine_st.or_stack[b].pstr_tr; let curr_pstr_tr = machine_st.pstr_tr; machine_st.unwind_pstr_trail(old_pstr_tr, curr_pstr_tr); @@ -540,7 +548,10 @@ pub(crate) trait CallPolicy: Any { machine_st.heap.truncate(machine_st.or_stack[b].h); let attr_var_init_b = machine_st.or_stack[b].attr_var_init_b; - machine_st.attr_var_init.attr_var_queue.truncate(attr_var_init_b); + machine_st + .attr_var_init + .attr_var_queue + .truncate(attr_var_init_b); machine_st.b = machine_st.or_stack[b].b; machine_st.or_stack.truncate(machine_st.b); @@ -551,10 +562,14 @@ pub(crate) trait CallPolicy: Any { Ok(()) } - fn context_call(&mut self, machine_st: &mut MachineState, name: ClauseName, - arity: usize, idx: CodeIndex, indices: &mut IndexStore) - -> CallResult - { + fn context_call( + &mut self, + machine_st: &mut MachineState, + name: ClauseName, + arity: usize, + idx: CodeIndex, + indices: &mut IndexStore, + ) -> CallResult { if machine_st.last_call { self.try_execute(machine_st, name, arity, idx, indices) } else { @@ -562,48 +577,59 @@ pub(crate) trait CallPolicy: Any { } } - fn try_call(&mut self, machine_st: &mut MachineState, name: ClauseName, arity: usize, - idx: CodeIndex, indices: &IndexStore) - -> CallResult - { + fn try_call( + &mut self, + machine_st: &mut MachineState, + name: ClauseName, + arity: usize, + idx: CodeIndex, + indices: &IndexStore, + ) -> CallResult { match idx.0.borrow().0 { - IndexPtr::Undefined => - return try_in_situ(machine_st, name, arity, indices, false), - IndexPtr::Index(compiled_tl_index) => + IndexPtr::Undefined => return try_in_situ(machine_st, name, arity, indices, false), + IndexPtr::Index(compiled_tl_index) => { machine_st.call_at_index(arity, compiled_tl_index) + } } Ok(()) } - fn try_execute(&mut self, machine_st: &mut MachineState, name: ClauseName, - arity: usize, idx: CodeIndex, indices: &IndexStore) - -> CallResult - { + fn try_execute( + &mut self, + machine_st: &mut MachineState, + name: ClauseName, + arity: usize, + idx: CodeIndex, + indices: &IndexStore, + ) -> CallResult { match idx.0.borrow().0 { - IndexPtr::Undefined => - return try_in_situ(machine_st, name, arity, indices, true), - IndexPtr::Index(compiled_tl_index) => + IndexPtr::Undefined => return try_in_situ(machine_st, name, arity, indices, true), + IndexPtr::Index(compiled_tl_index) => { machine_st.execute_at_index(arity, compiled_tl_index) + } } Ok(()) } - fn call_builtin(&mut self, machine_st: &mut MachineState, ct: &BuiltInClauseType, - indices: &mut IndexStore, parsing_stream: &mut PrologStream) - -> CallResult - { + fn call_builtin( + &mut self, + machine_st: &mut MachineState, + ct: &BuiltInClauseType, + indices: &mut IndexStore, + parsing_stream: &mut PrologStream, + ) -> CallResult { match ct { &BuiltInClauseType::AcyclicTerm => { let addr = machine_st[temp_v!(1)].clone(); machine_st.fail = machine_st.is_cyclic_term(addr); return_from_clause!(machine_st.last_call, machine_st) - }, + } &BuiltInClauseType::Arg => { machine_st.try_arg()?; return_from_clause!(machine_st.last_call, machine_st) - }, + } &BuiltInClauseType::Compare => { let a1 = machine_st[temp_v!(1)].clone(); let a2 = machine_st[temp_v!(2)].clone(); @@ -613,11 +639,11 @@ pub(crate) trait CallPolicy: Any { Ordering::Greater => { let spec = fetch_atom_op_spec(clause_name!(">"), None, &indices.op_dir); Addr::Con(Constant::Atom(clause_name!(">"), spec)) - }, + } Ordering::Equal => { let spec = fetch_atom_op_spec(clause_name!("="), None, &indices.op_dir); Addr::Con(Constant::Atom(clause_name!("="), spec)) - }, + } Ordering::Less => { let spec = fetch_atom_op_spec(clause_name!("<"), None, &indices.op_dir); Addr::Con(Constant::Atom(clause_name!("<"), spec)) @@ -626,57 +652,57 @@ pub(crate) trait CallPolicy: Any { machine_st.unify(a1, c); return_from_clause!(machine_st.last_call, machine_st) - }, + } &BuiltInClauseType::CompareTerm(qt) => { machine_st.compare_term(qt); return_from_clause!(machine_st.last_call, machine_st) - }, + } &BuiltInClauseType::CyclicTerm => { let addr = machine_st[temp_v!(1)].clone(); machine_st.fail = !machine_st.is_cyclic_term(addr); return_from_clause!(machine_st.last_call, machine_st) - }, + } &BuiltInClauseType::Nl => { let mut stdout = stdout(); write!(stdout, "\n\r").unwrap(); stdout.flush().unwrap(); return_from_clause!(machine_st.last_call, machine_st) - }, + } &BuiltInClauseType::Read => { match machine_st.read(parsing_stream, indices.atom_tbl.clone(), &indices.op_dir) { Ok(offset) => { let addr = machine_st[temp_v!(1)].clone(); machine_st.unify(addr, Addr::HeapCell(offset.heap_loc)); - }, + } Err(e) => { - let h = machine_st.heap.h; + let h = machine_st.heap.h; let stub = MachineError::functor_stub(clause_name!("read"), 1); - let err = MachineError::syntax_error(h, e); - let err = machine_st.error_form(err, stub); + let err = MachineError::syntax_error(h, e); + let err = machine_st.error_form(err, stub); return Err(err); } }; return_from_clause!(machine_st.last_call, machine_st) - }, + } &BuiltInClauseType::CopyTerm => { machine_st.copy_term(); return_from_clause!(machine_st.last_call, machine_st) - }, + } &BuiltInClauseType::Eq => { machine_st.fail = machine_st.eq_test(); return_from_clause!(machine_st.last_call, machine_st) - }, + } &BuiltInClauseType::Ground => { machine_st.fail = machine_st.ground_test(); return_from_clause!(machine_st.last_call, machine_st) - }, + } &BuiltInClauseType::Functor => { machine_st.try_functor(&indices)?; return_from_clause!(machine_st.last_call, machine_st) - }, + } &BuiltInClauseType::NotEq => { let a1 = machine_st[temp_v!(1)].clone(); let a2 = machine_st[temp_v!(2)].clone(); @@ -688,7 +714,7 @@ pub(crate) trait CallPolicy: Any { }; return_from_clause!(machine_st.last_call, machine_st) - }, + } &BuiltInClauseType::PartialString => { let s = machine_st.try_string_list(temp_v!(1))?; let a2 = machine_st[temp_v!(2)].clone(); @@ -697,7 +723,7 @@ pub(crate) trait CallPolicy: Any { machine_st.write_constant_to_var(a2, Constant::String(s)); return_from_clause!(machine_st.last_call, machine_st) - }, + } &BuiltInClauseType::Sort => { machine_st.check_sort_errors()?; @@ -713,7 +739,7 @@ pub(crate) trait CallPolicy: Any { machine_st.unify(r2, heap_addr); return_from_clause!(machine_st.last_call, machine_st) - }, + } &BuiltInClauseType::KeySort => { machine_st.check_keysort_errors()?; @@ -735,38 +761,46 @@ pub(crate) trait CallPolicy: Any { machine_st.unify(r2, heap_addr); return_from_clause!(machine_st.last_call, machine_st) - }, + } &BuiltInClauseType::Is(r, ref at) => { let a1 = machine_st[r].clone(); let a2 = machine_st.get_number(at)?; machine_st.unify(a1, Addr::Con(a2.to_constant())); return_from_clause!(machine_st.last_call, machine_st) - }, + } } } - fn compile_hook(&mut self, machine_st: &mut MachineState, hook: &CompileTimeHook) -> CallResult - { + fn compile_hook( + &mut self, + machine_st: &mut MachineState, + hook: &CompileTimeHook, + ) -> CallResult { machine_st.cp = LocalCodePtr::TopLevel(0, 0); machine_st.num_of_args = hook.arity(); machine_st.b0 = machine_st.b; machine_st.p = match hook { - CompileTimeHook::UserTermExpansion | CompileTimeHook::TermExpansion => - CodePtr::Local(LocalCodePtr::UserTermExpansion(0)), - CompileTimeHook::UserGoalExpansion | CompileTimeHook::GoalExpansion => + CompileTimeHook::UserTermExpansion | CompileTimeHook::TermExpansion => { + CodePtr::Local(LocalCodePtr::UserTermExpansion(0)) + } + CompileTimeHook::UserGoalExpansion | CompileTimeHook::GoalExpansion => { CodePtr::Local(LocalCodePtr::UserGoalExpansion(0)) + } }; Ok(()) } - fn call_n(&mut self, machine_st: &mut MachineState, arity: usize, indices: &mut IndexStore, - parsing_stream: &mut PrologStream) - -> CallResult - { + fn call_n( + &mut self, + machine_st: &mut MachineState, + arity: usize, + indices: &mut IndexStore, + parsing_stream: &mut PrologStream, + ) -> CallResult { if let Some((name, arity)) = machine_st.setup_call_n(arity) { match ClauseType::from(name.clone(), arity, None) { ClauseType::CallN => { @@ -777,18 +811,18 @@ pub(crate) trait CallPolicy: Any { } machine_st.p = CodePtr::CallN(arity, machine_st.p.local()); - }, + } ClauseType::BuiltIn(built_in) => { machine_st.setup_built_in_call(built_in.clone()); self.call_builtin(machine_st, &built_in, indices, parsing_stream)?; - }, + } ClauseType::Inlined(inlined) => { machine_st.execute_inlined(&inlined); if machine_st.last_call { machine_st.p = CodePtr::Local(machine_st.cp); } - }, + } ClauseType::Op(..) | ClauseType::Named(..) => { let module = name.owning_module(); @@ -799,17 +833,17 @@ pub(crate) trait CallPolicy: Any { let stub = MachineError::functor_stub(clause_name!("call"), arity + 1); let key = ExistenceError::Procedure(name, arity); - return Err(machine_st.error_form(MachineError::existence_error(h, key), - stub)); + return Err( + machine_st.error_form(MachineError::existence_error(h, key), stub) + ); } - }, + } ClauseType::Hook(_) | ClauseType::System(_) => { let name = Addr::Con(Constant::Atom(name, None)); let stub = MachineError::functor_stub(clause_name!("call"), arity + 1); - return Err(machine_st.error_form(MachineError::type_error(ValidType::Callable, - name), - stub)); + return Err(machine_st + .error_form(MachineError::type_error(ValidType::Callable, name), stub)); } }; } @@ -819,51 +853,60 @@ pub(crate) trait CallPolicy: Any { } impl CallPolicy for CWILCallPolicy { - fn context_call(&mut self, machine_st: &mut MachineState, name: ClauseName, - arity: usize, idx: CodeIndex, indices: &mut IndexStore) - -> CallResult - { - self.prev_policy.context_call(machine_st, name, arity, idx, indices)?; + fn context_call( + &mut self, + machine_st: &mut MachineState, + name: ClauseName, + arity: usize, + idx: CodeIndex, + indices: &mut IndexStore, + ) -> CallResult { + self.prev_policy + .context_call(machine_st, name, arity, idx, indices)?; self.increment(machine_st) } - fn retry_me_else(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult - { + fn retry_me_else(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult { self.prev_policy.retry_me_else(machine_st, offset)?; self.increment(machine_st) } - fn retry(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult - { + fn retry(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult { self.prev_policy.retry(machine_st, offset)?; self.increment(machine_st) } - fn trust_me(&mut self, machine_st: &mut MachineState) -> CallResult - { + fn trust_me(&mut self, machine_st: &mut MachineState) -> CallResult { self.prev_policy.trust_me(machine_st)?; self.increment(machine_st) } - fn trust(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult - { + fn trust(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult { self.prev_policy.trust(machine_st, offset)?; self.increment(machine_st) } - fn call_builtin(&mut self, machine_st: &mut MachineState, ct: &BuiltInClauseType, - indices: &mut IndexStore, parsing_stream: &mut PrologStream) - -> CallResult - { - self.prev_policy.call_builtin(machine_st, ct, indices, parsing_stream)?; + fn call_builtin( + &mut self, + machine_st: &mut MachineState, + ct: &BuiltInClauseType, + indices: &mut IndexStore, + parsing_stream: &mut PrologStream, + ) -> CallResult { + self.prev_policy + .call_builtin(machine_st, ct, indices, parsing_stream)?; self.increment(machine_st) } - fn call_n(&mut self, machine_st: &mut MachineState, arity: usize, indices: &mut IndexStore, - parsing_stream: &mut PrologStream) - -> CallResult - { - self.prev_policy.call_n(machine_st, arity, indices, parsing_stream)?; + fn call_n( + &mut self, + machine_st: &mut MachineState, + arity: usize, + indices: &mut IndexStore, + parsing_stream: &mut PrologStream, + ) -> CallResult { + self.prev_policy + .call_n(machine_st, arity, indices, parsing_stream)?; self.increment(machine_st) } } @@ -876,21 +919,22 @@ impl CallPolicy for DefaultCallPolicy {} pub(crate) struct CWILCallPolicy { pub(crate) prev_policy: Box, - count: Integer, + count: Integer, limits: Vec<(Integer, usize)>, - inference_limit_exceeded: bool + inference_limit_exceeded: bool, } impl CWILCallPolicy { - pub(crate) fn new_in_place(policy: &mut Box) - { + pub(crate) fn new_in_place(policy: &mut Box) { let mut prev_policy: Box = Box::new(DefaultCallPolicy {}); mem::swap(&mut prev_policy, policy); - let new_policy = CWILCallPolicy { prev_policy, - count: Integer::from(0), - limits: vec![], - inference_limit_exceeded: false }; + let new_policy = CWILCallPolicy { + prev_policy, + count: Integer::from(0), + limits: vec![], + inference_limit_exceeded: false, + }; *policy = Box::new(new_policy); } @@ -902,8 +946,11 @@ impl CWILCallPolicy { if let Some(&(ref limit, bp)) = self.limits.last() { if self.count == *limit { self.inference_limit_exceeded = true; - return Err(functor!("inference_limit_exceeded", 1, - [HeapCellValue::Addr(Addr::Con(Constant::Usize(bp)))])); + return Err(functor!( + "inference_limit_exceeded", + 1, + [HeapCellValue::Addr(Addr::Con(Constant::Usize(bp)))] + )); } else { self.count += 1; } @@ -916,8 +963,8 @@ impl CWILCallPolicy { limit += &self.count; match self.limits.last().cloned() { - Some((ref inner_limit, _)) if *inner_limit <= limit => {}, - _ => self.limits.push((limit, b)) + Some((ref inner_limit, _)) if *inner_limit <= limit => {} + _ => self.limits.push((limit, b)), }; &self.count @@ -986,13 +1033,17 @@ impl CutPolicy for DefaultCutPolicy { pub(crate) struct SCCCutPolicy { // locations of cleaners, cut points, the previous block cont_pts: Vec<(Addr, usize, usize)>, - r_c_w_h: usize, - r_c_wo_h: usize + r_c_w_h: usize, + r_c_wo_h: usize, } impl SCCCutPolicy { pub(crate) fn new(r_c_w_h: usize, r_c_wo_h: usize) -> Self { - SCCCutPolicy { cont_pts: vec![], r_c_w_h, r_c_wo_h } + SCCCutPolicy { + cont_pts: vec![], + r_c_w_h, + r_c_wo_h, + } } pub(crate) fn out_of_cont_pts(&self) -> bool { diff --git a/src/prolog/machine/machine_state_impl.rs b/src/prolog/machine/machine_state_impl.rs index a6f1a801..1df1b7bf 100644 --- a/src/prolog/machine/machine_state_impl.rs +++ b/src/prolog/machine/machine_state_impl.rs @@ -8,22 +8,22 @@ use prolog::forms::*; use prolog::heap_iter::*; use prolog::heap_print::*; use prolog::instructions::*; -use prolog::machine::attributed_variables::*; use prolog::machine::and_stack::*; +use prolog::machine::attributed_variables::*; use prolog::machine::code_repo::CodeRepo; use prolog::machine::copier::*; use prolog::machine::heap::*; -use prolog::machine::or_stack::*; use prolog::machine::machine_errors::*; use prolog::machine::machine_indices::*; use prolog::machine::machine_state::*; +use prolog::machine::or_stack::*; use prolog::ordered_float::*; -use prolog::rug::{Integer, Rational}; use prolog::read::PrologStream; +use prolog::rug::{Integer, Rational}; use indexmap::{IndexMap, IndexSet}; -use std::cmp::{min, max, Ordering}; +use std::cmp::{max, min, Ordering}; use std::f64; use std::mem; use std::rc::Rc; @@ -31,24 +31,22 @@ use std::rc::Rc; macro_rules! try_numeric_result { ($s: ident, $e: expr, $caller: expr) => {{ match $e { - Ok(val) => - Ok(val), - Err(e) => - Err($s.error_form(MachineError::evaluation_error(e), $caller)) + Ok(val) => Ok(val), + Err(e) => Err($s.error_form(MachineError::evaluation_error(e), $caller)), } - }} + }}; } macro_rules! try_or_fail { ($s:ident, $e:expr) => {{ match $e { - Ok(val) => val, + Ok(val) => val, Err(msg) => { $s.throw_exception(msg); return; } } - }} + }}; } impl MachineState { @@ -79,7 +77,7 @@ impl MachineState { interms: vec![Number::default(); 256], last_call: false, heap_locs: HeapVarDict::new(), - flags: MachineFlags::default() + flags: MachineFlags::default(), } } @@ -110,13 +108,13 @@ impl MachineState { interms: vec![Number::default(); 0], last_call: false, heap_locs: HeapVarDict::new(), - flags: MachineFlags::default() + flags: MachineFlags::default(), } } #[allow(dead_code)] pub fn print_heap(&self) { - for h in 0 .. self.heap.h { + for h in 0..self.heap.h { println!("{} : {}", h, self.heap[h]); } } @@ -127,15 +125,25 @@ impl MachineState { } fn next_global_index(&self) -> usize { - max(if self.and_stack.len() > 0 { self.and_stack[self.e].global_index } else { 0 }, - if self.b > 0 { self.or_stack[self.b - 1].global_index } else { 0 }) + 1 + max( + if self.and_stack.len() > 0 { + self.and_stack[self.e].global_index + } else { + 0 + }, + if self.b > 0 { + self.or_stack[self.b - 1].global_index + } else { + 0 + }, + ) + 1 } pub(crate) fn store(&self, addr: Addr) -> Addr { match addr { Addr::AttrVar(h) | Addr::HeapCell(h) => self.heap[h].as_addr(h), Addr::StackCell(fr, sc) => self.and_stack[fr][sc].clone(), - addr => addr + addr => addr, } } @@ -149,7 +157,7 @@ impl MachineState { } return addr; - }; + } } fn bind_attr_var(&mut self, h: usize, addr: Addr) { @@ -157,11 +165,11 @@ impl MachineState { Some(Ref::HeapCell(hc)) => { self.heap[hc] = HeapCellValue::Addr(Addr::AttrVar(h)); self.trail(TrailRef::Ref(Ref::HeapCell(hc))); - }, + } Some(Ref::StackCell(fr, sc)) => { self.and_stack[fr][sc] = Addr::AttrVar(h); self.trail(TrailRef::Ref(Ref::StackCell(fr, sc))); - }, + } _ => { self.push_attr_var_binding(h, addr.clone()); self.heap[h] = HeapCellValue::Addr(addr); @@ -176,12 +184,9 @@ impl MachineState { if t1.is_ref() && (!t2.is_ref() || a2 < r1) { match r1 { - Ref::StackCell(fr, sc) => - self.and_stack[fr][sc] = t2, - Ref::HeapCell(h) => - self.heap[h] = HeapCellValue::Addr(t2), - Ref::AttrVar(h) => - return self.bind_attr_var(h, t2) + Ref::StackCell(fr, sc) => self.and_stack[fr][sc] = t2, + Ref::HeapCell(h) => self.heap[h] = HeapCellValue::Addr(t2), + Ref::AttrVar(h) => return self.bind_attr_var(h, t2), }; self.trail(TrailRef::from(r1)); @@ -190,22 +195,26 @@ impl MachineState { Some(Ref::StackCell(fr, sc)) => { self.and_stack[fr][sc] = t1; self.trail(TrailRef::Ref(Ref::StackCell(fr, sc))); - }, + } Some(Ref::HeapCell(h)) => { self.heap[h] = HeapCellValue::Addr(t1); self.trail(TrailRef::Ref(Ref::HeapCell(h))); - }, - Some(Ref::AttrVar(h)) => - return self.bind_attr_var(h, t1), + } + Some(Ref::AttrVar(h)) => return self.bind_attr_var(h, t1), None => {} } } } - pub(super) - fn print_var_eq(&self, var: Rc, addr: Addr, op_dir: &OpDir, mut output: Outputter) - -> Outputter - where Outputter: HCValueOutputter + pub(super) fn print_var_eq( + &self, + var: Rc, + addr: Addr, + op_dir: &OpDir, + mut output: Outputter, + ) -> Outputter + where + Outputter: HCValueOutputter, { let orig_len = output.len(); @@ -230,9 +239,12 @@ impl MachineState { output } - pub(super) - fn unify_strings(&mut self, pdl: &mut Vec, s1: &mut StringList, s2: &mut StringList) -> bool - { + pub(super) fn unify_strings( + &mut self, + pdl: &mut Vec, + s1: &mut StringList, + s2: &mut StringList, + ) -> bool { if let Some(c1) = s1.head() { if let Some(c2) = s2.head() { if c1 == c2 { @@ -275,8 +287,12 @@ impl MachineState { false } - fn deconstruct_chars(&mut self, s: &mut StringList, offset: usize, pdl: &mut Vec) -> bool - { + fn deconstruct_chars( + &mut self, + s: &mut StringList, + offset: usize, + pdl: &mut Vec, + ) -> bool { if let Some(c) = s.head() { pdl.push(Addr::Con(Constant::String(s.tail()))); pdl.push(Addr::HeapCell(offset + 1)); @@ -300,15 +316,16 @@ impl MachineState { self.pstr_trail(prev_s); stepper(c); return true; - }, - HeapCellValue::Addr(Addr::Con(Constant::Atom(ref a, _))) => + } + HeapCellValue::Addr(Addr::Con(Constant::Atom(ref a, _))) => { if let Some(c) = a.as_str().chars().next() { if c.len_utf8() == a.as_str().len() { self.pstr_trail(prev_s); stepper(c); return true; } - }, + } + } _ => {} } } @@ -316,8 +333,12 @@ impl MachineState { false } - fn deconstruct_codes(&mut self, s: &mut StringList, offset: usize, pdl: &mut Vec) -> bool - { + fn deconstruct_codes( + &mut self, + s: &mut StringList, + offset: usize, + pdl: &mut Vec, + ) -> bool { if let Some(c) = s.head() { pdl.push(Addr::Con(Constant::String(s.tail()))); pdl.push(Addr::HeapCell(offset + 1)); @@ -341,13 +362,14 @@ impl MachineState { self.pstr_trail(prev_s); stepper(c as char); return true; - }, - HeapCellValue::Addr(Addr::Con(Constant::Integer(n))) => + } + HeapCellValue::Addr(Addr::Con(Constant::Integer(n))) => { if let Some(c) = n.to_u8() { self.pstr_trail(prev_s); stepper(c as char); return true; - }, + } + } _ => {} } } @@ -394,12 +416,15 @@ impl MachineState { } match (d1.clone(), d2.clone()) { - (Addr::AttrVar(h), addr) | (addr, Addr::AttrVar(h)) => - self.bind_with_occurs_check(Ref::AttrVar(h), addr), - (Addr::HeapCell(h), addr) | (addr, Addr::HeapCell(h)) => - self.bind_with_occurs_check(Ref::HeapCell(h), addr), - (Addr::StackCell(fr, sc), addr) | (addr, Addr::StackCell(fr, sc)) => - self.bind_with_occurs_check(Ref::StackCell(fr, sc), addr), + (Addr::AttrVar(h), addr) | (addr, Addr::AttrVar(h)) => { + self.bind_with_occurs_check(Ref::AttrVar(h), addr) + } + (Addr::HeapCell(h), addr) | (addr, Addr::HeapCell(h)) => { + self.bind_with_occurs_check(Ref::HeapCell(h), addr) + } + (Addr::StackCell(fr, sc), addr) | (addr, Addr::StackCell(fr, sc)) => { + self.bind_with_occurs_check(Ref::StackCell(fr, sc), addr) + } (Addr::Lis(a1), Addr::Str(a2)) | (Addr::Str(a2), Addr::Lis(a1)) => { if let &HeapCellValue::NamedStr(n2, ref f2, _) = &self.heap[a2] { if f2.as_str() == "." && n2 == 2 { @@ -414,45 +439,50 @@ impl MachineState { } self.fail = true; - }, + } (Addr::Lis(a1), Addr::Con(Constant::String(ref mut s))) - | (Addr::Con(Constant::String(ref mut s)), Addr::Lis(a1)) => { - if match self.flags.double_quotes { - DoubleQuotes::Chars => self.deconstruct_chars(s, a1, &mut pdl), - DoubleQuotes::Codes => self.deconstruct_codes(s, a1, &mut pdl), - DoubleQuotes::Atom => false - } { - continue; - } - - self.fail = true; - }, + | (Addr::Con(Constant::String(ref mut s)), Addr::Lis(a1)) => { + if match self.flags.double_quotes { + DoubleQuotes::Chars => self.deconstruct_chars(s, a1, &mut pdl), + DoubleQuotes::Codes => self.deconstruct_codes(s, a1, &mut pdl), + DoubleQuotes::Atom => false, + } { + continue; + } + + self.fail = true; + } (Addr::Con(Constant::EmptyList), Addr::Con(Constant::String(ref s))) - | (Addr::Con(Constant::String(ref s)), Addr::Con(Constant::EmptyList)) - if !self.flags.double_quotes.is_atom() => { - if s.is_expandable() && s.is_empty() { - self.pstr_trail(s.clone()); - s.set_expandable(false); - continue; - } + | (Addr::Con(Constant::String(ref s)), Addr::Con(Constant::EmptyList)) + if !self.flags.double_quotes.is_atom() => + { + if s.is_expandable() && s.is_empty() { + self.pstr_trail(s.clone()); + s.set_expandable(false); + continue; + } - self.fail = !s.is_empty(); - }, + self.fail = !s.is_empty(); + } (Addr::Lis(a1), Addr::Lis(a2)) => { pdl.push(Addr::HeapCell(a1)); pdl.push(Addr::HeapCell(a2)); pdl.push(Addr::HeapCell(a1 + 1)); pdl.push(Addr::HeapCell(a2 + 1)); - }, - (Addr::Con(Constant::String(ref mut s1)), - Addr::Con(Constant::String(ref mut s2))) => + } + ( + Addr::Con(Constant::String(ref mut s1)), + Addr::Con(Constant::String(ref mut s2)), + ) => { self.fail = !(self.unify_strings(&mut pdl, s1, s2) - || self.unify_strings(&mut pdl, s2, s1)), - (Addr::Con(ref c1), Addr::Con(ref c2)) => + || self.unify_strings(&mut pdl, s2, s1)) + } + (Addr::Con(ref c1), Addr::Con(ref c2)) => { if c1 != c2 { self.fail = true; - }, + } + } (Addr::Str(a1), Addr::Str(a2)) => { let r1 = &self.heap[a1]; let r2 = &self.heap[a2]; @@ -460,7 +490,7 @@ impl MachineState { if let &HeapCellValue::NamedStr(n1, ref f1, _) = r1 { if let &HeapCellValue::NamedStr(n2, ref f2, _) = r2 { if n1 == n2 && *f1 == *f2 { - for i in 1 .. n1 + 1 { + for i in 1..n1 + 1 { pdl.push(Addr::HeapCell(a1 + i)); pdl.push(Addr::HeapCell(a2 + i)); } @@ -471,8 +501,8 @@ impl MachineState { } self.fail = true; - }, - _ => self.fail = true + } + _ => self.fail = true, }; } } @@ -499,16 +529,13 @@ impl MachineState { } match (d1.clone(), d2.clone()) { - (Addr::AttrVar(h), addr) | (addr, Addr::AttrVar(h)) => - self.bind(Ref::AttrVar(h), addr), - (Addr::HeapCell(h), _) => - self.bind(Ref::HeapCell(h), d2), - (_, Addr::HeapCell(h)) => - self.bind(Ref::HeapCell(h), d1), - (Addr::StackCell(fr, sc), _) => - self.bind(Ref::StackCell(fr, sc), d2), - (_, Addr::StackCell(fr, sc)) => - self.bind(Ref::StackCell(fr, sc), d1), + (Addr::AttrVar(h), addr) | (addr, Addr::AttrVar(h)) => { + self.bind(Ref::AttrVar(h), addr) + } + (Addr::HeapCell(h), _) => self.bind(Ref::HeapCell(h), d2), + (_, Addr::HeapCell(h)) => self.bind(Ref::HeapCell(h), d1), + (Addr::StackCell(fr, sc), _) => self.bind(Ref::StackCell(fr, sc), d2), + (_, Addr::StackCell(fr, sc)) => self.bind(Ref::StackCell(fr, sc), d1), (Addr::Lis(a1), Addr::Str(a2)) | (Addr::Str(a2), Addr::Lis(a1)) => { if let &HeapCellValue::NamedStr(n2, ref f2, _) = &self.heap[a2] { if f2.as_str() == "." && n2 == 2 { @@ -523,45 +550,50 @@ impl MachineState { } self.fail = true; - }, + } (Addr::Lis(a1), Addr::Con(Constant::String(ref mut s))) - | (Addr::Con(Constant::String(ref mut s)), Addr::Lis(a1)) => { - if match self.flags.double_quotes { - DoubleQuotes::Chars => self.deconstruct_chars(s, a1, &mut pdl), - DoubleQuotes::Codes => self.deconstruct_codes(s, a1, &mut pdl), - DoubleQuotes::Atom => false - } { - continue; - } - - self.fail = true; - }, + | (Addr::Con(Constant::String(ref mut s)), Addr::Lis(a1)) => { + if match self.flags.double_quotes { + DoubleQuotes::Chars => self.deconstruct_chars(s, a1, &mut pdl), + DoubleQuotes::Codes => self.deconstruct_codes(s, a1, &mut pdl), + DoubleQuotes::Atom => false, + } { + continue; + } + + self.fail = true; + } (Addr::Con(Constant::EmptyList), Addr::Con(Constant::String(ref s))) - | (Addr::Con(Constant::String(ref s)), Addr::Con(Constant::EmptyList)) - if !self.flags.double_quotes.is_atom() => { - if s.is_expandable() && s.is_empty() { - self.pstr_trail(s.clone()); - s.set_expandable(false); - continue; - } + | (Addr::Con(Constant::String(ref s)), Addr::Con(Constant::EmptyList)) + if !self.flags.double_quotes.is_atom() => + { + if s.is_expandable() && s.is_empty() { + self.pstr_trail(s.clone()); + s.set_expandable(false); + continue; + } - self.fail = !s.is_empty(); - }, + self.fail = !s.is_empty(); + } (Addr::Lis(a1), Addr::Lis(a2)) => { pdl.push(Addr::HeapCell(a1)); pdl.push(Addr::HeapCell(a2)); pdl.push(Addr::HeapCell(a1 + 1)); pdl.push(Addr::HeapCell(a2 + 1)); - }, - (Addr::Con(Constant::String(ref mut s1)), - Addr::Con(Constant::String(ref mut s2))) => + } + ( + Addr::Con(Constant::String(ref mut s1)), + Addr::Con(Constant::String(ref mut s2)), + ) => { self.fail = !(self.unify_strings(&mut pdl, s1, s2) - || self.unify_strings(&mut pdl, s2, s1)), - (Addr::Con(ref c1), Addr::Con(ref c2)) => + || self.unify_strings(&mut pdl, s2, s1)) + } + (Addr::Con(ref c1), Addr::Con(ref c2)) => { if c1 != c2 { self.fail = true; - }, + } + } (Addr::Str(a1), Addr::Str(a2)) => { let r1 = &self.heap[a1]; let r2 = &self.heap[a2]; @@ -569,7 +601,7 @@ impl MachineState { if let &HeapCellValue::NamedStr(n1, ref f1, _) = r1 { if let &HeapCellValue::NamedStr(n2, ref f2, _) = r2 { if n1 == n2 && *f1 == *f2 { - for i in 1 .. n1 + 1 { + for i in 1..n1 + 1 { pdl.push(Addr::HeapCell(a1 + i)); pdl.push(Addr::HeapCell(a2 + i)); } @@ -580,8 +612,8 @@ impl MachineState { } self.fail = true; - }, - _ => self.fail = true + } + _ => self.fail = true, }; } } @@ -602,24 +634,27 @@ impl MachineState { pub(super) fn trail(&mut self, r: TrailRef) { match r { - TrailRef::Ref(Ref::HeapCell(h)) => + TrailRef::Ref(Ref::HeapCell(h)) => { if h < self.hb { self.trail.push(TrailRef::Ref(Ref::HeapCell(h))); self.tr += 1; - }, - TrailRef::Ref(Ref::AttrVar(h)) => + } + } + TrailRef::Ref(Ref::AttrVar(h)) => { if h < self.hb { self.trail.push(TrailRef::Ref(Ref::AttrVar(h))); self.tr += 1; - }, - TrailRef::AttrVarLink(h, prev_addr) => + } + } + TrailRef::AttrVarLink(h, prev_addr) => { if h < self.hb { self.trail.push(TrailRef::AttrVarLink(h, prev_addr)); self.tr += 1; - }, + } + } TrailRef::Ref(Ref::StackCell(fr, sc)) => { let fr_gi = self.and_stack[fr].global_index; - let b_gi = if !self.or_stack.is_empty() { + let b_gi = if !self.or_stack.is_empty() { if self.b > 0 { let b = self.b - 1; self.or_stack[b].global_index @@ -642,22 +677,26 @@ impl MachineState { // the sequence is reversed to respect the chronology of trail // additions, now that deleted attributes can be undeleted by // backtracking. - for i in (a1 .. a2).rev() { + for i in (a1..a2).rev() { match self.trail[i].clone() { - TrailRef::Ref(Ref::HeapCell(h)) => - self.heap[h] = HeapCellValue::Addr(Addr::HeapCell(h)), - TrailRef::Ref(Ref::AttrVar(h)) => - self.heap[h] = HeapCellValue::Addr(Addr::AttrVar(h)), - TrailRef::Ref(Ref::StackCell(fr, sc)) => - self.and_stack[fr][sc] = Addr::StackCell(fr, sc), - TrailRef::AttrVarLink(h, prev_addr) => + TrailRef::Ref(Ref::HeapCell(h)) => { + self.heap[h] = HeapCellValue::Addr(Addr::HeapCell(h)) + } + TrailRef::Ref(Ref::AttrVar(h)) => { + self.heap[h] = HeapCellValue::Addr(Addr::AttrVar(h)) + } + TrailRef::Ref(Ref::StackCell(fr, sc)) => { + self.and_stack[fr][sc] = Addr::StackCell(fr, sc) + } + TrailRef::AttrVarLink(h, prev_addr) => { self.heap[h] = HeapCellValue::Addr(prev_addr) + } } } } pub(super) fn unwind_pstr_trail(&mut self, a1: usize, a2: usize) { - for i in a1 .. a2 { + for i in a1..a2 { let (_, mut s, end) = self.pstr_trail[i].clone(); s.truncate(end); } @@ -699,8 +738,8 @@ impl MachineState { match tr_i { TrailRef::Ref(Ref::AttrVar(tr_i)) - | TrailRef::Ref(Ref::HeapCell(tr_i)) - | TrailRef::AttrVarLink(tr_i, _) => + | TrailRef::Ref(Ref::HeapCell(tr_i)) + | TrailRef::AttrVarLink(tr_i, _) => { if tr_i < hb { i += 1; } else { @@ -709,11 +748,12 @@ impl MachineState { self.trail[i] = val; self.trail.pop(); self.tr -= 1; - }, + } + } TrailRef::Ref(Ref::StackCell(fr, _)) => { let b = self.b - 1; let fr_gi = self.and_stack[fr].global_index; - let b_gi = if !self.or_stack.is_empty() { + let b_gi = if !self.or_stack.is_empty() { self.or_stack[b].global_index } else { 0 @@ -738,25 +778,22 @@ impl MachineState { self.pstr_trail(s.clone()); let new_s = s.push_char(c); - self.heap.push(HeapCellValue::Addr(Addr::Con(Constant::String(new_s)))); + self.heap + .push(HeapCellValue::Addr(Addr::Con(Constant::String(new_s)))); false } fn write_constant_to_string(&mut self, s: &mut StringList, c: Constant) -> bool { match c { - Constant::EmptyList if !self.flags.double_quotes.is_atom() => - !s.is_empty(), - Constant::String(ref s2) - if s.is_expandable() && s2.starts_with(s) => { - self.pstr_trail(s.clone()); - s.append_suffix(s2); - s.set_expandable(s2.is_expandable()); - false - }, - Constant::String(s2) => - s.borrow()[s.cursor() ..] != s2.borrow()[s2.cursor() ..], - Constant::Atom(ref a, _) - if a.as_str().starts_with(&s.borrow()[s.cursor() ..]) => + Constant::EmptyList if !self.flags.double_quotes.is_atom() => !s.is_empty(), + Constant::String(ref s2) if s.is_expandable() && s2.starts_with(s) => { + self.pstr_trail(s.clone()); + s.append_suffix(s2); + s.set_expandable(s2.is_expandable()); + false + } + Constant::String(s2) => s.borrow()[s.cursor()..] != s2.borrow()[s2.cursor()..], + Constant::Atom(ref a, _) if a.as_str().starts_with(&s.borrow()[s.cursor()..]) => { if let Some(c) = a.as_str().chars().next() { if c.len_utf8() == a.as_str().len() { // detect chars masquerading as atoms. @@ -770,95 +807,102 @@ impl MachineState { } } else { true - }, - Constant::Char(ref c) if s.is_empty() && s.is_expandable() => + } + } + Constant::Char(ref c) if s.is_empty() && s.is_expandable() => { match self.flags.double_quotes { DoubleQuotes::Chars => self.write_char_to_string(s, *c), - _ => false - }, - Constant::Char(ref c) => - match self.flags.double_quotes { - DoubleQuotes::Chars => - if s.borrow().chars().next() == Some(*c) && c.len_utf8() == s.len() { - s.set_expandable(false); - false - } else { - true - }, - _ => false - }, - Constant::CharCode(ref c) if s.is_empty() && s.is_expandable() => + _ => false, + } + } + Constant::Char(ref c) => match self.flags.double_quotes { + DoubleQuotes::Chars => { + if s.borrow().chars().next() == Some(*c) && c.len_utf8() == s.len() { + s.set_expandable(false); + false + } else { + true + } + } + _ => false, + }, + Constant::CharCode(ref c) if s.is_empty() && s.is_expandable() => { match self.flags.double_quotes { DoubleQuotes::Codes => self.write_char_to_string(s, *c as char), - _ => false - }, - Constant::CharCode(ref c) => - match self.flags.double_quotes { - DoubleQuotes::Codes => - if s.borrow().chars().next() == Some(*c as char) && 1 == s.len() { - s.set_expandable(false); - false - } else { - true - }, - _ => false - }, - _ => true + _ => false, + } + } + Constant::CharCode(ref c) => match self.flags.double_quotes { + DoubleQuotes::Codes => { + if s.borrow().chars().next() == Some(*c as char) && 1 == s.len() { + s.set_expandable(false); + false + } else { + true + } + } + _ => false, + }, + _ => true, } } pub(super) fn write_constant_to_var(&mut self, addr: Addr, c: Constant) { match self.store(self.deref(addr)) { - Addr::Con(Constant::String(ref mut s)) => - self.fail = self.write_constant_to_string(s, c), - Addr::Con(c1) => + Addr::Con(Constant::String(ref mut s)) => { + self.fail = self.write_constant_to_string(s, c) + } + Addr::Con(c1) => { if c1 != c { self.fail = true; - }, - Addr::Lis(l) => - self.unify(Addr::Lis(l), Addr::Con(c)), - addr => if let Some(r) = addr.as_var() { - self.bind(r, Addr::Con(c)); - } else { - self.fail = true; + } + } + Addr::Lis(l) => self.unify(Addr::Lis(l), Addr::Con(c)), + addr => { + if let Some(r) = addr.as_var() { + self.bind(r, Addr::Con(c)); + } else { + self.fail = true; + } } }; } pub(super) fn get_number(&mut self, at: &ArithmeticTerm) -> Result { match at { - &ArithmeticTerm::Reg(r) => - self.arith_eval_by_metacall(r), - &ArithmeticTerm::Interm(i) => - Ok(mem::replace(&mut self.interms[i-1], Number::Integer(Integer::from(0)))), - &ArithmeticTerm::Number(ref n) => - Ok(n.clone()), + &ArithmeticTerm::Reg(r) => self.arith_eval_by_metacall(r), + &ArithmeticTerm::Interm(i) => Ok(mem::replace( + &mut self.interms[i - 1], + Number::Integer(Integer::from(0)), + )), + &ArithmeticTerm::Number(ref n) => Ok(n.clone()), } } - fn rational_from_number(&self, n: Number, caller: &MachineStub) -> Result - { + fn rational_from_number( + &self, + n: Number, + caller: &MachineStub, + ) -> Result { match n { Number::Rational(r) => Ok(r), - Number::Float(OrderedFloat(f)) => - Rational::from_f64(f).ok_or_else(|| { - self.error_form(MachineError::instantiation_error(), caller.clone()) - }), - Number::Integer(n) => - Ok(Rational::from(n)) + Number::Float(OrderedFloat(f)) => Rational::from_f64(f).ok_or_else(|| { + self.error_form(MachineError::instantiation_error(), caller.clone()) + }), + Number::Integer(n) => Ok(Rational::from(n)), } } - fn get_rational(&mut self, at: &ArithmeticTerm, caller: &MachineStub) - -> Result - { + fn get_rational( + &mut self, + at: &ArithmeticTerm, + caller: &MachineStub, + ) -> Result { let n = self.get_number(at)?; self.rational_from_number(n, caller) } - pub(super) - fn arith_eval_by_metacall(&self, r: RegType) -> Result - { + pub(super) fn arith_eval_by_metacall(&self, r: RegType) -> Result { let a = self[r].clone(); let caller = MachineError::functor_stub(clause_name!("(is)"), 2); @@ -876,36 +920,37 @@ impl MachineState { "*" => interms.push(try_numeric_result!(self, a1 * a2, caller.clone())?), "/" => interms.push(self.div(a1, a2)?), "**" => interms.push(self.pow(a1, a2, "(is)")?), - "^" => interms.push(self.int_pow(a1, a2)?), - "max" => interms.push(self.max(a1, a2)?), - "min" => interms.push(self.min(a1, a2)?), + "^" => interms.push(self.int_pow(a1, a2)?), + "max" => interms.push(self.max(a1, a2)?), + "min" => interms.push(self.min(a1, a2)?), "rdiv" => { let r1 = self.rational_from_number(a1, &caller)?; let r2 = self.rational_from_number(a2, &caller)?; let result = Number::Rational(self.rdiv(r1, r2)?); interms.push(result) - }, - "//" => interms.push(Number::Integer(self.idiv(a1, a2)?)), + } + "//" => interms.push(Number::Integer(self.idiv(a1, a2)?)), "div" => interms.push(Number::Integer(self.int_floor_div(a1, a2)?)), - ">>" => interms.push(Number::Integer(self.shr(a1, a2)?)), - "<<" => interms.push(Number::Integer(self.shl(a1, a2)?)), + ">>" => interms.push(Number::Integer(self.shr(a1, a2)?)), + "<<" => interms.push(Number::Integer(self.shl(a1, a2)?)), "/\\" => interms.push(Number::Integer(self.and(a1, a2)?)), "\\/" => interms.push(Number::Integer(self.or(a1, a2)?)), "xor" => interms.push(Number::Integer(self.xor(a1, a2)?)), "mod" => interms.push(Number::Integer(self.modulus(a1, a2)?)), "rem" => interms.push(Number::Integer(self.remainder(a1, a2)?)), "atan2" => interms.push(Number::Float(OrderedFloat(self.atan2(a1, a2)?))), - _ => return Err(self.error_form(MachineError::instantiation_error(), - caller)) + _ => { + return Err(self.error_form(MachineError::instantiation_error(), caller)) + } } - }, + } HeapCellValue::NamedStr(1, name, _) => { let a1 = interms.pop().unwrap(); match name.as_str() { - "-" => interms.push(- a1), - "+" => interms.push(a1), + "-" => interms.push(-a1), + "+" => interms.push(a1), "cos" => interms.push(Number::Float(OrderedFloat(self.cos(a1)?))), "sin" => interms.push(Number::Float(OrderedFloat(self.sin(a1)?))), "tan" => interms.push(Number::Float(OrderedFloat(self.tan(a1)?))), @@ -915,36 +960,40 @@ impl MachineState { "acos" => interms.push(Number::Float(OrderedFloat(self.acos(a1)?))), "asin" => interms.push(Number::Float(OrderedFloat(self.asin(a1)?))), "atan" => interms.push(Number::Float(OrderedFloat(self.atan(a1)?))), - "abs" => interms.push(a1.abs()), + "abs" => interms.push(a1.abs()), "float" => interms.push(Number::Float(OrderedFloat(self.float(a1)?))), "truncate" => interms.push(Number::Integer(self.truncate(a1))), "round" => interms.push(Number::Integer(self.round(a1)?)), "ceiling" => interms.push(Number::Integer(self.ceiling(a1))), "floor" => interms.push(Number::Integer(self.floor(a1))), "\\" => interms.push(Number::Integer(self.bitwise_complement(a1)?)), - _ => return Err(self.error_form(MachineError::instantiation_error(), - caller)) + _ => { + return Err(self.error_form(MachineError::instantiation_error(), caller)) + } } - }, - HeapCellValue::Addr(Addr::Con(Constant::Integer(n))) => - interms.push(Number::Integer(n)), - HeapCellValue::Addr(Addr::Con(Constant::Float(n))) => - interms.push(Number::Float(n)), - HeapCellValue::Addr(Addr::Con(Constant::Rational(n))) => - interms.push(Number::Rational(n)), + } + HeapCellValue::Addr(Addr::Con(Constant::Integer(n))) => { + interms.push(Number::Integer(n)) + } + HeapCellValue::Addr(Addr::Con(Constant::Float(n))) => { + interms.push(Number::Float(n)) + } + HeapCellValue::Addr(Addr::Con(Constant::Rational(n))) => { + interms.push(Number::Rational(n)) + } HeapCellValue::Addr(Addr::Con(Constant::Atom(ref name, _))) if name.as_str() == "pi" => - interms.push(Number::Float(OrderedFloat(f64::consts::PI))), - _ => - return Err(self.error_form(MachineError::instantiation_error(), caller)) + { + interms.push(Number::Float(OrderedFloat(f64::consts::PI))) + } + _ => return Err(self.error_form(MachineError::instantiation_error(), caller)), } - }; + } Ok(interms.pop().unwrap()) } - fn rdiv(&self, r1: Rational, r2: Rational) -> Result - { + fn rdiv(&self, r1: Rational, r2: Rational) -> Result { let stub = MachineError::functor_stub(clause_name!("(rdiv)"), 2); if r2 == 0 { @@ -954,41 +1003,39 @@ impl MachineState { } } - fn int_floor_div(&self, n1: Number, n2: Number) -> Result - { + fn int_floor_div(&self, n1: Number, n2: Number) -> Result { let stub = MachineError::functor_stub(clause_name!("(div)"), 2); match n1 / n2 { Ok(result) => Ok(rnd_i(&result).to_owned()), - Err(e) => Err(self.error_form(MachineError::evaluation_error(e), stub)) + Err(e) => Err(self.error_form(MachineError::evaluation_error(e), stub)), } } - fn idiv(&self, n1: Number, n2: Number) -> Result - { + fn idiv(&self, n1: Number, n2: Number) -> Result { let stub = MachineError::functor_stub(clause_name!("(//)"), 2); match (n1, n2) { - (Number::Integer(n1), Number::Integer(n2)) => + (Number::Integer(n1), Number::Integer(n2)) => { if n2 == 0 { - Err(self.error_form(MachineError::evaluation_error(EvalError::ZeroDivisor), - stub)) + Err(self + .error_form(MachineError::evaluation_error(EvalError::ZeroDivisor), stub)) } else { Ok(n1.div_rem(n2).0) - }, - (Number::Integer(_), n2) => - Err(self.error_form(MachineError::type_error(ValidType::Integer, - Addr::Con(n2.to_constant())), - stub)), - (n1, _) => - Err(self.error_form(MachineError::type_error(ValidType::Integer, - Addr::Con(n1.to_constant())), - stub)) + } + } + (Number::Integer(_), n2) => Err(self.error_form( + MachineError::type_error(ValidType::Integer, Addr::Con(n2.to_constant())), + stub, + )), + (n1, _) => Err(self.error_form( + MachineError::type_error(ValidType::Integer, Addr::Con(n1.to_constant())), + stub, + )), } } - fn div(&self, n1: Number, n2: Number) -> Result - { + fn div(&self, n1: Number, n2: Number) -> Result { let stub = MachineError::functor_stub(clause_name!("(/)"), 2); if n2.is_zero() { @@ -998,8 +1045,7 @@ impl MachineState { } } - fn atan2(&self, n1: Number, n2: Number) -> Result - { + fn atan2(&self, n1: Number, n2: Number) -> Result { let stub = MachineError::functor_stub(clause_name!("(is)"), 2); if n1.is_zero() && n2.is_zero() { @@ -1012,15 +1058,14 @@ impl MachineState { } } - fn int_pow(&self, n1: Number, n2: Number) -> Result - { + fn int_pow(&self, n1: Number, n2: Number) -> Result { if n1.is_zero() && n2.is_negative() { let stub = MachineError::functor_stub(clause_name!("(is)"), 2); return Err(self.error_form(MachineError::evaluation_error(EvalError::Undefined), stub)); } match (n1, n2) { - (Number::Integer(n1), Number::Integer(n2)) => + (Number::Integer(n1), Number::Integer(n2)) => { if n1 != 1 && n2 < 0 { let n = Addr::Con(Constant::Integer(n1)); let stub = MachineError::functor_stub(clause_name!("^"), 2); @@ -1028,20 +1073,23 @@ impl MachineState { Err(self.error_form(MachineError::type_error(ValidType::Float, n), stub)) } else { Ok(Number::Integer(binary_pow(n1, n2))) - }, + } + } (n1, Number::Integer(n2)) => { let f1 = self.float(n1)?; let f2 = self.float(Number::Integer(n2))?; self.unary_float_fn_template(Number::Float(OrderedFloat(f1)), |f| f.powf(f2)) .map(|f| Number::Float(OrderedFloat(f))) - }, + } (n1, n2) => { let f2 = self.float(n2)?; if n1.is_negative() && f2 != f2.floor() { let stub = MachineError::functor_stub(clause_name!("(is)"), 2); - return Err(self.error_form(MachineError::evaluation_error(EvalError::Undefined), stub)); + return Err( + self.error_form(MachineError::evaluation_error(EvalError::Undefined), stub) + ); } let f1 = self.float(n1)?; @@ -1051,8 +1099,7 @@ impl MachineState { } } - fn float_pow(&self, n1: Number, n2: Number) -> Result - { + fn float_pow(&self, n1: Number, n2: Number) -> Result { let f1 = result_f(&n1, rnd_f); let f2 = result_f(&n2, rnd_f); @@ -1063,26 +1110,26 @@ impl MachineState { let result = result_f(&Number::Float(OrderedFloat(f1.powf(f2))), rnd_f); - Ok(Number::Float(OrderedFloat(try_numeric_result!(self, result, stub)?))) + Ok(Number::Float(OrderedFloat(try_numeric_result!( + self, result, stub + )?))) } - fn pow(&self, n1: Number, n2: Number, culprit: &'static str) -> Result - { + fn pow(&self, n1: Number, n2: Number, culprit: &'static str) -> Result { if n2.is_negative() { let stub = MachineError::functor_stub(clause_name!(culprit), 2); return Err(self.error_form(MachineError::evaluation_error(EvalError::Undefined), stub)); } match (n1, n2) { - (Number::Integer(n1), Number::Integer(n2)) => - Ok(Number::Integer(binary_pow(n1, n2))), - (n1, n2) => - self.float_pow(n1, n2) + (Number::Integer(n1), Number::Integer(n2)) => Ok(Number::Integer(binary_pow(n1, n2))), + (n1, n2) => self.float_pow(n1, n2), } } fn unary_float_fn_template(&self, n1: Number, f: FloatFn) -> Result - where FloatFn: Fn(f64) -> f64 + where + FloatFn: Fn(f64) -> f64, { let stub = MachineError::functor_stub(clause_name!("(is)"), 2); @@ -1092,48 +1139,39 @@ impl MachineState { try_numeric_result!(self, f1, stub) } - fn sin(&self, n1: Number) -> Result - { + fn sin(&self, n1: Number) -> Result { self.unary_float_fn_template(n1, |f| f.sin()) } - fn cos(&self, n1: Number) -> Result - { + fn cos(&self, n1: Number) -> Result { self.unary_float_fn_template(n1, |f| f.cos()) } - fn tan(&self, n1: Number) -> Result - { + fn tan(&self, n1: Number) -> Result { self.unary_float_fn_template(n1, |f| f.tan()) } - fn log(&self, n1: Number) -> Result - { + fn log(&self, n1: Number) -> Result { self.unary_float_fn_template(n1, |f| f.log(f64::consts::E)) } - fn exp(&self, n1: Number) -> Result - { + fn exp(&self, n1: Number) -> Result { self.unary_float_fn_template(n1, |f| f.exp()) } - fn asin(&self, n1: Number) -> Result - { + fn asin(&self, n1: Number) -> Result { self.unary_float_fn_template(n1, |f| f.asin()) } - fn acos(&self, n1: Number) -> Result - { + fn acos(&self, n1: Number) -> Result { self.unary_float_fn_template(n1, |f| f.acos()) } - fn atan(&self, n1: Number) -> Result - { + fn atan(&self, n1: Number) -> Result { self.unary_float_fn_template(n1, |f| f.atan()) } - fn sqrt(&self, n1: Number) -> Result - { + fn sqrt(&self, n1: Number) -> Result { if n1.is_negative() { let stub = MachineError::functor_stub(clause_name!("(is)"), 2); return Err(self.error_form(MachineError::evaluation_error(EvalError::Undefined), stub)); @@ -1142,24 +1180,20 @@ impl MachineState { self.unary_float_fn_template(n1, |f| f.sqrt()) } - fn float(&self, n: Number) -> Result - { + fn float(&self, n: Number) -> Result { let stub = MachineError::functor_stub(clause_name!("(is)"), 2); try_numeric_result!(self, result_f(&n, rnd_f), stub) } - fn floor(&self, n1: Number) -> Integer - { + fn floor(&self, n1: Number) -> Integer { rnd_i(&n1).to_owned() } - fn ceiling(&self, n1: Number) -> Integer - { + fn ceiling(&self, n1: Number) -> Integer { -self.floor(-n1) } - fn truncate(&self, n: Number) -> Integer - { + fn truncate(&self, n: Number) -> Integer { if n.is_negative() { -self.floor(n.abs()) } else { @@ -1167,8 +1201,7 @@ impl MachineState { } } - fn round(&self, n: Number) -> Result - { + fn round(&self, n: Number) -> Result { let stub = MachineError::functor_stub(clause_name!("(is)"), 2); let result = n + Number::Float(OrderedFloat(0.5f64)); @@ -1177,128 +1210,120 @@ impl MachineState { Ok(self.floor(result)) } - fn shr(&self, n1: Number, n2: Number) -> Result - { + fn shr(&self, n1: Number, n2: Number) -> Result { let stub = MachineError::functor_stub(clause_name!("(>>)"), 2); match (n1, n2) { - (Number::Integer(n1), Number::Integer(n2)) => - match n2.to_u32() { - Some(n2) => Ok(n1 >> n2), - _ => Ok(n1 >> u32::max_value()) - }, - (Number::Integer(_), n2) => - Err(self.error_form(MachineError::type_error(ValidType::Integer, - Addr::Con(n2.to_constant())), - stub)), - (n1, _) => - Err(self.error_form(MachineError::type_error(ValidType::Integer, - Addr::Con(n1.to_constant())), - stub)) + (Number::Integer(n1), Number::Integer(n2)) => match n2.to_u32() { + Some(n2) => Ok(n1 >> n2), + _ => Ok(n1 >> u32::max_value()), + }, + (Number::Integer(_), n2) => Err(self.error_form( + MachineError::type_error(ValidType::Integer, Addr::Con(n2.to_constant())), + stub, + )), + (n1, _) => Err(self.error_form( + MachineError::type_error(ValidType::Integer, Addr::Con(n1.to_constant())), + stub, + )), } } - fn shl(&self, n1: Number, n2: Number) -> Result - { + fn shl(&self, n1: Number, n2: Number) -> Result { let stub = MachineError::functor_stub(clause_name!("(<<)"), 2); match (n1, n2) { - (Number::Integer(n1), Number::Integer(n2)) => - match n2.to_u32() { - Some(n2) => Ok(n1 << n2), - _ => Ok(n1 << u32::max_value()) - }, - (Number::Integer(_), n2) => - Err(self.error_form(MachineError::type_error(ValidType::Integer, - Addr::Con(n2.to_constant())), - stub)), - (n1, _) => - Err(self.error_form(MachineError::type_error(ValidType::Integer, - Addr::Con(n1.to_constant())), - stub)) + (Number::Integer(n1), Number::Integer(n2)) => match n2.to_u32() { + Some(n2) => Ok(n1 << n2), + _ => Ok(n1 << u32::max_value()), + }, + (Number::Integer(_), n2) => Err(self.error_form( + MachineError::type_error(ValidType::Integer, Addr::Con(n2.to_constant())), + stub, + )), + (n1, _) => Err(self.error_form( + MachineError::type_error(ValidType::Integer, Addr::Con(n1.to_constant())), + stub, + )), } } - fn bitwise_complement(&self, n1: Number) -> Result - { + fn bitwise_complement(&self, n1: Number) -> Result { let stub = MachineError::functor_stub(clause_name!("(\\)"), 2); match n1 { - Number::Integer(n1) => - Ok(!n1), - _ => - Err(self.error_form(MachineError::type_error(ValidType::Integer, - Addr::Con(n1.to_constant())), - stub)) + Number::Integer(n1) => Ok(!n1), + _ => Err(self.error_form( + MachineError::type_error(ValidType::Integer, Addr::Con(n1.to_constant())), + stub, + )), } } - fn xor(&self, n1: Number, n2: Number) -> Result - { + fn xor(&self, n1: Number, n2: Number) -> Result { let stub = MachineError::functor_stub(clause_name!("(xor)"), 2); match (n1, n2) { - (Number::Integer(n1), Number::Integer(n2)) => - Ok(n1 ^ n2), - (Number::Integer(_), n2) => - Err(self.error_form(MachineError::type_error(ValidType::Integer, - Addr::Con(n2.to_constant())), - stub)), - (n1, _) => - Err(self.error_form(MachineError::type_error(ValidType::Integer, - Addr::Con(n1.to_constant())), - stub)) + (Number::Integer(n1), Number::Integer(n2)) => Ok(n1 ^ n2), + (Number::Integer(_), n2) => Err(self.error_form( + MachineError::type_error(ValidType::Integer, Addr::Con(n2.to_constant())), + stub, + )), + (n1, _) => Err(self.error_form( + MachineError::type_error(ValidType::Integer, Addr::Con(n1.to_constant())), + stub, + )), } } - fn and(&self, n1: Number, n2: Number) -> Result - { + fn and(&self, n1: Number, n2: Number) -> Result { let stub = MachineError::functor_stub(clause_name!("(/\\)"), 2); match (n1, n2) { - (Number::Integer(n1), Number::Integer(n2)) => - Ok(n1 & n2), - (Number::Integer(_), n2) => - Err(self.error_form(MachineError::type_error(ValidType::Integer, - Addr::Con(n2.to_constant())), - stub)), - (n1, _) => - Err(self.error_form(MachineError::type_error(ValidType::Integer, - Addr::Con(n1.to_constant())), - stub)) + (Number::Integer(n1), Number::Integer(n2)) => Ok(n1 & n2), + (Number::Integer(_), n2) => Err(self.error_form( + MachineError::type_error(ValidType::Integer, Addr::Con(n2.to_constant())), + stub, + )), + (n1, _) => Err(self.error_form( + MachineError::type_error(ValidType::Integer, Addr::Con(n1.to_constant())), + stub, + )), } } - fn modulus(&self, x: Number, y: Number) -> Result - { + fn modulus(&self, x: Number, y: Number) -> Result { let stub = MachineError::functor_stub(clause_name!("(mod)"), 2); match (x, y) { - (Number::Integer(x), Number::Integer(y)) => + (Number::Integer(x), Number::Integer(y)) => { if y == 0 { - Err(self.error_form(MachineError::evaluation_error(EvalError::ZeroDivisor), stub)) + Err(self + .error_form(MachineError::evaluation_error(EvalError::ZeroDivisor), stub)) } else { Ok(x.div_rem_floor(y).1) - }, - (Number::Integer(_), n2) => - Err(self.error_form(MachineError::type_error(ValidType::Integer, - Addr::Con(n2.to_constant())), - stub)), - (n1, _) => - Err(self.error_form(MachineError::type_error(ValidType::Integer, - Addr::Con(n1.to_constant())), - stub)) + } + } + (Number::Integer(_), n2) => Err(self.error_form( + MachineError::type_error(ValidType::Integer, Addr::Con(n2.to_constant())), + stub, + )), + (n1, _) => Err(self.error_form( + MachineError::type_error(ValidType::Integer, Addr::Con(n1.to_constant())), + stub, + )), } } fn max(&self, n1: Number, n2: Number) -> Result { match (n1, n2) { - (Number::Integer(n1), Number::Integer(n2)) => + (Number::Integer(n1), Number::Integer(n2)) => { if n1 > n2 { Ok(Number::Integer(n1)) } else { Ok(Number::Integer(n2)) - }, + } + } (n1, n2) => { let stub = MachineError::functor_stub(clause_name!("max"), 2); @@ -1312,15 +1337,16 @@ impl MachineState { fn min(&self, n1: Number, n2: Number) -> Result { match (n1, n2) { - (Number::Integer(n1), Number::Integer(n2)) => + (Number::Integer(n1), Number::Integer(n2)) => { if n1 < n2 { Ok(Number::Integer(n1)) } else { Ok(Number::Integer(n2)) - }, + } + } (n1, n2) => { let stub = MachineError::functor_stub(clause_name!("max"), 2); - + let f1 = try_numeric_result!(self, result_f(&n1, rnd_f), stub.clone())?; let f2 = try_numeric_result!(self, result_f(&n2, rnd_f), stub)?; @@ -1329,50 +1355,46 @@ impl MachineState { } } - fn remainder(&self, n1: Number, n2: Number) -> Result - { + fn remainder(&self, n1: Number, n2: Number) -> Result { let stub = MachineError::functor_stub(clause_name!("(rem)"), 2); match (n1, n2) { - (Number::Integer(n1), Number::Integer(n2)) => + (Number::Integer(n1), Number::Integer(n2)) => { if n2 == 0 { - Err(self.error_form(MachineError::evaluation_error(EvalError::ZeroDivisor), - stub)) + Err(self + .error_form(MachineError::evaluation_error(EvalError::ZeroDivisor), stub)) } else { Ok(n1 % n2) - }, - (Number::Integer(_), n2) => - Err(self.error_form(MachineError::type_error(ValidType::Integer, - Addr::Con(n2.to_constant())), - stub)), - (n1, _) => - Err(self.error_form(MachineError::type_error(ValidType::Integer, - Addr::Con(n1.to_constant())), - stub)) + } + } + (Number::Integer(_), n2) => Err(self.error_form( + MachineError::type_error(ValidType::Integer, Addr::Con(n2.to_constant())), + stub, + )), + (n1, _) => Err(self.error_form( + MachineError::type_error(ValidType::Integer, Addr::Con(n1.to_constant())), + stub, + )), } } - fn or(&self, n1: Number, n2: Number) -> Result - { + fn or(&self, n1: Number, n2: Number) -> Result { let stub = MachineError::functor_stub(clause_name!("(\\/)"), 2); match (n1, n2) { - (Number::Integer(n1), Number::Integer(n2)) => - Ok(n1 | n2), - (Number::Integer(_), n2) => - Err(self.error_form(MachineError::type_error(ValidType::Integer, - Addr::Con(n2.to_constant())), - stub)), - (n1, _) => - Err(self.error_form(MachineError::type_error(ValidType::Integer, - Addr::Con(n1.to_constant())), - stub)) + (Number::Integer(n1), Number::Integer(n2)) => Ok(n1 | n2), + (Number::Integer(_), n2) => Err(self.error_form( + MachineError::type_error(ValidType::Integer, Addr::Con(n2.to_constant())), + stub, + )), + (n1, _) => Err(self.error_form( + MachineError::type_error(ValidType::Integer, Addr::Con(n1.to_constant())), + stub, + )), } } - pub(super) - fn execute_arith_instr(&mut self, instr: &ArithmeticInstruction) - { + pub(super) fn execute_arith_instr(&mut self, instr: &ArithmeticInstruction) { let stub = MachineError::functor_stub(clause_name!("(is)"), 2); match instr { @@ -1382,49 +1404,49 @@ impl MachineState { self.interms[t - 1] = try_or_fail!(self, try_numeric_result!(self, n1 + n2, stub)); self.p += 1; - }, + } &ArithmeticInstruction::Sub(ref a1, ref a2, t) => { let n1 = try_or_fail!(self, self.get_number(a1)); let n2 = try_or_fail!(self, self.get_number(a2)); self.interms[t - 1] = try_or_fail!(self, try_numeric_result!(self, n1 - n2, stub)); self.p += 1; - }, + } &ArithmeticInstruction::Mul(ref a1, ref a2, t) => { let n1 = try_or_fail!(self, self.get_number(a1)); let n2 = try_or_fail!(self, self.get_number(a2)); self.interms[t - 1] = try_or_fail!(self, try_numeric_result!(self, n1 * n2, stub)); self.p += 1; - }, + } &ArithmeticInstruction::Max(ref a1, ref a2, t) => { let n1 = try_or_fail!(self, self.get_number(a1)); let n2 = try_or_fail!(self, self.get_number(a2)); self.interms[t - 1] = try_or_fail!(self, self.max(n1, n2)); self.p += 1; - }, + } &ArithmeticInstruction::Min(ref a1, ref a2, t) => { let n1 = try_or_fail!(self, self.get_number(a1)); let n2 = try_or_fail!(self, self.get_number(a2)); self.interms[t - 1] = try_or_fail!(self, self.min(n1, n2)); self.p += 1; - }, + } &ArithmeticInstruction::IntPow(ref a1, ref a2, t) => { let n1 = try_or_fail!(self, self.get_number(a1)); let n2 = try_or_fail!(self, self.get_number(a2)); self.interms[t - 1] = try_or_fail!(self, self.int_pow(n1, n2)); self.p += 1; - }, + } &ArithmeticInstruction::Pow(ref a1, ref a2, t) => { let n1 = try_or_fail!(self, self.get_number(a1)); let n2 = try_or_fail!(self, self.get_number(a2)); self.interms[t - 1] = try_or_fail!(self, self.pow(n1, n2, "(**)")); self.p += 1; - }, + } &ArithmeticInstruction::RDiv(ref a1, ref a2, t) => { let stub = MachineError::functor_stub(clause_name!("(rdiv)"), 2); @@ -1433,192 +1455,200 @@ impl MachineState { self.interms[t - 1] = Number::Rational(try_or_fail!(self, self.rdiv(r1, r2))); self.p += 1; - }, + } &ArithmeticInstruction::IntFloorDiv(ref a1, ref a2, t) => { let n1 = try_or_fail!(self, self.get_number(a1)); let n2 = try_or_fail!(self, self.get_number(a2)); - self.interms[t - 1] = Number::Integer(try_or_fail!(self, self.int_floor_div(n1, n2))); + self.interms[t - 1] = + Number::Integer(try_or_fail!(self, self.int_floor_div(n1, n2))); self.p += 1; - }, + } &ArithmeticInstruction::IDiv(ref a1, ref a2, t) => { let n1 = try_or_fail!(self, self.get_number(a1)); let n2 = try_or_fail!(self, self.get_number(a2)); self.interms[t - 1] = Number::Integer(try_or_fail!(self, self.idiv(n1, n2))); self.p += 1; - }, + } &ArithmeticInstruction::Abs(ref a1, t) => { let n1 = try_or_fail!(self, self.get_number(a1)); self.interms[t - 1] = n1.abs(); self.p += 1; - }, + } &ArithmeticInstruction::Neg(ref a1, t) => { let n1 = try_or_fail!(self, self.get_number(a1)); - self.interms[t - 1] = - n1; + self.interms[t - 1] = -n1; self.p += 1; - }, + } &ArithmeticInstruction::BitwiseComplement(ref a1, t) => { let n1 = try_or_fail!(self, self.get_number(a1)); - self.interms[t - 1] = Number::Integer(try_or_fail!(self, self.bitwise_complement(n1))); + self.interms[t - 1] = + Number::Integer(try_or_fail!(self, self.bitwise_complement(n1))); self.p += 1; - }, + } &ArithmeticInstruction::Div(ref a1, ref a2, t) => { let n1 = try_or_fail!(self, self.get_number(a1)); let n2 = try_or_fail!(self, self.get_number(a2)); self.interms[t - 1] = try_or_fail!(self, self.div(n1, n2)); self.p += 1; - }, + } &ArithmeticInstruction::Shr(ref a1, ref a2, t) => { let n1 = try_or_fail!(self, self.get_number(a1)); let n2 = try_or_fail!(self, self.get_number(a2)); self.interms[t - 1] = Number::Integer(try_or_fail!(self, self.shr(n1, n2))); self.p += 1; - }, + } &ArithmeticInstruction::Shl(ref a1, ref a2, t) => { let n1 = try_or_fail!(self, self.get_number(a1)); let n2 = try_or_fail!(self, self.get_number(a2)); self.interms[t - 1] = Number::Integer(try_or_fail!(self, self.shl(n1, n2))); self.p += 1; - }, + } &ArithmeticInstruction::Xor(ref a1, ref a2, t) => { let n1 = try_or_fail!(self, self.get_number(a1)); let n2 = try_or_fail!(self, self.get_number(a2)); self.interms[t - 1] = Number::Integer(try_or_fail!(self, self.xor(n1, n2))); self.p += 1; - }, + } &ArithmeticInstruction::And(ref a1, ref a2, t) => { let n1 = try_or_fail!(self, self.get_number(a1)); let n2 = try_or_fail!(self, self.get_number(a2)); self.interms[t - 1] = Number::Integer(try_or_fail!(self, self.and(n1, n2))); self.p += 1; - }, + } &ArithmeticInstruction::Or(ref a1, ref a2, t) => { let n1 = try_or_fail!(self, self.get_number(a1)); let n2 = try_or_fail!(self, self.get_number(a2)); self.interms[t - 1] = Number::Integer(try_or_fail!(self, self.or(n1, n2))); self.p += 1; - }, + } &ArithmeticInstruction::Mod(ref a1, ref a2, t) => { let n1 = try_or_fail!(self, self.get_number(a1)); let n2 = try_or_fail!(self, self.get_number(a2)); self.interms[t - 1] = Number::Integer(try_or_fail!(self, self.modulus(n1, n2))); self.p += 1; - }, + } &ArithmeticInstruction::Rem(ref a1, ref a2, t) => { let n1 = try_or_fail!(self, self.get_number(a1)); let n2 = try_or_fail!(self, self.get_number(a2)); self.interms[t - 1] = Number::Integer(try_or_fail!(self, self.remainder(n1, n2))); self.p += 1; - }, + } &ArithmeticInstruction::Cos(ref a1, t) => { let n1 = try_or_fail!(self, self.get_number(a1)); self.interms[t - 1] = Number::Float(OrderedFloat(try_or_fail!(self, self.cos(n1)))); self.p += 1; - }, + } &ArithmeticInstruction::Sin(ref a1, t) => { let n1 = try_or_fail!(self, self.get_number(a1)); self.interms[t - 1] = Number::Float(OrderedFloat(try_or_fail!(self, self.sin(n1)))); self.p += 1; - }, + } &ArithmeticInstruction::Tan(ref a1, t) => { let n1 = try_or_fail!(self, self.get_number(a1)); self.interms[t - 1] = Number::Float(OrderedFloat(try_or_fail!(self, self.tan(n1)))); self.p += 1; - }, + } &ArithmeticInstruction::Sqrt(ref a1, t) => { let n1 = try_or_fail!(self, self.get_number(a1)); - self.interms[t - 1] = Number::Float(OrderedFloat(try_or_fail!(self, self.sqrt(n1)))); + self.interms[t - 1] = + Number::Float(OrderedFloat(try_or_fail!(self, self.sqrt(n1)))); self.p += 1; - }, + } &ArithmeticInstruction::Log(ref a1, t) => { let n1 = try_or_fail!(self, self.get_number(a1)); self.interms[t - 1] = Number::Float(OrderedFloat(try_or_fail!(self, self.log(n1)))); self.p += 1; - }, + } &ArithmeticInstruction::Exp(ref a1, t) => { let n1 = try_or_fail!(self, self.get_number(a1)); self.interms[t - 1] = Number::Float(OrderedFloat(try_or_fail!(self, self.exp(n1)))); self.p += 1; - }, + } &ArithmeticInstruction::ACos(ref a1, t) => { let n1 = try_or_fail!(self, self.get_number(a1)); - self.interms[t - 1] = Number::Float(OrderedFloat(try_or_fail!(self, self.acos(n1)))); + self.interms[t - 1] = + Number::Float(OrderedFloat(try_or_fail!(self, self.acos(n1)))); self.p += 1; - }, + } &ArithmeticInstruction::ASin(ref a1, t) => { let n1 = try_or_fail!(self, self.get_number(a1)); - self.interms[t - 1] = Number::Float(OrderedFloat(try_or_fail!(self, self.asin(n1)))); + self.interms[t - 1] = + Number::Float(OrderedFloat(try_or_fail!(self, self.asin(n1)))); self.p += 1; - }, + } &ArithmeticInstruction::ATan(ref a1, t) => { let n1 = try_or_fail!(self, self.get_number(a1)); - self.interms[t - 1] = Number::Float(OrderedFloat(try_or_fail!(self, self.atan(n1)))); + self.interms[t - 1] = + Number::Float(OrderedFloat(try_or_fail!(self, self.atan(n1)))); self.p += 1; - }, + } &ArithmeticInstruction::ATan2(ref a1, ref a2, t) => { let n1 = try_or_fail!(self, self.get_number(a1)); let n2 = try_or_fail!(self, self.get_number(a2)); - self.interms[t - 1] = Number::Float(OrderedFloat(try_or_fail!(self, self.atan2(n1, n2)))); + self.interms[t - 1] = + Number::Float(OrderedFloat(try_or_fail!(self, self.atan2(n1, n2)))); self.p += 1; - }, + } &ArithmeticInstruction::Float(ref a1, t) => { let n1 = try_or_fail!(self, self.get_number(a1)); - self.interms[t - 1] = Number::Float(OrderedFloat(try_or_fail!(self, self.float(n1)))); + self.interms[t - 1] = + Number::Float(OrderedFloat(try_or_fail!(self, self.float(n1)))); self.p += 1; - }, + } &ArithmeticInstruction::Truncate(ref a1, t) => { let n1 = try_or_fail!(self, self.get_number(a1)); self.interms[t - 1] = Number::Integer(self.truncate(n1)); self.p += 1; - }, + } &ArithmeticInstruction::Round(ref a1, t) => { let n1 = try_or_fail!(self, self.get_number(a1)); self.interms[t - 1] = Number::Integer(try_or_fail!(self, self.round(n1))); self.p += 1; - }, + } &ArithmeticInstruction::Ceiling(ref a1, t) => { let n1 = try_or_fail!(self, self.get_number(a1)); self.interms[t - 1] = Number::Integer(self.ceiling(n1)); self.p += 1; - }, + } &ArithmeticInstruction::Floor(ref a1, t) => { let n1 = try_or_fail!(self, self.get_number(a1)); self.interms[t - 1] = Number::Integer(self.floor(n1)); self.p += 1; - }, + } &ArithmeticInstruction::Plus(ref a1, t) => { let n1 = try_or_fail!(self, self.get_number(a1)); self.interms[t - 1] = n1; self.p += 1; - }, + } }; } @@ -1626,13 +1656,16 @@ impl MachineState { let h = self.heap.h; if let Some(c) = s.head() { - self.heap.push(HeapCellValue::Addr(Addr::Con(Constant::Char(c)))); - self.heap.push(HeapCellValue::Addr(Addr::Con(Constant::String(s.tail())))); + self.heap + .push(HeapCellValue::Addr(Addr::Con(Constant::Char(c)))); + self.heap + .push(HeapCellValue::Addr(Addr::Con(Constant::String(s.tail())))); self.s = h; self.mode = MachineMode::Read; } else if s.is_expandable() { - self.heap.push(HeapCellValue::Addr(Addr::Con(Constant::String(s.clone())))); + self.heap + .push(HeapCellValue::Addr(Addr::Con(Constant::String(s.clone())))); self.s = h; self.mode = MachineMode::Read; @@ -1645,13 +1678,16 @@ impl MachineState { let h = self.heap.h; if let Some(c) = s.head() { - self.heap.push(HeapCellValue::Addr(Addr::Con(Constant::CharCode(c as u8)))); - self.heap.push(HeapCellValue::Addr(Addr::Con(Constant::String(s.tail())))); + self.heap + .push(HeapCellValue::Addr(Addr::Con(Constant::CharCode(c as u8)))); + self.heap + .push(HeapCellValue::Addr(Addr::Con(Constant::String(s.tail())))); self.s = h; self.mode = MachineMode::Read; } else if s.is_expandable() { - self.heap.push(HeapCellValue::Addr(Addr::Con(Constant::String(s.clone())))); + self.heap + .push(HeapCellValue::Addr(Addr::Con(Constant::String(s.clone())))); self.s = h; self.mode = MachineMode::Read; @@ -1665,32 +1701,33 @@ impl MachineState { &FactInstruction::GetConstant(_, ref c, reg) => { let addr = self[reg].clone(); self.write_constant_to_var(addr, c.clone()); - }, + } &FactInstruction::GetList(_, reg) => { let addr = self.store(self.deref(self[reg].clone())); match addr { - Addr::Con(Constant::String(ref s)) => - match self.flags.double_quotes { - DoubleQuotes::Chars => self.get_char_list(s), - DoubleQuotes::Codes => self.get_code_list(s), - _ => self.fail = true - }, - addr @ Addr::AttrVar(_) | addr @ Addr::StackCell(..) | addr @ Addr::HeapCell(_) => { + Addr::Con(Constant::String(ref s)) => match self.flags.double_quotes { + DoubleQuotes::Chars => self.get_char_list(s), + DoubleQuotes::Codes => self.get_code_list(s), + _ => self.fail = true, + }, + addr @ Addr::AttrVar(_) + | addr @ Addr::StackCell(..) + | addr @ Addr::HeapCell(_) => { let h = self.heap.h; - self.heap.push(HeapCellValue::Addr(Addr::Lis(h+1))); + self.heap.push(HeapCellValue::Addr(Addr::Lis(h + 1))); self.bind(addr.as_var().unwrap(), Addr::HeapCell(h)); self.mode = MachineMode::Write; - }, + } Addr::Lis(a) => { self.s = a; self.mode = MachineMode::Read; - }, - _ => self.fail = true + } + _ => self.fail = true, }; - }, + } &FactInstruction::GetStructure(ref ct, arity, reg) => { let addr = self.deref(self[reg].clone()); @@ -1706,45 +1743,44 @@ impl MachineState { self.fail = true; } } - }, + } Addr::AttrVar(_) | Addr::HeapCell(_) | Addr::StackCell(_, _) => { let h = self.heap.h; self.heap.push(HeapCellValue::Addr(Addr::Str(h + 1))); - self.heap.push(HeapCellValue::NamedStr(arity, ct.name(), ct.spec())); + self.heap + .push(HeapCellValue::NamedStr(arity, ct.name(), ct.spec())); self.bind(addr.as_var().unwrap(), Addr::HeapCell(h)); self.mode = MachineMode::Write; - }, - _ => self.fail = true + } + _ => self.fail = true, }; - }, - &FactInstruction::GetVariable(norm, arg) => - self[norm] = self.registers[arg].clone(), + } + &FactInstruction::GetVariable(norm, arg) => self[norm] = self.registers[arg].clone(), &FactInstruction::GetValue(norm, arg) => { let norm_addr = self[norm].clone(); - let reg_addr = self.registers[arg].clone(); + let reg_addr = self.registers[arg].clone(); self.unify(norm_addr, reg_addr); - }, + } &FactInstruction::UnifyConstant(ref c) => { match self.mode { - MachineMode::Read => { + MachineMode::Read => { let addr = Addr::HeapCell(self.s); self.write_constant_to_var(addr, c.clone()); - }, + } MachineMode::Write => { self.heap.push(HeapCellValue::Addr(Addr::Con(c.clone()))); } }; self.s += 1; - }, + } &FactInstruction::UnifyVariable(reg) => { match self.mode { - MachineMode::Read => - self[reg] = self.heap[self.s].as_addr(self.s), + MachineMode::Read => self[reg] = self.heap[self.s].as_addr(self.s), MachineMode::Write => { let h = self.heap.h; @@ -1754,18 +1790,18 @@ impl MachineState { }; self.s += 1; - }, + } &FactInstruction::UnifyLocalValue(reg) => { let s = self.s; match self.mode { - MachineMode::Read => { + MachineMode::Read => { let reg_addr = self[reg].clone(); self.unify(reg_addr, Addr::HeapCell(s)); - }, + } MachineMode::Write => { let addr = self.deref(self[reg].clone()); - let h = self.heap.h; + let h = self.heap.h; if let Addr::HeapCell(hc) = addr { if hc < h { @@ -1784,15 +1820,15 @@ impl MachineState { }; self.s += 1; - }, + } &FactInstruction::UnifyValue(reg) => { let s = self.s; match self.mode { - MachineMode::Read => { + MachineMode::Read => { let reg_addr = self[reg].clone(); self.unify(reg_addr, Addr::HeapCell(s)); - }, + } MachineMode::Write => { let heap_val = self.store(self[reg].clone()); self.heap.push(HeapCellValue::Addr(heap_val)); @@ -1800,15 +1836,14 @@ impl MachineState { }; self.s += 1; - }, + } &FactInstruction::UnifyVoid(n) => { match self.mode { - MachineMode::Read => - self.s += n, + MachineMode::Read => self.s += n, MachineMode::Write => { let h = self.heap.h; - for i in h .. h + n { + for i in h..h + n { self.heap.push(HeapCellValue::Addr(Addr::HeapCell(i))); } } @@ -1825,8 +1860,13 @@ impl MachineState { let offset = match addr { Addr::HeapCell(_) | Addr::StackCell(..) | Addr::AttrVar(..) => v, - Addr::Con(Constant::String(ref s)) if !self.flags.double_quotes.is_atom() => - if s.is_empty() && !s.is_expandable() { c } else { l }, + Addr::Con(Constant::String(ref s)) if !self.flags.double_quotes.is_atom() => { + if s.is_empty() && !s.is_expandable() { + c + } else { + l + } + } Addr::Con(_) => c, Addr::Lis(_) => l, Addr::Str(_) => s, @@ -1838,28 +1878,26 @@ impl MachineState { match offset { 0 => self.fail = true, - o => self.p += o + o => self.p += o, }; - }, + } &IndexingInstruction::SwitchOnConstant(_, ref hm) => { let a1 = self.registers[1].clone(); let addr = self.store(self.deref(a1)); let offset = match addr { - Addr::Con(constant) => { - match hm.get(&constant) { - Some(offset) => *offset, - _ => 0 - } + Addr::Con(constant) => match hm.get(&constant) { + Some(offset) => *offset, + _ => 0, }, - _ => 0 + _ => 0, }; match offset { 0 => self.fail = true, o => self.p += o, }; - }, + } &IndexingInstruction::SwitchOnStructure(_, ref hm) => { let a1 = self.registers[1].clone(); let addr = self.store(self.deref(a1)); @@ -1869,18 +1907,18 @@ impl MachineState { if let &HeapCellValue::NamedStr(arity, ref name, _) = &self.heap[s] { match hm.get(&(name.clone(), arity)) { Some(offset) => *offset, - _ => 0 + _ => 0, } } else { 0 } - }, - _ => 0 + } + _ => 0, }; match offset { 0 => self.fail = true, - o => self.p += o + o => self.p += o, }; } }; @@ -1888,20 +1926,20 @@ impl MachineState { pub(super) fn execute_query_instr(&mut self, instr: &QueryInstruction) { match instr { - &QueryInstruction::GetVariable(norm, arg) => - self[norm] = self.registers[arg].clone(), - &QueryInstruction::PutConstant(_, ref constant, reg) => - self[reg] = Addr::Con(constant.clone()), - &QueryInstruction::PutList(_, reg) => - self[reg] = Addr::Lis(self.heap.h), + &QueryInstruction::GetVariable(norm, arg) => self[norm] = self.registers[arg].clone(), + &QueryInstruction::PutConstant(_, ref constant, reg) => { + self[reg] = Addr::Con(constant.clone()) + } + &QueryInstruction::PutList(_, reg) => self[reg] = Addr::Lis(self.heap.h), &QueryInstruction::PutStructure(ref ct, arity, reg) => { let h = self.heap.h; - self.heap.push(HeapCellValue::NamedStr(arity, ct.name(), ct.spec())); + self.heap + .push(HeapCellValue::NamedStr(arity, ct.name(), ct.spec())); self[reg] = Addr::Str(h); - }, + } &QueryInstruction::PutUnsafeValue(n, arg) => { - let e = self.e; + let e = self.e; let addr = self.deref(Addr::StackCell(e, n)); if addr.is_protected(e) { @@ -1914,9 +1952,8 @@ impl MachineState { self.registers[arg] = self.heap[h].as_addr(h); } - }, - &QueryInstruction::PutValue(norm, arg) => - self.registers[arg] = self[norm].clone(), + } + &QueryInstruction::PutValue(norm, arg) => self.registers[arg] = self[norm].clone(), &QueryInstruction::PutVariable(norm, arg) => { match norm { RegType::Perm(n) => { @@ -1924,7 +1961,7 @@ impl MachineState { self[norm] = Addr::StackCell(e, n); self.registers[arg] = self[norm].clone(); - }, + } RegType::Temp(_) => { let h = self.heap.h; self.heap.push(HeapCellValue::Addr(Addr::HeapCell(h))); @@ -1933,13 +1970,13 @@ impl MachineState { self.registers[arg] = Addr::HeapCell(h); } }; - }, + } &QueryInstruction::SetConstant(ref c) => { self.heap.push(HeapCellValue::Addr(Addr::Con(c.clone()))); - }, + } &QueryInstruction::SetLocalValue(reg) => { let addr = self.deref(self[reg].clone()); - let h = self.heap.h; + let h = self.heap.h; if let Addr::HeapCell(hc) = addr { if hc < h { @@ -1951,33 +1988,32 @@ impl MachineState { self.heap.push(HeapCellValue::Addr(Addr::HeapCell(h))); self.bind(Ref::HeapCell(h), addr); - }, + } &QueryInstruction::SetVariable(reg) => { let h = self.heap.h; self.heap.push(HeapCellValue::Addr(Addr::HeapCell(h))); self[reg] = Addr::HeapCell(h); - }, + } &QueryInstruction::SetValue(reg) => { let heap_val = self[reg].clone(); self.heap.push(HeapCellValue::Addr(heap_val)); - }, + } &QueryInstruction::SetVoid(n) => { let h = self.heap.h; - for i in h .. h + n { + for i in h..h + n { self.heap.push(HeapCellValue::Addr(Addr::HeapCell(i))); } } } } - pub(super) fn handle_internal_call_n(&mut self, arity: usize) - { + pub(super) fn handle_internal_call_n(&mut self, arity: usize) { let arity = arity + 1; - let pred = self.registers[1].clone(); + let pred = self.registers[1].clone(); - for i in 2 .. arity { - self.registers[i-1] = self.registers[i].clone(); + for i in 2..arity { + self.registers[i - 1] = self.registers[i].clone(); } if arity > 1 { @@ -1991,11 +2027,13 @@ impl MachineState { pub(super) fn set_ball(&mut self) { let addr = self[temp_v!(1)].clone(); self.ball.boundary = self.heap.h; - copy_term(CopyBallTerm::new(&mut self.and_stack, &mut self.heap, &mut self.ball.stub), addr); + copy_term( + CopyBallTerm::new(&mut self.and_stack, &mut self.heap, &mut self.ball.stub), + addr, + ); } - pub(super) fn setup_call_n(&mut self, arity: usize) -> Option - { + pub(super) fn setup_call_n(&mut self, arity: usize) -> Option { let stub = MachineError::functor_stub(clause_name!("call"), arity + 1); let addr = self.store(self.deref(self.registers[arity].clone())); @@ -2005,18 +2043,20 @@ impl MachineState { if let HeapCellValue::NamedStr(narity, name, _) = result { if narity + arity > 63 { - let representation_error = - self.error_form(MachineError::representation_error(RepFlag::MaxArity), stub); + let representation_error = self.error_form( + MachineError::representation_error(RepFlag::MaxArity), + stub, + ); self.throw_exception(representation_error); return None; } - for i in (1 .. arity).rev() { + for i in (1..arity).rev() { self.registers[i + narity] = self.registers[i].clone(); } - for i in 1 .. narity + 1 { + for i in 1..narity + 1 { self.registers[i] = self.heap[a + i].as_addr(a + i); } @@ -2025,16 +2065,18 @@ impl MachineState { self.fail = true; return None; } - }, + } Addr::Con(Constant::Atom(name, _)) => (name, 0), Addr::HeapCell(_) | Addr::StackCell(_, _) => { - let instantiation_error = self.error_form(MachineError::instantiation_error(), stub); + let instantiation_error = + self.error_form(MachineError::instantiation_error(), stub); self.throw_exception(instantiation_error); return None; - }, + } _ => { - let type_error = self.error_form(MachineError::type_error(ValidType::Callable, addr), stub); + let type_error = + self.error_form(MachineError::type_error(ValidType::Callable, addr), stub); self.throw_exception(type_error); return None; @@ -2059,12 +2101,12 @@ impl MachineState { let diff = self.heap_ball_boundary_diff(); let mut stub = vec![]; - for index in 0 .. self.ball.stub.len() { + for index in 0..self.ball.stub.len() { let heap_value = self.ball.stub[index].clone(); stub.push(match heap_value { HeapCellValue::Addr(addr) => HeapCellValue::Addr(addr - diff), - _ => heap_value + _ => heap_value, }); } @@ -2095,14 +2137,16 @@ impl MachineState { } // arg(+N, +Term, ?Arg) - pub(super) fn try_arg(&mut self) -> CallResult - { + pub(super) fn try_arg(&mut self) -> CallResult { let stub = MachineError::functor_stub(clause_name!("arg"), 3); let n = self.store(self.deref(self[temp_v!(1)].clone())); match n { - Addr::HeapCell(_) | Addr::StackCell(..) => // 8.5.2.3 a) - return Err(self.error_form(MachineError::instantiation_error(), stub)), + Addr::HeapCell(_) | Addr::StackCell(..) => + // 8.5.2.3 a) + { + return Err(self.error_form(MachineError::instantiation_error(), stub)) + } Addr::Con(Constant::Integer(n)) => { if n < 0 { // 8.5.2.3 e) @@ -2123,55 +2167,63 @@ impl MachineState { let term = self.store(self.deref(self[temp_v!(2)].clone())); match term { - Addr::HeapCell(_) | Addr::StackCell(..) => // 8.5.2.3 b) - return Err(self.error_form(MachineError::instantiation_error(), stub)), - Addr::Str(o) => - match self.heap[o].clone() { - HeapCellValue::NamedStr(arity, _, _) if 1 <= n && n <= arity => { - let a3 = self[temp_v!(3)].clone(); - let h_a = Addr::HeapCell(o + n); - - self.unify(a3, h_a); - }, - _ => self.fail = true - }, - Addr::Lis(l) => + Addr::HeapCell(_) | Addr::StackCell(..) => + // 8.5.2.3 b) + { + return Err(self.error_form(MachineError::instantiation_error(), stub)) + } + Addr::Str(o) => match self.heap[o].clone() { + HeapCellValue::NamedStr(arity, _, _) if 1 <= n && n <= arity => { + let a3 = self[temp_v!(3)].clone(); + let h_a = Addr::HeapCell(o + n); + + self.unify(a3, h_a); + } + _ => self.fail = true, + }, + Addr::Lis(l) => { if n == 1 || n == 2 { - let a3 = self[temp_v!(3)].clone(); + let a3 = self[temp_v!(3)].clone(); let h_a = Addr::HeapCell(l + n - 1); self.unify(a3, h_a); } else { self.fail = true; - }, + } + } Addr::Con(Constant::String(ref s)) - if !self.flags.double_quotes.is_atom() && !s.is_empty() => { - if n == 1 || n == 2 { - let a3 = self[temp_v!(3)].clone(); - let h_a = if n == 1 { - if self.flags.double_quotes.is_chars() { - Addr::Con(Constant::Char(s.head().unwrap())) - } else { - Addr::Con(Constant::CharCode(s.head().unwrap() as u8)) - } + if !self.flags.double_quotes.is_atom() && !s.is_empty() => + { + if n == 1 || n == 2 { + let a3 = self[temp_v!(3)].clone(); + let h_a = if n == 1 { + if self.flags.double_quotes.is_chars() { + Addr::Con(Constant::Char(s.head().unwrap())) } else { - Addr::Con(Constant::String(s.tail())) - }; - - self.unify(a3, h_a); + Addr::Con(Constant::CharCode(s.head().unwrap() as u8)) + } } else { - self.fail = true; - } + Addr::Con(Constant::String(s.tail())) + }; + + self.unify(a3, h_a); + } else { + self.fail = true; } - _ => // 8.5.2.3 d) - return Err(self.error_form(MachineError::type_error(ValidType::Compound, term), - stub)) + } + _ => + // 8.5.2.3 d) + { + return Err(self + .error_form(MachineError::type_error(ValidType::Compound, term), stub)) + } } - - - }, - _ => // 8.5.2.3 c) + } + _ => + // 8.5.2.3 c) + { return Err(self.error_form(MachineError::type_error(ValidType::Integer, n), stub)) + } } Ok(()) @@ -2187,7 +2239,7 @@ impl MachineState { CompareNumberQT::LessThanOrEqual if ordering != Ordering::Greater => false, CompareNumberQT::NotEqual if ordering != Ordering::Equal => false, CompareNumberQT::Equal if ordering == Ordering::Equal => false, - _ => true + _ => true, }; self.p += 1; @@ -2198,27 +2250,23 @@ impl MachineState { let a2 = self[temp_v!(2)].clone(); match self.compare_term_test(&a1, &a2) { - Ordering::Greater => - match qt { - CompareTermQT::GreaterThan | CompareTermQT::GreaterThanOrEqual => return, - _ => self.fail = true - }, - Ordering::Equal => - match qt { - CompareTermQT::GreaterThanOrEqual | CompareTermQT::LessThanOrEqual => return, - _ => self.fail = true - }, - Ordering::Less => - match qt { - CompareTermQT::LessThan | CompareTermQT::LessThanOrEqual => return, - _ => self.fail = true - } + Ordering::Greater => match qt { + CompareTermQT::GreaterThan | CompareTermQT::GreaterThanOrEqual => return, + _ => self.fail = true, + }, + Ordering::Equal => match qt { + CompareTermQT::GreaterThanOrEqual | CompareTermQT::LessThanOrEqual => return, + _ => self.fail = true, + }, + Ordering::Less => match qt { + CompareTermQT::LessThan | CompareTermQT::LessThanOrEqual => return, + _ => self.fail = true, + }, }; } // returns true on failure. - pub(super) fn eq_test(&self) -> bool - { + pub(super) fn eq_test(&self) -> bool { let a1 = self[temp_v!(1)].clone(); let a2 = self[temp_v!(2)].clone(); @@ -2226,17 +2274,18 @@ impl MachineState { while let Some((v1, v2)) = iter.next() { match (v1, v2) { - (HeapCellValue::NamedStr(ar1, n1, _), HeapCellValue::NamedStr(ar2, n2, _)) => + (HeapCellValue::NamedStr(ar1, n1, _), HeapCellValue::NamedStr(ar2, n2, _)) => { if ar1 != ar2 || n1 != n2 { return true; - }, - (HeapCellValue::Addr(Addr::Lis(_)), HeapCellValue::Addr(Addr::Lis(_))) => - continue, - (HeapCellValue::Addr(a1), HeapCellValue::Addr(a2)) => + } + } + (HeapCellValue::Addr(Addr::Lis(_)), HeapCellValue::Addr(Addr::Lis(_))) => continue, + (HeapCellValue::Addr(a1), HeapCellValue::Addr(a2)) => { if a1 != a2 { return true; - }, - _ => return true + } + } + _ => return true, } } @@ -2249,131 +2298,190 @@ impl MachineState { while let Some((v1, v2)) = iter.next() { match (v1, v2) { - (HeapCellValue::Addr(Addr::Lis(_)), HeapCellValue::Addr(Addr::Con(Constant::String(_)))) - | (HeapCellValue::Addr(Addr::Con(Constant::String(_))), HeapCellValue::Addr(Addr::Lis(_))) - if !self.flags.double_quotes.is_atom() => {}, - (HeapCellValue::Addr(Addr::Con(Constant::EmptyList)), - HeapCellValue::Addr(Addr::Con(Constant::String(ref s)))) - if !self.flags.double_quotes.is_atom() => if s.is_empty() { + ( + HeapCellValue::Addr(Addr::Lis(_)), + HeapCellValue::Addr(Addr::Con(Constant::String(_))), + ) + | ( + HeapCellValue::Addr(Addr::Con(Constant::String(_))), + HeapCellValue::Addr(Addr::Lis(_)), + ) if !self.flags.double_quotes.is_atom() => {} + ( + HeapCellValue::Addr(Addr::Con(Constant::EmptyList)), + HeapCellValue::Addr(Addr::Con(Constant::String(ref s))), + ) if !self.flags.double_quotes.is_atom() => { + if s.is_empty() { return Ordering::Equal; } else { return Ordering::Greater; - }, - (HeapCellValue::Addr(Addr::Con(Constant::Atom(atom, _))), - HeapCellValue::Addr(Addr::Con(Constant::Char(c)))) => + } + } + ( + HeapCellValue::Addr(Addr::Con(Constant::Atom(atom, _))), + HeapCellValue::Addr(Addr::Con(Constant::Char(c))), + ) => { return if atom.as_str().chars().count() == 1 { atom.as_str().chars().next().cmp(&Some(c)) } else { Ordering::Greater - }, - (HeapCellValue::Addr(Addr::Con(Constant::Char(c))), - HeapCellValue::Addr(Addr::Con(Constant::Atom(atom, _)))) => + } + } + ( + HeapCellValue::Addr(Addr::Con(Constant::Char(c))), + HeapCellValue::Addr(Addr::Con(Constant::Atom(atom, _))), + ) => { return if atom.as_str().chars().count() == 1 { Some(c).cmp(&atom.as_str().chars().next()) } else { Ordering::Less - }, - (HeapCellValue::Addr(Addr::Con(Constant::String(ref s))), - HeapCellValue::Addr(Addr::Con(Constant::EmptyList))) - if !self.flags.double_quotes.is_atom() => if s.is_empty() { + } + } + ( + HeapCellValue::Addr(Addr::Con(Constant::String(ref s))), + HeapCellValue::Addr(Addr::Con(Constant::EmptyList)), + ) if !self.flags.double_quotes.is_atom() => { + if s.is_empty() { return Ordering::Equal; } else { return Ordering::Less; - }, - (HeapCellValue::Addr(Addr::HeapCell(hc1)), - 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))) => + } + } + ( + HeapCellValue::Addr(Addr::HeapCell(hc1)), + 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::AttrVar(_)), _) => - return Ordering::Less, - (HeapCellValue::Addr(Addr::StackCell(fr1, sc1)), - HeapCellValue::Addr(Addr::StackCell(fr2, sc2))) => + | (HeapCellValue::Addr(Addr::AttrVar(_)), _) => return Ordering::Less, + ( + HeapCellValue::Addr(Addr::StackCell(fr1, sc1)), + HeapCellValue::Addr(Addr::StackCell(fr2, sc2)), + ) => { if fr1 > fr2 { return Ordering::Greater; } else if fr1 < fr2 || sc1 < sc2 { return Ordering::Less; } else if sc1 > sc2 { return Ordering::Greater; - }, - (HeapCellValue::Addr(Addr::StackCell(..)), - 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::Integer(..))), - HeapCellValue::Addr(Addr::HeapCell(_))) - | (HeapCellValue::Addr(Addr::Con(Constant::Integer(..))), - HeapCellValue::Addr(Addr::AttrVar(_))) => - return Ordering::Greater, - (HeapCellValue::Addr(Addr::Con(Constant::Integer(..))), - HeapCellValue::Addr(Addr::StackCell(..))) => - return Ordering::Greater, - (HeapCellValue::Addr(Addr::Con(Constant::Integer(n1))), - HeapCellValue::Addr(Addr::Con(Constant::Integer(n2)))) => + } + } + ( + HeapCellValue::Addr(Addr::StackCell(..)), + 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::Integer(..))), + HeapCellValue::Addr(Addr::HeapCell(_)), + ) + | ( + HeapCellValue::Addr(Addr::Con(Constant::Integer(..))), + HeapCellValue::Addr(Addr::AttrVar(_)), + ) => return Ordering::Greater, + ( + HeapCellValue::Addr(Addr::Con(Constant::Integer(..))), + HeapCellValue::Addr(Addr::StackCell(..)), + ) => return Ordering::Greater, + ( + HeapCellValue::Addr(Addr::Con(Constant::Integer(n1))), + HeapCellValue::Addr(Addr::Con(Constant::Integer(n2))), + ) => { if n1 != n2 { return n1.cmp(&n2); - }, - (HeapCellValue::Addr(Addr::Con(Constant::Integer(_))), _) => - return Ordering::Less, - (HeapCellValue::Addr(Addr::Con(Constant::Float(..))), - HeapCellValue::Addr(Addr::HeapCell(_))) - | (HeapCellValue::Addr(Addr::Con(Constant::Float(..))), - HeapCellValue::Addr(Addr::AttrVar(_))) => - return Ordering::Greater, - (HeapCellValue::Addr(Addr::Con(Constant::Float(..))), - HeapCellValue::Addr(Addr::StackCell(..))) => - return Ordering::Greater, - (HeapCellValue::Addr(Addr::Con(Constant::Float(n1))), - HeapCellValue::Addr(Addr::Con(Constant::Float(n2)))) => + } + } + (HeapCellValue::Addr(Addr::Con(Constant::Integer(_))), _) => return Ordering::Less, + ( + HeapCellValue::Addr(Addr::Con(Constant::Float(..))), + HeapCellValue::Addr(Addr::HeapCell(_)), + ) + | ( + HeapCellValue::Addr(Addr::Con(Constant::Float(..))), + HeapCellValue::Addr(Addr::AttrVar(_)), + ) => return Ordering::Greater, + ( + HeapCellValue::Addr(Addr::Con(Constant::Float(..))), + HeapCellValue::Addr(Addr::StackCell(..)), + ) => return Ordering::Greater, + ( + HeapCellValue::Addr(Addr::Con(Constant::Float(n1))), + HeapCellValue::Addr(Addr::Con(Constant::Float(n2))), + ) => { if n1 != n2 { return n1.cmp(&n2); - }, - (HeapCellValue::Addr(Addr::Con(Constant::Float(_))), _) => - return Ordering::Less, - (HeapCellValue::Addr(Addr::Con(Constant::Rational(..))), - HeapCellValue::Addr(Addr::HeapCell(_))) - | (HeapCellValue::Addr(Addr::Con(Constant::Rational(..))), - HeapCellValue::Addr(Addr::AttrVar(_))) => - return Ordering::Greater, - (HeapCellValue::Addr(Addr::Con(Constant::Rational(..))), - HeapCellValue::Addr(Addr::StackCell(..))) => - return Ordering::Greater, - (HeapCellValue::Addr(Addr::Con(Constant::Rational(n1))), - HeapCellValue::Addr(Addr::Con(Constant::Rational(n2)))) => + } + } + (HeapCellValue::Addr(Addr::Con(Constant::Float(_))), _) => return Ordering::Less, + ( + HeapCellValue::Addr(Addr::Con(Constant::Rational(..))), + HeapCellValue::Addr(Addr::HeapCell(_)), + ) + | ( + HeapCellValue::Addr(Addr::Con(Constant::Rational(..))), + HeapCellValue::Addr(Addr::AttrVar(_)), + ) => return Ordering::Greater, + ( + HeapCellValue::Addr(Addr::Con(Constant::Rational(..))), + HeapCellValue::Addr(Addr::StackCell(..)), + ) => return Ordering::Greater, + ( + HeapCellValue::Addr(Addr::Con(Constant::Rational(n1))), + HeapCellValue::Addr(Addr::Con(Constant::Rational(n2))), + ) => { if n1 != n2 { return n1.cmp(&n2); - }, - (HeapCellValue::Addr(Addr::Con(Constant::Rational(_))), _) => - return Ordering::Less, - (HeapCellValue::Addr(Addr::Con(Constant::String(..))), - 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(..))) => - return Ordering::Greater, - (HeapCellValue::Addr(Addr::Con(Constant::String(_))), - HeapCellValue::Addr(Addr::Con(Constant::Integer(_)))) => - return Ordering::Greater, - (HeapCellValue::Addr(Addr::Con(Constant::String(_))), - HeapCellValue::Addr(Addr::Con(Constant::Rational(_)))) => - return Ordering::Greater, - (HeapCellValue::Addr(Addr::Con(Constant::String(_))), - HeapCellValue::Addr(Addr::Con(Constant::Float(_)))) => - return Ordering::Greater, - (HeapCellValue::Addr(Addr::Con(Constant::String(s1))), - HeapCellValue::Addr(Addr::Con(Constant::String(s2)))) => + } + } + (HeapCellValue::Addr(Addr::Con(Constant::Rational(_))), _) => { + return Ordering::Less + } + ( + HeapCellValue::Addr(Addr::Con(Constant::String(..))), + 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(..)), + ) => return Ordering::Greater, + ( + HeapCellValue::Addr(Addr::Con(Constant::String(_))), + HeapCellValue::Addr(Addr::Con(Constant::Integer(_))), + ) => return Ordering::Greater, + ( + HeapCellValue::Addr(Addr::Con(Constant::String(_))), + HeapCellValue::Addr(Addr::Con(Constant::Rational(_))), + ) => return Ordering::Greater, + ( + HeapCellValue::Addr(Addr::Con(Constant::String(_))), + HeapCellValue::Addr(Addr::Con(Constant::Float(_))), + ) => return Ordering::Greater, + ( + HeapCellValue::Addr(Addr::Con(Constant::String(s1))), + HeapCellValue::Addr(Addr::Con(Constant::String(s2))), + ) => { return if s1.is_expandable() { if s2.is_expandable() { s1.cmp(&s2) @@ -2386,48 +2494,58 @@ impl MachineState { } else { s1.cmp(&s2) } - }, - (HeapCellValue::Addr(Addr::Con(Constant::String(_))), _) => - return Ordering::Less, - (HeapCellValue::Addr(Addr::Con(Constant::Atom(..))), - 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(..))) => - return Ordering::Greater, - (HeapCellValue::Addr(Addr::Con(Constant::Atom(..))), - HeapCellValue::Addr(Addr::Con(Constant::Float(_)))) => - return Ordering::Greater, - (HeapCellValue::Addr(Addr::Con(Constant::Atom(..))), - HeapCellValue::Addr(Addr::Con(Constant::Integer(_)))) => - return Ordering::Greater, - (HeapCellValue::Addr(Addr::Con(Constant::Atom(..))), - HeapCellValue::Addr(Addr::Con(Constant::Rational(_)))) => - return Ordering::Greater, - (HeapCellValue::Addr(Addr::Con(Constant::Atom(..))), - HeapCellValue::Addr(Addr::Con(Constant::String(_)))) => - return Ordering::Greater, - (HeapCellValue::Addr(Addr::Con(Constant::Atom(s1, _))), - HeapCellValue::Addr(Addr::Con(Constant::Atom(s2, _)))) => + } + } + (HeapCellValue::Addr(Addr::Con(Constant::String(_))), _) => return Ordering::Less, + ( + HeapCellValue::Addr(Addr::Con(Constant::Atom(..))), + 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(..)), + ) => return Ordering::Greater, + ( + HeapCellValue::Addr(Addr::Con(Constant::Atom(..))), + HeapCellValue::Addr(Addr::Con(Constant::Float(_))), + ) => return Ordering::Greater, + ( + HeapCellValue::Addr(Addr::Con(Constant::Atom(..))), + HeapCellValue::Addr(Addr::Con(Constant::Integer(_))), + ) => return Ordering::Greater, + ( + HeapCellValue::Addr(Addr::Con(Constant::Atom(..))), + HeapCellValue::Addr(Addr::Con(Constant::Rational(_))), + ) => return Ordering::Greater, + ( + HeapCellValue::Addr(Addr::Con(Constant::Atom(..))), + HeapCellValue::Addr(Addr::Con(Constant::String(_))), + ) => return Ordering::Greater, + ( + HeapCellValue::Addr(Addr::Con(Constant::Atom(s1, _))), + HeapCellValue::Addr(Addr::Con(Constant::Atom(s2, _))), + ) => { if s1 != s2 { return s1.cmp(&s2); - }, - (HeapCellValue::Addr(Addr::Con(Constant::Atom(..))), _) => - return Ordering::Less, - (HeapCellValue::NamedStr(ar1, n1, _), HeapCellValue::NamedStr(ar2, n2, _)) => + } + } + (HeapCellValue::Addr(Addr::Con(Constant::Atom(..))), _) => return Ordering::Less, + (HeapCellValue::NamedStr(ar1, n1, _), HeapCellValue::NamedStr(ar2, n2, _)) => { if ar1 < ar2 { return Ordering::Less; } else if ar1 > ar2 { return Ordering::Greater; } else if n1 != n2 { return n1.cmp(&n2); - }, - (HeapCellValue::Addr(Addr::Lis(_)), HeapCellValue::Addr(Addr::Lis(_))) => - continue, + } + } + (HeapCellValue::Addr(Addr::Lis(_)), HeapCellValue::Addr(Addr::Lis(_))) => continue, (HeapCellValue::Addr(Addr::Lis(_)), HeapCellValue::NamedStr(ar, n, _)) - | (HeapCellValue::NamedStr(ar, n, _), HeapCellValue::Addr(Addr::Lis(_))) => + | (HeapCellValue::NamedStr(ar, n, _), HeapCellValue::Addr(Addr::Lis(_))) => { if ar == 2 && n.as_str() == "." { continue; } else if ar < 2 { @@ -2436,14 +2554,13 @@ impl MachineState { return Ordering::Less; } else { return n.as_str().cmp("."); - }, - (HeapCellValue::NamedStr(..), _) => - return Ordering::Greater, - (HeapCellValue::Addr(Addr::Lis(_)), _) => - return Ordering::Greater, + } + } + (HeapCellValue::NamedStr(..), _) => return Ordering::Greater, + (HeapCellValue::Addr(Addr::Lis(_)), _) => return Ordering::Greater, _ => {} } - }; + } iter.first_to_expire } @@ -2451,7 +2568,7 @@ impl MachineState { pub(super) fn reset_block(&mut self, addr: Addr) { match self.store(addr) { Addr::Con(Constant::Usize(b)) => self.block = b, - _ => self.fail = true + _ => self.fail = true, }; } @@ -2462,93 +2579,94 @@ impl MachineState { let n2 = try_or_fail!(self, self.get_number(at_2)); self.compare_numbers(cmp, n1, n2); - }, + } &InlinedClauseType::IsAtom(r1) => { let d = self.store(self.deref(self[r1].clone())); match d { Addr::Con(Constant::Atom(..)) | Addr::Con(Constant::Char(_)) => self.p += 1, Addr::Con(Constant::EmptyList) => self.p += 1, - _ => self.fail = true + _ => self.fail = true, }; - }, + } &InlinedClauseType::IsAtomic(r1) => { let d = self.store(self.deref(self[r1].clone())); match d { Addr::Con(_) => self.p += 1, - _ => self.fail = true + _ => self.fail = true, }; - }, + } &InlinedClauseType::IsInteger(r1) => { let d = self.store(self.deref(self[r1].clone())); match d { - Addr::Con(Constant::Integer(_)) => self.p += 1, + Addr::Con(Constant::Integer(_)) => self.p += 1, Addr::Con(Constant::CharCode(_)) => self.p += 1, - Addr::Con(Constant::Rational(r)) => + Addr::Con(Constant::Rational(r)) => { if r.denom() == &1 { self.p += 1; } else { self.fail = true; - }, - _ => self.fail = true + } + } + _ => self.fail = true, }; - }, + } &InlinedClauseType::IsCompound(r1) => { let d = self.store(self.deref(self[r1].clone())); match d { Addr::Str(_) | Addr::Lis(_) => self.p += 1, - _ => self.fail = true + _ => self.fail = true, }; - }, + } &InlinedClauseType::IsFloat(r1) => { let d = self.store(self.deref(self[r1].clone())); match d { Addr::Con(Constant::Float(_)) => self.p += 1, - _ => self.fail = true + _ => self.fail = true, }; - }, + } &InlinedClauseType::IsRational(r1) => { let d = self.store(self.deref(self[r1].clone())); match d { Addr::Con(Constant::Rational(_)) => self.p += 1, - _ => self.fail = true + _ => self.fail = true, }; - }, + } &InlinedClauseType::IsString(r1) => { let d = self.store(self.deref(self[r1].clone())); match d { Addr::Con(Constant::String(_)) => self.p += 1, - _ => self.fail = true + _ => self.fail = true, }; - }, + } &InlinedClauseType::IsNonVar(r1) => { let d = self.store(self.deref(self[r1].clone())); match d { Addr::AttrVar(_) | Addr::HeapCell(_) | Addr::StackCell(..) => self.fail = true, - _ => self.p += 1 + _ => self.p += 1, }; - }, + } &InlinedClauseType::IsVar(r1) => { let d = self.store(self.deref(self[r1].clone())); match d { - Addr::AttrVar(_) | Addr::HeapCell(_) | Addr::StackCell(_,_) => self.p += 1, - _ => self.fail = true + Addr::AttrVar(_) | Addr::HeapCell(_) | Addr::StackCell(_, _) => self.p += 1, + _ => self.fail = true, }; - }, + } &InlinedClauseType::IsPartialString(r1) => { let d = self.store(self.deref(self[r1].clone())); match d { Addr::Con(Constant::String(ref s)) if s.is_expandable() => self.p += 1, - _ => self.fail = true + _ => self.fail = true, }; } } @@ -2565,29 +2683,38 @@ impl MachineState { } } - fn try_functor_compound_case(&mut self, name: ClauseName, arity: usize, spec: Option) - { - let name = Addr::Con(Constant::Atom(name, spec)); + fn try_functor_compound_case( + &mut self, + name: ClauseName, + arity: usize, + spec: Option, + ) { + let name = Addr::Con(Constant::Atom(name, spec)); let arity = Addr::Con(Constant::Integer(Integer::from(arity))); self.try_functor_unify_components(name, arity); } - fn try_functor_fabricate_struct(&mut self, name: ClauseName, arity: isize, - spec: Option, op_dir: &OpDir, - r: Ref) - { + fn try_functor_fabricate_struct( + &mut self, + name: ClauseName, + arity: isize, + spec: Option, + op_dir: &OpDir, + r: Ref, + ) { let spec = fetch_atom_op_spec(name.clone(), spec, op_dir); let f_a = if name.as_str() == "." && arity == 2 { Addr::Lis(self.heap.h) } else { let h = self.heap.h; - self.heap.push(HeapCellValue::NamedStr(arity as usize, name, spec)); + self.heap + .push(HeapCellValue::NamedStr(arity as usize, name, spec)); Addr::Str(h) }; - for _ in 0 .. arity { + for _ in 0..arity { let h = self.heap.h; self.heap.push(HeapCellValue::Addr(Addr::HeapCell(h))); } @@ -2600,32 +2727,32 @@ impl MachineState { let a1 = self.store(self.deref(self[temp_v!(1)].clone())); match a1.clone() { - Addr::DBRef(_) => - self.fail = true, + Addr::DBRef(_) => self.fail = true, Addr::Con(Constant::String(ref s)) - if !self.flags.double_quotes.is_atom() && !s.is_empty() => { - let shared_op_desc = fetch_op_spec(clause_name!("."), 2, None, &indices.op_dir); - self.try_functor_compound_case(clause_name!("."), 2, shared_op_desc) - }, - Addr::Con(_) => - self.try_functor_unify_components(a1, Addr::Con(Constant::Integer(Integer::from(0)))), - Addr::Str(o) => - match self.heap[o].clone() { - HeapCellValue::NamedStr(arity, name, spec) => { - let spec = fetch_op_spec(name.clone(), arity, spec, &indices.op_dir); - self.try_functor_compound_case(name, arity, spec) - }, - _ => self.fail = true - }, - Addr::Lis(_) => { + if !self.flags.double_quotes.is_atom() && !s.is_empty() => + { let shared_op_desc = fetch_op_spec(clause_name!("."), 2, None, &indices.op_dir); self.try_functor_compound_case(clause_name!("."), 2, shared_op_desc) + } + Addr::Con(_) => self + .try_functor_unify_components(a1, Addr::Con(Constant::Integer(Integer::from(0)))), + Addr::Str(o) => match self.heap[o].clone() { + HeapCellValue::NamedStr(arity, name, spec) => { + let spec = fetch_op_spec(name.clone(), arity, spec, &indices.op_dir); + self.try_functor_compound_case(name, arity, spec) + } + _ => self.fail = true, }, + Addr::Lis(_) => { + let shared_op_desc = fetch_op_spec(clause_name!("."), 2, None, &indices.op_dir); + self.try_functor_compound_case(clause_name!("."), 2, shared_op_desc) + } Addr::AttrVar(..) | Addr::HeapCell(_) | Addr::StackCell(..) => { - let name = self.store(self.deref(self[temp_v!(2)].clone())); + let name = self.store(self.deref(self[temp_v!(2)].clone())); let arity = self.store(self.deref(self[temp_v!(3)].clone())); - if name.is_ref() || arity.is_ref() { // 8.5.1.3 a) & 8.5.1.3 b) + if name.is_ref() || arity.is_ref() { + // 8.5.1.3 a) & 8.5.1.3 b) return Err(self.error_form(MachineError::instantiation_error(), stub)); } @@ -2644,33 +2771,49 @@ impl MachineState { return Err(self.error_form(rep_err, stub)); } else if arity < 0 { // 8.5.1.3 g) - let arity = Integer::from(arity); - let dom_err = MachineError::domain_error(DomainError::NotLessThanZero, - Addr::Con(Constant::Integer(arity))); + let arity = Integer::from(arity); + let dom_err = MachineError::domain_error( + DomainError::NotLessThanZero, + Addr::Con(Constant::Integer(arity)), + ); return Err(self.error_form(dom_err, stub)); } match name { - Addr::Con(_) if arity == 0 => - self.unify(a1, name), - Addr::Con(Constant::Atom(name, spec)) => - self.try_functor_fabricate_struct(name, arity, spec, &indices.op_dir, - a1.as_var().unwrap()), + Addr::Con(_) if arity == 0 => self.unify(a1, name), + Addr::Con(Constant::Atom(name, spec)) => self.try_functor_fabricate_struct( + name, + arity, + spec, + &indices.op_dir, + a1.as_var().unwrap(), + ), Addr::Con(Constant::Char(c)) => { let name = clause_name!(c.to_string(), indices.atom_tbl); - self.try_functor_fabricate_struct(name, arity, None, &indices.op_dir, - a1.as_var().unwrap()); - }, - Addr::Con(_) => - return Err(self.error_form(MachineError::type_error(ValidType::Atom, name), - stub)), // 8.5.1.3 e) - _ => - return Err(self.error_form(MachineError::type_error(ValidType::Atomic, name), - stub)) // 8.5.1.3 c) + self.try_functor_fabricate_struct( + name, + arity, + None, + &indices.op_dir, + a1.as_var().unwrap(), + ); + } + Addr::Con(_) => { + return Err(self + .error_form(MachineError::type_error(ValidType::Atom, name), stub)) + } // 8.5.1.3 e) + _ => { + return Err(self.error_form( + MachineError::type_error(ValidType::Atomic, name), + stub, + )) + } // 8.5.1.3 c) }; } else if !arity.is_ref() { // 8.5.1.3 d) - return Err(self.error_form(MachineError::type_error(ValidType::Integer, arity), stub)); + return Err( + self.error_form(MachineError::type_error(ValidType::Integer, arity), stub) + ); } } }; @@ -2694,8 +2837,7 @@ impl MachineState { *list = result; } - pub(super) - fn try_string_list(&self, r: RegType) -> Result { + pub(super) fn try_string_list(&self, r: RegType) -> Result { let a1 = self[r].clone(); let a1 = self.store(self.deref(a1)); @@ -2705,21 +2847,25 @@ impl MachineState { let stub = MachineError::functor_stub(clause_name!("partial_string"), 2); match self.try_from_list(r, stub.clone()) { - Ok(addrs) => - Ok(StringList::new(match self.try_char_list(addrs) { + Ok(addrs) => Ok(StringList::new( + match self.try_char_list(addrs) { Ok(string) => string, Err(err) => { return Err(self.error_form(err, stub)); } - }, false)), - Err(err) => return Err(err) + }, + false, + )), + Err(err) => return Err(err), } } } - pub(super) - fn try_from_list(&self, r: RegType, caller: MachineStub) -> Result, MachineStub> - { + pub(super) fn try_from_list( + &self, + r: RegType, + caller: MachineStub, + ) -> Result, MachineStub> { let a1 = self.store(self.deref(self[r].clone())); match a1.clone() { @@ -2731,41 +2877,47 @@ impl MachineState { loop { match self.heap[l].clone() { - HeapCellValue::Addr(addr) => - match self.store(self.deref(addr)) { - Addr::Lis(hcp) => { - result.push(self.heap[hcp].as_addr(hcp)); - l = hcp + 1; - }, - Addr::Con(Constant::String(ref s)) - if !self.flags.double_quotes.is_atom() => { - result.push(Addr::Con(Constant::String(s.clone()))); - break; - }, - Addr::Con(Constant::EmptyList) => - break, - Addr::HeapCell(_) | Addr::StackCell(..) => - return Err(self.error_form(MachineError::instantiation_error(), caller)), - _ => - return Err(self.error_form(MachineError::type_error(ValidType::List, a1), - caller)) - }, - _ => - return Err(self.error_form(MachineError::type_error(ValidType::List, a1), - caller)) + HeapCellValue::Addr(addr) => match self.store(self.deref(addr)) { + Addr::Lis(hcp) => { + result.push(self.heap[hcp].as_addr(hcp)); + l = hcp + 1; + } + Addr::Con(Constant::String(ref s)) + if !self.flags.double_quotes.is_atom() => + { + result.push(Addr::Con(Constant::String(s.clone()))); + break; + } + Addr::Con(Constant::EmptyList) => break, + Addr::HeapCell(_) | Addr::StackCell(..) => { + return Err( + self.error_form(MachineError::instantiation_error(), caller) + ) + } + _ => { + return Err(self.error_form( + MachineError::type_error(ValidType::List, a1), + caller, + )) + } + }, + _ => { + return Err(self + .error_form(MachineError::type_error(ValidType::List, a1), caller)) + } } } Ok(result) - }, - Addr::Con(Constant::String(ref s)) if !self.flags.double_quotes.is_atom() => - Ok(vec![Addr::Con(Constant::String(s.clone()))]), - Addr::HeapCell(_) | Addr::StackCell(..) => - Err(self.error_form(MachineError::instantiation_error(), caller)), - Addr::Con(Constant::EmptyList) => - Ok(vec![]), - _ => - Err(self.error_form(MachineError::type_error(ValidType::List, a1), caller)) + } + Addr::Con(Constant::String(ref s)) if !self.flags.double_quotes.is_atom() => { + Ok(vec![Addr::Con(Constant::String(s.clone()))]) + } + Addr::HeapCell(_) | Addr::StackCell(..) => { + Err(self.error_form(MachineError::instantiation_error(), caller)) + } + Addr::Con(Constant::EmptyList) => Ok(vec![]), + _ => Err(self.error_form(MachineError::type_error(ValidType::List, a1), caller)), } } @@ -2774,19 +2926,19 @@ impl MachineState { let stub = MachineError::functor_stub(clause_name!("keysort"), 2); match self.store(self.deref(a)) { - Addr::HeapCell(_) | Addr::StackCell(..) => - Err(self.error_form(MachineError::instantiation_error(), stub)), - Addr::Str(s) => - match self.heap[s].clone() { - HeapCellValue::NamedStr(2, ref name, Some(_)) - if *name == clause_name!("-") => - Ok(Addr::HeapCell(s+1)), - _ => - Err(self.error_form(MachineError::type_error(ValidType::Pair, - self.heap[s].as_addr(s)), - stub)) - }, - a => Err(self.error_form(MachineError::type_error(ValidType::Pair, a), stub)) + Addr::HeapCell(_) | Addr::StackCell(..) => { + Err(self.error_form(MachineError::instantiation_error(), stub)) + } + Addr::Str(s) => match self.heap[s].clone() { + HeapCellValue::NamedStr(2, ref name, Some(_)) if *name == clause_name!("-") => { + Ok(Addr::HeapCell(s + 1)) + } + _ => Err(self.error_form( + MachineError::type_error(ValidType::Pair, self.heap[s].as_addr(s)), + stub, + )), + }, + a => Err(self.error_form(MachineError::type_error(ValidType::Pair, a), stub)), } } @@ -2831,8 +2983,7 @@ impl MachineState { } // returns true on failure. - pub(super) fn structural_eq_test(&self) -> bool - { + pub(super) fn structural_eq_test(&self) -> bool { let a1 = self[temp_v!(1)].clone(); let a2 = self[temp_v!(2)].clone(); @@ -2842,70 +2993,108 @@ impl MachineState { for (v1, v2) in iter { match (v1, v2) { - (HeapCellValue::Addr(Addr::Lis(l)), HeapCellValue::Addr(Addr::Con(Constant::String(ref s)))) - | (HeapCellValue::Addr(Addr::Con(Constant::String(ref s))), HeapCellValue::Addr(Addr::Lis(l))) - if !self.flags.double_quotes.is_atom() => { - match self.flags.double_quotes { - DoubleQuotes::Chars => - if self.structural_char_list_test(s, l) { - continue; - }, - DoubleQuotes::Codes => - if self.structural_code_list_test(s, l) { - continue; - }, - DoubleQuotes::Atom => unreachable!() + ( + HeapCellValue::Addr(Addr::Lis(l)), + HeapCellValue::Addr(Addr::Con(Constant::String(ref s))), + ) + | ( + HeapCellValue::Addr(Addr::Con(Constant::String(ref s))), + HeapCellValue::Addr(Addr::Lis(l)), + ) if !self.flags.double_quotes.is_atom() => match self.flags.double_quotes { + DoubleQuotes::Chars => { + if self.structural_char_list_test(s, l) { + continue; } - }, - (HeapCellValue::Addr(Addr::Con(Constant::String(ref s1))), - HeapCellValue::Addr(Addr::Con(Constant::String(ref s2)))) => - match s1.head() { - Some(c1) => if let Some(c2) = s2.head() { + } + DoubleQuotes::Codes => { + if self.structural_code_list_test(s, l) { + continue; + } + } + DoubleQuotes::Atom => unreachable!(), + }, + ( + HeapCellValue::Addr(Addr::Con(Constant::String(ref s1))), + HeapCellValue::Addr(Addr::Con(Constant::String(ref s2))), + ) => match s1.head() { + Some(c1) => { + if let Some(c2) = s2.head() { if c1 != c2 { return true; } } else { return true; - }, - None => return !s2.is_empty() - }, - (HeapCellValue::Addr(Addr::Con(Constant::String(ref s))), - HeapCellValue::Addr(Addr::Con(Constant::EmptyList))) - | (HeapCellValue::Addr(Addr::Con(Constant::EmptyList)), - HeapCellValue::Addr(Addr::Con(Constant::String(ref s)))) - if !self.flags.double_quotes.is_atom() => if !s.is_empty() { + } + } + None => return !s2.is_empty(), + }, + ( + HeapCellValue::Addr(Addr::Con(Constant::String(ref s))), + HeapCellValue::Addr(Addr::Con(Constant::EmptyList)), + ) + | ( + HeapCellValue::Addr(Addr::Con(Constant::EmptyList)), + HeapCellValue::Addr(Addr::Con(Constant::String(ref s))), + ) if !self.flags.double_quotes.is_atom() => { + if !s.is_empty() { return true; - }, - (HeapCellValue::NamedStr(ar1, n1, _), HeapCellValue::NamedStr(ar2, n2, _)) => + } + } + (HeapCellValue::NamedStr(ar1, n1, _), HeapCellValue::NamedStr(ar2, n2, _)) => { if ar1 != ar2 || n1 != n2 { return true; - }, - (HeapCellValue::Addr(Addr::Lis(_)), HeapCellValue::Addr(Addr::Lis(_))) => - continue, - (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(_))) => - match (var_pairs.get(&v1).cloned(), var_pairs.get(&v2).cloned()) { - (Some(ref v2_p), Some(ref v1_p)) if *v1_p == v1 && *v2_p == v2 => - continue, - (Some(_), _) | (_, Some(_)) => - return true, - (None, None) => { - var_pairs.insert(v1.clone(), v2.clone()); - var_pairs.insert(v2, v1); - } - }, - (HeapCellValue::Addr(a1), HeapCellValue::Addr(a2)) => + } + } + (HeapCellValue::Addr(Addr::Lis(_)), HeapCellValue::Addr(Addr::Lis(_))) => continue, + ( + 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(_)), + ) => match (var_pairs.get(&v1).cloned(), var_pairs.get(&v2).cloned()) { + (Some(ref v2_p), Some(ref v1_p)) if *v1_p == v1 && *v2_p == v2 => continue, + (Some(_), _) | (_, Some(_)) => return true, + (None, None) => { + var_pairs.insert(v1.clone(), v2.clone()); + var_pairs.insert(v2, v1); + } + }, + (HeapCellValue::Addr(a1), HeapCellValue::Addr(a2)) => { if a1 != a2 { return true; - }, - _ => return true + } + } + _ => return true, } } @@ -2913,25 +3102,21 @@ impl MachineState { } // returns true on failure. - pub(super) fn ground_test(&self) -> bool - { + pub(super) fn ground_test(&self) -> bool { let a = self.store(self.deref(self[temp_v!(1)].clone())); for v in self.acyclic_pre_order_iter(a) { match v { - HeapCellValue::Addr(Addr::HeapCell(..)) => - return true, - HeapCellValue::Addr(Addr::StackCell(..)) => - return true, + HeapCellValue::Addr(Addr::HeapCell(..)) => return true, + HeapCellValue::Addr(Addr::StackCell(..)) => return true, _ => {} } - }; + } false } - pub(super) fn setup_built_in_call(&mut self, ct: BuiltInClauseType) - { + pub(super) fn setup_built_in_call(&mut self, ct: BuiltInClauseType) { self.num_of_args = ct.arity(); self.b0 = self.b; @@ -2945,14 +3130,16 @@ impl MachineState { if self.e + 1 < self.and_stack.len() { let and_gi = self.and_stack[self.e].global_index; - let or_gi = self.or_stack.top() + let or_gi = self + .or_stack + .top() .map(|or_fr| or_fr.global_index) .unwrap_or(0); if and_gi > or_gi { let new_e = self.e + 1; - self.and_stack[new_e].e = self.e; + self.and_stack[new_e].e = self.e; self.and_stack[new_e].cp = self.cp.clone(); self.and_stack[new_e].global_index = gi; @@ -2971,21 +3158,23 @@ impl MachineState { let e = self.e; self.cp = self.and_stack[e].cp.clone(); - self.e = self.and_stack[e].e; + self.e = self.and_stack[e].e; self.p += 1; } - fn handle_call_clause(&mut self, indices: &mut IndexStore, - code_repo: &CodeRepo, - call_policy: &mut Box, - cut_policy: &mut Box, - parsing_stream: &mut PrologStream, - ct: &ClauseType, - arity: usize, - lco: bool, - use_default_cp: bool) - { + fn handle_call_clause( + &mut self, + indices: &mut IndexStore, + code_repo: &CodeRepo, + call_policy: &mut Box, + cut_policy: &mut Box, + parsing_stream: &mut PrologStream, + ct: &ClauseType, + arity: usize, + lco: bool, + use_default_cp: bool, + ) { let mut default_call_policy: Box = Box::new(DefaultCallPolicy {}); let call_policy = if use_default_cp { &mut default_call_policy @@ -2996,44 +3185,65 @@ impl MachineState { self.last_call = lco; match ct { - &ClauseType::BuiltIn(ref ct) => - try_or_fail!(self, call_policy.call_builtin(self, ct, indices, parsing_stream)), - &ClauseType::CallN => - try_or_fail!(self, call_policy.call_n(self, arity, indices, parsing_stream)), - &ClauseType::Hook(ref hook) => - try_or_fail!(self, call_policy.compile_hook(self, hook)), + &ClauseType::BuiltIn(ref ct) => try_or_fail!( + self, + call_policy.call_builtin(self, ct, indices, parsing_stream) + ), + &ClauseType::CallN => try_or_fail!( + self, + call_policy.call_n(self, arity, indices, parsing_stream) + ), + &ClauseType::Hook(ref hook) => try_or_fail!(self, call_policy.compile_hook(self, hook)), &ClauseType::Inlined(ref ct) => { self.execute_inlined(ct); if lco { self.p = CodePtr::Local(self.cp); } - }, - &ClauseType::Named(ref name, _, ref idx) | &ClauseType::Op(ref name, _, ref idx) => - try_or_fail!(self, call_policy.context_call(self, name.clone(), arity, idx.clone(), - indices)), - &ClauseType::System(ref ct) => - try_or_fail!(self, self.system_call(ct, code_repo, indices, call_policy, cut_policy, - parsing_stream)) + } + &ClauseType::Named(ref name, _, ref idx) | &ClauseType::Op(ref name, _, ref idx) => { + try_or_fail!( + self, + call_policy.context_call(self, name.clone(), arity, idx.clone(), indices) + ) + } + &ClauseType::System(ref ct) => try_or_fail!( + self, + self.system_call( + ct, + code_repo, + indices, + call_policy, + cut_policy, + parsing_stream + ) + ), }; } - pub(super) - fn execute_ctrl_instr(&mut self, - indices: &mut IndexStore, - code_repo: &CodeRepo, - call_policy: &mut Box, - cut_policy: &mut Box, - parsing_stream: &mut PrologStream, - instr: &ControlInstruction) - { + pub(super) fn execute_ctrl_instr( + &mut self, + indices: &mut IndexStore, + code_repo: &CodeRepo, + call_policy: &mut Box, + cut_policy: &mut Box, + parsing_stream: &mut PrologStream, + instr: &ControlInstruction, + ) { match instr { - &ControlInstruction::Allocate(num_cells) => - self.allocate(num_cells), - &ControlInstruction::CallClause(ref ct, arity, _, lco, use_default_cp) => - self.handle_call_clause(indices, code_repo, call_policy, cut_policy, - parsing_stream, ct, arity, lco, - use_default_cp), + &ControlInstruction::Allocate(num_cells) => self.allocate(num_cells), + &ControlInstruction::CallClause(ref ct, arity, _, lco, use_default_cp) => self + .handle_call_clause( + indices, + code_repo, + call_policy, + cut_policy, + parsing_stream, + ct, + arity, + lco, + use_default_cp, + ), &ControlInstruction::Deallocate => self.deallocate(), &ControlInstruction::JmpBy(arity, offset, _, lco) => { if !lco { @@ -3043,126 +3253,135 @@ impl MachineState { self.num_of_args = arity; self.b0 = self.b; self.p += offset; - }, - &ControlInstruction::Proceed => - self.p = CodePtr::Local(self.cp.clone()) + } + &ControlInstruction::Proceed => self.p = CodePtr::Local(self.cp.clone()), }; } - pub(super) fn execute_indexed_choice_instr(&mut self, instr: &IndexedChoiceInstruction, - call_policy: &mut Box) - { + pub(super) fn execute_indexed_choice_instr( + &mut self, + instr: &IndexedChoiceInstruction, + call_policy: &mut Box, + ) { match instr { &IndexedChoiceInstruction::Try(l) => { let n = self.num_of_args; let gi = self.next_global_index(); - self.or_stack.push(gi, - self.e, - self.cp.clone(), - self.attr_var_init.attr_var_queue.len(), - self.b, - self.p.clone() + 1, - self.tr, - self.pstr_tr, - self.heap.h, - self.b0, - self.num_of_args); + self.or_stack.push( + gi, + self.e, + self.cp.clone(), + self.attr_var_init.attr_var_queue.len(), + self.b, + self.p.clone() + 1, + self.tr, + self.pstr_tr, + self.heap.h, + self.b0, + self.num_of_args, + ); self.b = self.or_stack.len(); let b = self.b - 1; - for i in 1 .. n + 1 { + for i in 1..n + 1 { self.or_stack[b][i] = self.registers[i].clone(); } self.hb = self.heap.h; self.p += l; - }, - &IndexedChoiceInstruction::Retry(l) => - try_or_fail!(self, call_policy.retry(self, l)), - &IndexedChoiceInstruction::Trust(l) => - try_or_fail!(self, call_policy.trust(self, l)) + } + &IndexedChoiceInstruction::Retry(l) => try_or_fail!(self, call_policy.retry(self, l)), + &IndexedChoiceInstruction::Trust(l) => try_or_fail!(self, call_policy.trust(self, l)), }; } - pub(super) fn execute_choice_instr(&mut self, instr: &ChoiceInstruction, - call_policy: &mut Box) - { + pub(super) fn execute_choice_instr( + &mut self, + instr: &ChoiceInstruction, + call_policy: &mut Box, + ) { match instr { &ChoiceInstruction::TryMeElse(offset) => { let n = self.num_of_args; let gi = self.next_global_index(); - self.or_stack.push(gi, - self.e, - self.cp.clone(), - self.attr_var_init.attr_var_queue.len(), - self.b, - self.p.clone() + offset, - self.tr, - self.pstr_tr, - self.heap.h, - self.b0, - self.num_of_args); + self.or_stack.push( + gi, + self.e, + self.cp.clone(), + self.attr_var_init.attr_var_queue.len(), + self.b, + self.p.clone() + offset, + self.tr, + self.pstr_tr, + self.heap.h, + self.b0, + self.num_of_args, + ); self.b = self.or_stack.len(); - let b = self.b - 1; + let b = self.b - 1; - for i in 1 .. n + 1 { + for i in 1..n + 1 { self.or_stack[b][i] = self.registers[i].clone(); } self.hb = self.heap.h; self.p += 1; - }, + } &ChoiceInstruction::DefaultRetryMeElse(offset) => { let mut call_policy = DefaultCallPolicy {}; try_or_fail!(self, call_policy.retry_me_else(self, offset)) - }, + } &ChoiceInstruction::DefaultTrustMe => { let mut call_policy = DefaultCallPolicy {}; try_or_fail!(self, call_policy.trust_me(self)) - }, - &ChoiceInstruction::RetryMeElse(offset) => - try_or_fail!(self, call_policy.retry_me_else(self, offset)), - &ChoiceInstruction::TrustMe => - try_or_fail!(self, call_policy.trust_me(self)) + } + &ChoiceInstruction::RetryMeElse(offset) => { + try_or_fail!(self, call_policy.retry_me_else(self, offset)) + } + &ChoiceInstruction::TrustMe => try_or_fail!(self, call_policy.trust_me(self)), } } - pub(super) fn execute_cut_instr(&mut self, instr: &CutInstruction, - cut_policy: &mut Box) - { + pub(super) fn execute_cut_instr( + &mut self, + instr: &CutInstruction, + cut_policy: &mut Box, + ) { match instr { &CutInstruction::NeckCut => { - let b = self.b; + let b = self.b; let b0 = self.b0; if b > b0 { self.b = b0; self.tidy_trail(); - self.tidy_pstr_trail(); + self.tidy_pstr_trail(); self.or_stack.truncate(self.b); } self.p += 1; - }, + } &CutInstruction::GetLevel(r) => { let b0 = self.b0; self[r] = Addr::Con(Constant::Usize(b0)); self.p += 1; - }, + } &CutInstruction::GetLevelAndUnify(r) => { let b0 = self[perm_v!(1)].clone(); - let a = self[r].clone(); + let a = self[r].clone(); self.unify(a, b0); self.p += 1; - }, - &CutInstruction::Cut(r) => if !cut_policy.cut(self, r) { - self.p += 1; + } + &CutInstruction::Cut(r) => { + if !cut_policy.cut(self, r) { + self.p += 1; + } } } } @@ -3195,8 +3414,7 @@ impl MachineState { self.lifted_heap.clear(); } - pub(super) - fn sink_to_snapshot(&mut self) -> MachineState { + pub(super) fn sink_to_snapshot(&mut self) -> MachineState { let mut snapshot = MachineState::with_capacity(0); snapshot.hb = self.hb; @@ -3224,8 +3442,7 @@ impl MachineState { snapshot } - pub(super) - fn absorb_snapshot(&mut self, mut snapshot: MachineState) { + pub(super) fn absorb_snapshot(&mut self, mut snapshot: MachineState) { self.hb = snapshot.hb; self.e = snapshot.e; self.b = snapshot.b; diff --git a/src/prolog/machine/mod.rs b/src/prolog/machine/mod.rs index c54c8a22..b9e90cc7 100644 --- a/src/prolog/machine/mod.rs +++ b/src/prolog/machine/mod.rs @@ -7,29 +7,30 @@ use prolog::forms::*; use prolog::heap_print::*; use prolog::instructions::*; use prolog::read::*; -use prolog::write::{ContinueResult, next_keypress}; +use prolog::write::{next_keypress, ContinueResult}; -pub mod machine_indices; -pub mod heap; mod and_stack; -mod or_stack; mod attributed_variables; +pub(super) mod code_repo; +pub mod compile; mod copier; mod dynamic_database; +pub mod heap; pub mod machine_errors; -pub mod toplevel; -pub mod compile; -pub(super) mod code_repo; -pub mod modules; +pub mod machine_indices; pub(super) mod machine_state; +pub mod modules; +mod or_stack; pub(super) mod term_expansion; +pub mod toplevel; -#[macro_use] mod machine_state_impl; +#[macro_use] +mod machine_state_impl; mod system_calls; use prolog::machine::attributed_variables::*; -use prolog::machine::compile::*; use prolog::machine::code_repo::*; +use prolog::machine::compile::*; use prolog::machine::machine_errors::*; use prolog::machine::machine_indices::*; use prolog::machine::machine_state::*; @@ -40,13 +41,13 @@ use prolog::read::PrologStream; use indexmap::IndexMap; use std::collections::VecDeque; -use std::io::{Read, Write, stdout}; use std::fs::File; +use std::io::{stdout, Read, Write}; use std::mem; use std::ops::Index; use std::rc::Rc; -use termion::raw::{IntoRawMode}; +use termion::raw::IntoRawMode; pub struct MachinePolicies { call_policy: Box, @@ -69,7 +70,7 @@ pub struct Machine { pub(super) indices: IndexStore, pub(super) code_repo: CodeRepo, pub(super) toplevel_idx: usize, - pub(super) prolog_stream: ParsingStream> + pub(super) prolog_stream: ParsingStream>, } impl Index for CodeRepo { @@ -103,23 +104,21 @@ impl SubModuleUser for IndexStore { &mut self.op_dir } - fn get_code_index(&self, key: PredicateKey, module: ClauseName) -> Option - { + fn get_code_index(&self, key: PredicateKey, module: ClauseName) -> Option { match module.as_str() { "user" | "builtin" => self.code_dir.get(&key).cloned(), - _ => self.modules.get(&module).and_then(|ref module| { - module.code_dir.get(&key).cloned().map(CodeIndex::from) - }) + _ => self + .modules + .get(&module) + .and_then(|ref module| module.code_dir.get(&key).cloned().map(CodeIndex::from)), } } - fn remove_code_index(&mut self, key: PredicateKey) - { + fn remove_code_index(&mut self, key: PredicateKey) { self.code_dir.remove(&key); } - fn insert_dir_entry(&mut self, name: ClauseName, arity: usize, idx: CodeIndex) - { + fn insert_dir_entry(&mut self, name: ClauseName, arity: usize, idx: CodeIndex) { if let Some(ref code_idx) = self.code_dir.get(&(name.clone(), arity)) { if !code_idx.is_undefined() { println!("warning: overwriting {}/{}", &name, arity); @@ -133,21 +132,31 @@ impl SubModuleUser for IndexStore { self.code_dir.insert((name, arity), idx); } - fn use_qualified_module(&mut self, code_repo: &mut CodeRepo, flags: MachineFlags, - submodule: &Module, exports: &Vec) - -> Result<(), SessionError> - { + fn use_qualified_module( + &mut self, + code_repo: &mut CodeRepo, + flags: MachineFlags, + submodule: &Module, + exports: &Vec, + ) -> Result<(), SessionError> { use_qualified_module(self, submodule, exports)?; - submodule.dump_expansions(code_repo, flags).map_err(SessionError::from) + submodule + .dump_expansions(code_repo, flags) + .map_err(SessionError::from) } - fn use_module(&mut self, code_repo: &mut CodeRepo, flags: MachineFlags, submodule: &Module) - -> Result<(), SessionError> - { + fn use_module( + &mut self, + code_repo: &mut CodeRepo, + flags: MachineFlags, + submodule: &Module, + ) -> Result<(), SessionError> { use_module(self, submodule)?; if !submodule.inserted_expansions { - submodule.dump_expansions(code_repo, flags).map_err(SessionError::from) + submodule + .dump_expansions(code_repo, flags) + .map_err(SessionError::from) } else { Ok(()) } @@ -155,9 +164,9 @@ impl SubModuleUser for IndexStore { } static BUILTINS: &str = include_str!("../lib/builtins.pl"); -static ERROR: &str = include_str!("../lib/error.pl"); -static LISTS: &str = include_str!("../lib/lists.pl"); -static NON_ISO: &str = include_str!("../lib/non_iso.pl"); +static ERROR: &str = include_str!("../lib/error.pl"); +static LISTS: &str = include_str!("../lib/lists.pl"); +static NON_ISO: &str = include_str!("../lib/non_iso.pl"); static TOPLEVEL: &str = include_str!("../toplevel.pl"); impl Machine { @@ -166,16 +175,16 @@ impl Machine { Ok(code) => { self.machine_st.attr_var_init.verify_attrs_loc = self.code_repo.code.len(); self.code_repo.code.extend(code.into_iter()); - }, - Err(_) => panic!("Machine::compile_special_forms() failed at VERIFY_ATTRS") + } + Err(_) => panic!("Machine::compile_special_forms() failed at VERIFY_ATTRS"), } match compile_special_form(self, parsing_stream(PROJECT_ATTRS.as_bytes())) { Ok(code) => { self.machine_st.attr_var_init.project_attrs_loc = self.code_repo.code.len(); self.code_repo.code.extend(code.into_iter()); - }, - Err(_) => panic!("Machine::compile_special_forms() failed at PROJECT_ATTRS") + } + Err(_) => panic!("Machine::compile_special_forms() failed at PROJECT_ATTRS"), } } @@ -187,15 +196,15 @@ impl Machine { fn compile_scryerrc(&mut self) { let mut path = match dirs::home_dir() { Some(path) => path, - None => return + None => return, }; - + path.push(".scryerrc"); if path.is_file() { let file_src = match File::open(&path) { Ok(file_handle) => parsing_stream(file_handle), - Err(_) => return + Err(_) => return, }; compile_user_module(self, file_src); @@ -221,13 +230,16 @@ impl Machine { indices: IndexStore::new(), code_repo: CodeRepo::new(), toplevel_idx: 0, - prolog_stream + prolog_stream, }; let atom_tbl = wam.indices.atom_tbl.clone(); - compile_listing(&mut wam, parsing_stream(BUILTINS.as_bytes()), - default_index_store!(atom_tbl.clone())); + compile_listing( + &mut wam, + parsing_stream(BUILTINS.as_bytes()), + default_index_store!(atom_tbl.clone()), + ); wam.compile_special_forms(); wam.compile_top_level(); @@ -246,11 +258,10 @@ impl Machine { self.machine_st.flags } - pub fn check_toplevel_code(&self, indices: &IndexStore) -> Result<(), SessionError> - { + pub fn check_toplevel_code(&self, indices: &IndexStore) -> Result<(), SessionError> { for (key, idx) in &indices.code_dir { match ClauseType::from(key.0.clone(), key.1, None) { - ClauseType::Named(..) | ClauseType::Op(..) => {}, + ClauseType::Named(..) | ClauseType::Op(..) => {} _ => { // ensure we don't try to overwrite the name/arity of a builtin. let err_str = format!("{}/{}", key.0, key.1); @@ -269,8 +280,12 @@ impl Machine { } if existing_idx.module_name() != idx.module_name() { - let err_str = format!("{}/{} from module {}", key.0, key.1, - existing_idx.module_name().as_str()); + let err_str = format!( + "{}/{} from module {}", + key.0, + key.1, + existing_idx.module_name().as_str() + ); let err_str = clause_name!(err_str, self.indices.atom_tbl()); return Err(SessionError::CannotOverwriteImport(err_str)); @@ -282,8 +297,7 @@ impl Machine { Ok(()) } - pub fn add_batched_code(&mut self, code: Code, code_dir: CodeDir) - { + pub fn add_batched_code(&mut self, code: Code, code_dir: CodeDir) { // error detection has finished, so update the master index of keys. for (key, idx) in code_dir { if let Some(ref mut master_idx) = self.indices.code_dir.get_mut(&key) { @@ -309,12 +323,13 @@ impl Machine { #[inline] pub fn add_module(&mut self, module: Module, code: Code) { - self.indices.modules.insert(module.module_decl.name.clone(), module); + self.indices + .modules + .insert(module.module_decl.name.clone(), module); self.code_repo.code.extend(code.into_iter()); } - pub fn submit_query(&mut self, code: Code, alloc_locs: AllocVarDict) -> EvalSession - { + pub fn submit_query(&mut self, code: Code, alloc_locs: AllocVarDict) -> EvalSession { self.code_repo.cached_query = code; self.run_query(&alloc_locs); @@ -328,16 +343,15 @@ impl Machine { pub fn throw_session_error(&mut self, err: SessionError, key: PredicateKey) { let h = self.machine_st.heap.h; - let err = MachineError::session_error(h, err); + let err = MachineError::session_error(h, err); let stub = MachineError::functor_stub(key.0, key.1); - let err = self.machine_st.error_form(err, stub); + let err = self.machine_st.error_form(err, stub); self.machine_st.throw_exception(err); return; } - fn handle_toplevel_command(&mut self, code_ptr: REPLCodePtr, p: LocalCodePtr) - { + fn handle_toplevel_command(&mut self, code_ptr: REPLCodePtr, p: LocalCodePtr) { match code_ptr { REPLCodePtr::CompileBatch => { #[cfg(feature = "readline_rs_compat")] @@ -352,7 +366,7 @@ impl Machine { EvalSession::Error(e) => self.throw_session_error(e, (clause_name!("repl"), 0)), _ => {} }; - }, + } REPLCodePtr::SubmitQueryAndPrintResults => { let term = self.machine_st[temp_v!(1)].clone(); let stub = MachineError::functor_stub(clause_name!("repl"), 0); @@ -364,16 +378,18 @@ impl Machine { for addr in addrs { match addr { Addr::Str(s) => { - let var_atom = match self.machine_st.heap[s+1].as_addr(s+1) { - Addr::Con(Constant::Atom(var_atom, _)) => - Rc::new(var_atom.to_string()), - _ => unreachable!() + let var_atom = match self.machine_st.heap[s + 1].as_addr(s + 1) + { + Addr::Con(Constant::Atom(var_atom, _)) => { + Rc::new(var_atom.to_string()) + } + _ => unreachable!(), }; - let var_addr = self.machine_st.heap[s+2].as_addr(s+2); + let var_addr = self.machine_st.heap[s + 2].as_addr(s + 2); var_dict.insert(var_atom, var_addr); - }, - _ => unreachable!() + } + _ => unreachable!(), }; } @@ -381,7 +397,7 @@ impl Machine { let term_output = self.machine_st.print_query(term, &self.indices.op_dir); term_output.result() - }, + } Err(err_stub) => { self.machine_st.throw_exception(err_stub); return; @@ -395,7 +411,7 @@ impl Machine { let result = match stream_to_toplevel(stream, self) { Ok(packet) => compile_term(self, packet), - Err(e) => EvalSession::from(e) + Err(e) => EvalSession::from(e), }; self.handle_eval_session(result, snapshot); @@ -419,117 +435,128 @@ impl Machine { fn handle_eval_session(&mut self, result: EvalSession, snapshot: MachineState) { match result { - EvalSession::InitialQuerySuccess(alloc_locs) => - loop { - let bindings = { - let output = PrinterOutputter::new(); - self.toplevel_heap_view(output).result() - }; - - let attr_goals = self.attribute_goals(); + EvalSession::InitialQuerySuccess(alloc_locs) => loop { + let bindings = { + let output = PrinterOutputter::new(); + self.toplevel_heap_view(output).result() + }; - if !(self.machine_st.b > 0) { - if bindings.is_empty() { - let space = if requires_space(&attr_goals, ".") { " " } else { "" }; + let attr_goals = self.attribute_goals(); - if !attr_goals.is_empty() { - println!("{}{}.", attr_goals, space); - } else { - println!("true."); - } + if !(self.machine_st.b > 0) { + if bindings.is_empty() { + let space = if requires_space(&attr_goals, ".") { + " " + } else { + "" + }; - self.machine_st.absorb_snapshot(snapshot); - return; + if !attr_goals.is_empty() { + println!("{}{}.", attr_goals, space); + } else { + println!("true."); } - } else if bindings.is_empty() && attr_goals.is_empty() { - print!("true"); - stdout().flush().unwrap(); + + self.machine_st.absorb_snapshot(snapshot); + return; } + } else if bindings.is_empty() && attr_goals.is_empty() { + print!("true"); + stdout().flush().unwrap(); + } - let mut raw_stdout = stdout().into_raw_mode().unwrap(); + let mut raw_stdout = stdout().into_raw_mode().unwrap(); - if !attr_goals.is_empty() { - if bindings.is_empty() { - write!(raw_stdout, "{}", attr_goals).unwrap(); - } else { - write!(raw_stdout, "{}, {}", bindings, attr_goals).unwrap(); - } - } else if !bindings.is_empty() { - write!(raw_stdout, "{}", bindings).unwrap(); + if !attr_goals.is_empty() { + if bindings.is_empty() { + write!(raw_stdout, "{}", attr_goals).unwrap(); + } else { + write!(raw_stdout, "{}, {}", bindings, attr_goals).unwrap(); } + } else if !bindings.is_empty() { + write!(raw_stdout, "{}", bindings).unwrap(); + } - if self.machine_st.b > 0 { - raw_stdout.flush().unwrap(); + if self.machine_st.b > 0 { + raw_stdout.flush().unwrap(); - let result = match next_keypress() { - ContinueResult::ContinueQuery => { - write!(raw_stdout, " ;\r\n").unwrap(); - self.continue_query(&alloc_locs) - }, - ContinueResult::Conclude => { - write!(raw_stdout, " ...\r\n").unwrap(); - self.machine_st.absorb_snapshot(snapshot); + let result = match next_keypress() { + ContinueResult::ContinueQuery => { + write!(raw_stdout, " ;\r\n").unwrap(); + self.continue_query(&alloc_locs) + } + ContinueResult::Conclude => { + write!(raw_stdout, " ...\r\n").unwrap(); + self.machine_st.absorb_snapshot(snapshot); + return; + } + }; + + let mut raw_stdout = stdout().into_raw_mode().unwrap(); + + match result { + EvalSession::QueryFailure => { + if self.machine_st.ball.stub.len() > 0 { + self.propagate_exception_to_toplevel(snapshot); return; - } - }; + } else { + write!(raw_stdout, "false.\r\n").unwrap(); + raw_stdout.flush().unwrap(); - let mut raw_stdout = stdout().into_raw_mode().unwrap(); - - match result { - EvalSession::QueryFailure => - if self.machine_st.ball.stub.len() > 0 { - self.propagate_exception_to_toplevel(snapshot); - return; - } else { - write!(raw_stdout, "false.\r\n").unwrap(); - raw_stdout.flush().unwrap(); - - self.machine_st.absorb_snapshot(snapshot); - return; - }, - EvalSession::Error(err) => { self.machine_st.absorb_snapshot(snapshot); - self.throw_session_error(err, (clause_name!("repl"), 0)); return; - }, - _ => {} + } + } + EvalSession::Error(err) => { + self.machine_st.absorb_snapshot(snapshot); + self.throw_session_error(err, (clause_name!("repl"), 0)); + return; } + _ => {} + } + } else { + if bindings.is_empty() && attr_goals.is_empty() { + write!(raw_stdout, "true.\r\n").unwrap(); } else { - if bindings.is_empty() && attr_goals.is_empty() { - write!(raw_stdout, "true.\r\n").unwrap(); + let space = if !attr_goals.is_empty() { + if requires_space(&attr_goals, ".") { + " " + } else { + "" + } } else { - let space = if !attr_goals.is_empty() { - if requires_space(&attr_goals, ".") { " " } else { "" } + if requires_space(&bindings, ".") { + " " } else { - if requires_space(&bindings, ".") { " " } else { "" } - }; - - write!(raw_stdout, "{}.\r\n", space).unwrap(); - } + "" + } + }; - break; + write!(raw_stdout, "{}.\r\n", space).unwrap(); } - }, + + break; + } + }, EvalSession::Error(err) => { self.machine_st.absorb_snapshot(snapshot); self.throw_session_error(err, (clause_name!("repl"), 0)); return; - }, - EvalSession::QueryFailure => + } + EvalSession::QueryFailure => { if self.machine_st.ball.stub.len() > 0 { return self.propagate_exception_to_toplevel(snapshot); } else { println!("false."); - }, + } + } _ => {} } self.machine_st.absorb_snapshot(snapshot); } - pub(super) - fn run_query(&mut self, alloc_locs: &AllocVarDict) - { + pub(super) fn run_query(&mut self, alloc_locs: &AllocVarDict) { let end_ptr = top_level_code_ptr!(0, self.code_repo.size_of_cached_query()); while self.machine_st.p < end_ptr { @@ -538,20 +565,23 @@ impl Machine { &Line::Control(ref ctrl_instr) if ctrl_instr.is_jump_instr() => { self.machine_st.record_var_places(cn, alloc_locs); cn += 1; - }, + } _ => {} } self.machine_st.p = top_level_code_ptr!(cn, p); } - self.machine_st.query_stepper(&mut self.indices, &mut self.policies, &mut self.code_repo, - &mut self.prolog_stream); + self.machine_st.query_stepper( + &mut self.indices, + &mut self.policies, + &mut self.code_repo, + &mut self.prolog_stream, + ); match self.machine_st.p { - CodePtr::Local(LocalCodePtr::TopLevel(_, p)) if p > 0 => {}, - CodePtr::REPL(code_ptr, p) => - self.handle_toplevel_command(code_ptr, p), + CodePtr::Local(LocalCodePtr::TopLevel(_, p)) if p > 0 => {} + CodePtr::REPL(code_ptr, p) => self.handle_toplevel_command(code_ptr, p), CodePtr::DynamicTransaction(trans_type, p) => { // self.code_repo.cached_query is about to be overwritten by the term expander, // so hold onto it locally and restore it after the compiler has finished. @@ -569,7 +599,7 @@ impl Machine { } self.code_repo.cached_query = cached_query; - }, + } _ => { if self.machine_st.heap_locs.is_empty() { self.machine_st.record_var_places(0, alloc_locs); @@ -581,8 +611,7 @@ impl Machine { } } - pub fn continue_query(&mut self, alloc_locs: &AllocVarDict) -> EvalSession - { + pub fn continue_query(&mut self, alloc_locs: &AllocVarDict) -> EvalSession { if !self.or_stack_is_empty() { let b = self.machine_st.b - 1; self.machine_st.p = self.machine_st.or_stack[b].bp.clone(); @@ -605,15 +634,17 @@ impl Machine { } pub fn toplevel_heap_view(&self, mut output: Outputter) -> Outputter - where Outputter: HCValueOutputter + where + Outputter: HCValueOutputter, { let mut sorted_vars: Vec<_> = self.machine_st.heap_locs.iter().collect(); sorted_vars.sort_by_key(|ref v| v.0); for (var, addr) in sorted_vars { let addr = self.machine_st.store(self.machine_st.deref(addr.clone())); - output = self.machine_st.print_var_eq(var.clone(), addr, &self.indices.op_dir, - output); + output = self + .machine_st + .print_var_eq(var.clone(), addr, &self.indices.op_dir, output); } output @@ -621,14 +652,19 @@ impl Machine { #[cfg(test)] pub fn test_heap_view(&self, mut output: Outputter) -> Outputter - where Outputter: HCValueOutputter + where + Outputter: HCValueOutputter, { let mut sorted_vars: Vec<(&Rc, &Addr)> = self.machine_st.heap_locs.iter().collect(); sorted_vars.sort_by_key(|ref v| v.0); for (var, addr) in sorted_vars { - output = self.machine_st.print_var_eq(var.clone(), addr.clone(), &self.indices.op_dir, - output); + output = self.machine_st.print_var_eq( + var.clone(), + addr.clone(), + &self.indices.op_dir, + output, + ); } output @@ -640,18 +676,18 @@ impl Machine { } impl MachineState { - fn record_var_places(&mut self, chunk_num: usize, alloc_locs: &AllocVarDict) - { + fn record_var_places(&mut self, chunk_num: usize, alloc_locs: &AllocVarDict) { for (var, var_data) in alloc_locs { match var_data { - &VarData::Perm(p) if p > 0 => + &VarData::Perm(p) if p > 0 => { if !self.heap_locs.contains_key(var) { let e = self.e; let r = var_data.as_reg_type().reg_num(); let addr = self.and_stack[e][r].clone(); self.heap_locs.insert(var.clone(), addr); - }, + } + } &VarData::Temp(cn, _, _) if cn == chunk_num => { let r = var_data.as_reg_type(); @@ -659,18 +695,19 @@ impl MachineState { let addr = self[r].clone(); self.heap_locs.insert(var.clone(), addr); } - }, + } _ => {} } } } - fn print_query(&mut self, addr: Addr, op_dir: &OpDir) -> PrinterOutputter - { + fn print_query(&mut self, addr: Addr, op_dir: &OpDir) -> PrinterOutputter { let flags = self.flags; let mut output = { - self.flags = MachineFlags { double_quotes: DoubleQuotes::Atom }; + self.flags = MachineFlags { + double_quotes: DoubleQuotes::Atom, + }; let output = PrinterOutputter::new(); let mut printer = HCPrinter::from_heap_locs(&self, op_dir, output); @@ -689,28 +726,38 @@ impl MachineState { output } - fn dispatch_instr(&mut self, instr: &Line, indices: &mut IndexStore, policies: &mut MachinePolicies, - code_repo: &CodeRepo, prolog_stream: &mut PrologStream) - { + fn dispatch_instr( + &mut self, + instr: &Line, + indices: &mut IndexStore, + policies: &mut MachinePolicies, + code_repo: &CodeRepo, + prolog_stream: &mut PrologStream, + ) { match instr { - &Line::Arithmetic(ref arith_instr) => - self.execute_arith_instr(arith_instr), - &Line::Choice(ref choice_instr) => - self.execute_choice_instr(choice_instr, &mut policies.call_policy), - &Line::Cut(ref cut_instr) => - self.execute_cut_instr(cut_instr, &mut policies.cut_policy), - &Line::Control(ref control_instr) => - self.execute_ctrl_instr(indices, code_repo, &mut policies.call_policy, - &mut policies.cut_policy, prolog_stream, - control_instr), + &Line::Arithmetic(ref arith_instr) => self.execute_arith_instr(arith_instr), + &Line::Choice(ref choice_instr) => { + self.execute_choice_instr(choice_instr, &mut policies.call_policy) + } + &Line::Cut(ref cut_instr) => { + self.execute_cut_instr(cut_instr, &mut policies.cut_policy) + } + &Line::Control(ref control_instr) => self.execute_ctrl_instr( + indices, + code_repo, + &mut policies.call_policy, + &mut policies.cut_policy, + prolog_stream, + control_instr, + ), &Line::Fact(ref fact_instr) => { self.execute_fact_instr(&fact_instr); self.p += 1; - }, - &Line::Indexing(ref indexing_instr) => - self.execute_indexing_instr(&indexing_instr), - &Line::IndexedChoice(ref choice_instr) => - self.execute_indexed_choice_instr(choice_instr, &mut policies.call_policy), + } + &Line::Indexing(ref indexing_instr) => self.execute_indexing_instr(&indexing_instr), + &Line::IndexedChoice(ref choice_instr) => { + self.execute_indexed_choice_instr(choice_instr, &mut policies.call_policy) + } &Line::Query(ref query_instr) => { self.execute_query_instr(&query_instr); self.p += 1; @@ -718,24 +765,27 @@ impl MachineState { } } - fn execute_instr(&mut self, indices: &mut IndexStore, policies: &mut MachinePolicies, - code_repo: &CodeRepo, prolog_stream: &mut PrologStream) - { + fn execute_instr( + &mut self, + indices: &mut IndexStore, + policies: &mut MachinePolicies, + code_repo: &CodeRepo, + prolog_stream: &mut PrologStream, + ) { let instr = match code_repo.lookup_instr(self.last_call, &self.p) { Some(instr) => instr, - None => return + None => return, }; self.dispatch_instr(instr.as_ref(), indices, policies, code_repo, prolog_stream); } - fn backtrack(&mut self) - { + fn backtrack(&mut self) { if self.b > 0 { let b = self.b - 1; self.b0 = self.or_stack[b].b0; - self.p = self.or_stack[b].bp.clone(); + self.p = self.or_stack[b].bp.clone(); if let CodePtr::Local(LocalCodePtr::TopLevel(_, p)) = self.p { self.fail = p == 0; @@ -749,27 +799,23 @@ impl MachineState { fn check_machine_index(&mut self, code_repo: &CodeRepo) -> bool { match self.p { - CodePtr::Local(LocalCodePtr::DirEntry(p)) - if p < code_repo.code.len() => {}, + CodePtr::Local(LocalCodePtr::DirEntry(p)) if p < code_repo.code.len() => {} CodePtr::Local(LocalCodePtr::UserTermExpansion(p)) - if p < code_repo.term_expanders.len() => {}, - CodePtr::Local(LocalCodePtr::UserTermExpansion(_)) => - self.fail = true, + if p < code_repo.term_expanders.len() => {} + CodePtr::Local(LocalCodePtr::UserTermExpansion(_)) => self.fail = true, CodePtr::Local(LocalCodePtr::UserGoalExpansion(p)) - if p < code_repo.goal_expanders.len() => {}, - CodePtr::Local(LocalCodePtr::UserGoalExpansion(_)) => - self.fail = true, - CodePtr::Local(LocalCodePtr::InSituDirEntry(p)) - if p < code_repo.in_situ_code.len() => {}, - CodePtr::Local(_) | CodePtr::REPL(..) => - return false, + if p < code_repo.goal_expanders.len() => {} + CodePtr::Local(LocalCodePtr::UserGoalExpansion(_)) => self.fail = true, + CodePtr::Local(LocalCodePtr::InSituDirEntry(p)) if p < code_repo.in_situ_code.len() => { + } + CodePtr::Local(_) | CodePtr::REPL(..) => return false, CodePtr::DynamicTransaction(..) => { // prevent use of dynamic transactions from // succeeding in expansions. self.fail will be toggled // back to false later. self.fail = true; return false; - }, + } _ => {} } @@ -777,10 +823,13 @@ impl MachineState { } // return true iff verify_attr_interrupt is called. - fn verify_attr_stepper(&mut self, indices: &mut IndexStore, policies: &mut MachinePolicies, - code_repo: &mut CodeRepo, prolog_stream: &mut PrologStream) - -> bool - { + fn verify_attr_stepper( + &mut self, + indices: &mut IndexStore, + policies: &mut MachinePolicies, + code_repo: &mut CodeRepo, + prolog_stream: &mut PrologStream, + ) -> bool { loop { let instr = match code_repo.lookup_instr(self.last_call, &self.p) { Some(instr) => { @@ -791,8 +840,8 @@ impl MachineState { self.run_verify_attr_interrupt(cp); return true; } - }, - None => return false + } + None => return false, }; self.dispatch_instr(instr.as_ref(), indices, policies, code_repo, prolog_stream); @@ -814,9 +863,13 @@ impl MachineState { self.verify_attr_interrupt(p); } - fn query_stepper(&mut self, indices: &mut IndexStore, policies: &mut MachinePolicies, - code_repo: &mut CodeRepo, prolog_stream: &mut PrologStream) - { + fn query_stepper( + &mut self, + indices: &mut IndexStore, + policies: &mut MachinePolicies, + code_repo: &mut CodeRepo, + prolog_stream: &mut PrologStream, + ) { loop { self.execute_instr(indices, policies, code_repo, prolog_stream); @@ -825,7 +878,7 @@ impl MachineState { } match self.p { - CodePtr::VerifyAttrInterrupt(_) => { + CodePtr::VerifyAttrInterrupt(_) => { self.p = CodePtr::Local(self.attr_var_init.cp + 1); if !self.verify_attr_stepper(indices, policies, code_repo, prolog_stream) { @@ -836,11 +889,12 @@ impl MachineState { let cp = self.p.local(); self.run_verify_attr_interrupt(cp); } - }, - _ => + } + _ => { if !self.check_machine_index(code_repo) { break; } + } } } } diff --git a/src/prolog/machine/modules.rs b/src/prolog/machine/modules.rs index c66a8f62..94f218ba 100644 --- a/src/prolog/machine/modules.rs +++ b/src/prolog/machine/modules.rs @@ -6,37 +6,50 @@ use prolog::machine::code_repo::*; use prolog::machine::machine_errors::*; use prolog::machine::machine_indices::*; -use std::collections::{VecDeque}; +use std::collections::VecDeque; // Module's and related types are defined in forms. impl Module { pub fn new(module_decl: ModuleDecl, atom_tbl: TabledData) -> Self { - Module { module_decl, atom_tbl, - user_term_expansions: (Predicate::new(), VecDeque::from(vec![])), - user_goal_expansions: (Predicate::new(), VecDeque::from(vec![])), - term_expansions: (Predicate::new(), VecDeque::from(vec![])), - goal_expansions: (Predicate::new(), VecDeque::from(vec![])), - code_dir: CodeDir::new(), - op_dir: default_op_dir(), - inserted_expansions: false } + Module { + module_decl, + atom_tbl, + user_term_expansions: (Predicate::new(), VecDeque::from(vec![])), + user_goal_expansions: (Predicate::new(), VecDeque::from(vec![])), + term_expansions: (Predicate::new(), VecDeque::from(vec![])), + goal_expansions: (Predicate::new(), VecDeque::from(vec![])), + code_dir: CodeDir::new(), + op_dir: default_op_dir(), + inserted_expansions: false, + } } - pub fn dump_expansions(&self, code_repo: &mut CodeRepo, flags: MachineFlags) - -> Result<(), ParserError> - { + pub fn dump_expansions( + &self, + code_repo: &mut CodeRepo, + flags: MachineFlags, + ) -> Result<(), ParserError> { { - let te = code_repo.term_dir.entry((clause_name!("term_expansion"), 2)) + let te = code_repo + .term_dir + .entry((clause_name!("term_expansion"), 2)) .or_insert((Predicate::new(), VecDeque::from(vec![]))); - (te.0).0.extend((self.user_term_expansions.0).0.iter().cloned()); + (te.0) + .0 + .extend((self.user_term_expansions.0).0.iter().cloned()); te.1.extend(self.user_term_expansions.1.iter().cloned()); } { - let ge = code_repo.term_dir.entry((clause_name!("goal_expansion"), 2)) + let ge = code_repo + .term_dir + .entry((clause_name!("goal_expansion"), 2)) .or_insert((Predicate::new(), VecDeque::from(vec![]))); - (ge.0).0.extend((self.user_goal_expansions.0).0.iter().cloned()); + (ge.0) + .0 + .extend((self.user_goal_expansions.0).0.iter().cloned()); ge.1.extend(self.user_goal_expansions.1.iter().cloned()); } @@ -46,14 +59,17 @@ impl Module { Ok(()) } - pub fn add_module_expansion_record(&mut self, hook: CompileTimeHook, clause: PredicateClause, - queue: VecDeque) - { + pub fn add_module_expansion_record( + &mut self, + hook: CompileTimeHook, + clause: PredicateClause, + queue: VecDeque, + ) { match hook { CompileTimeHook::TermExpansion | CompileTimeHook::UserTermExpansion => { (self.term_expansions.0).0.push(clause); self.term_expansions.1.extend(queue.into_iter()); - }, + } CompileTimeHook::GoalExpansion | CompileTimeHook::UserGoalExpansion => { (self.goal_expansions.0).0.push(clause); self.goal_expansions.1.extend(queue.into_iter()); @@ -62,8 +78,7 @@ impl Module { } } -pub trait SubModuleUser -{ +pub trait SubModuleUser { fn atom_tbl(&self) -> TabledData; fn op_dir(&mut self) -> &mut OpDir; fn remove_code_index(&mut self, PredicateKey); @@ -71,18 +86,18 @@ pub trait SubModuleUser fn insert_dir_entry(&mut self, ClauseName, usize, CodeIndex); - fn get_op_module_name(&mut self, name: ClauseName, fixity: Fixity) -> Option - { - self.op_dir().get(&(name, fixity)).map(|op_val| op_val.owning_module()) + fn get_op_module_name(&mut self, name: ClauseName, fixity: Fixity) -> Option { + self.op_dir() + .get(&(name, fixity)) + .map(|op_val| op_val.owning_module()) } - fn remove_module(&mut self, mod_name: ClauseName, module: &Module) - { + fn remove_module(&mut self, mod_name: ClauseName, module: &Module) { for (name, arity) in module.module_decl.exports.iter().cloned() { let name = name.defrock_brackets(); match self.get_code_index((name.clone(), arity), mod_name.clone()) { - Some(CodeIndex (ref code_idx)) => { + Some(CodeIndex(ref code_idx)) => { if &code_idx.borrow().1 != &module.module_decl.name { continue; } @@ -91,15 +106,13 @@ pub trait SubModuleUser // remove or respecify ops. if arity == 2 { - if let Some(mod_name) = self.get_op_module_name(name.clone(), Fixity::In) - { + if let Some(mod_name) = self.get_op_module_name(name.clone(), Fixity::In) { if mod_name == module.module_decl.name { self.op_dir().remove(&(name.clone(), Fixity::In)); } } } else if arity == 1 { - if let Some(mod_name) = self.get_op_module_name(name.clone(), Fixity::Pre) - { + if let Some(mod_name) = self.get_op_module_name(name.clone(), Fixity::Pre) { if mod_name == module.module_decl.name { self.op_dir().remove(&(name.clone(), Fixity::Pre)); } @@ -112,15 +125,14 @@ pub trait SubModuleUser } } } - }, + } _ => {} }; } } - + // returns true on successful import. - fn import_decl(&mut self, name: ClauseName, arity: usize, submodule: &Module) -> bool - { + fn import_decl(&mut self, name: ClauseName, arity: usize, submodule: &Module) -> bool { let name = name.defrock_brackets(); let mut found_op = false; @@ -153,17 +165,30 @@ pub trait SubModuleUser } } - fn use_qualified_module(&mut self, &mut CodeRepo, MachineFlags, &Module, &Vec) - -> Result<(), SessionError>; + fn use_qualified_module( + &mut self, + &mut CodeRepo, + MachineFlags, + &Module, + &Vec, + ) -> Result<(), SessionError>; fn use_module(&mut self, &mut CodeRepo, MachineFlags, &Module) -> Result<(), SessionError>; } -pub fn use_qualified_module(user: &mut User, submodule: &Module, exports: &Vec) - -> Result<(), SessionError> - where User: SubModuleUser +pub fn use_qualified_module( + user: &mut User, + submodule: &Module, + exports: &Vec, +) -> Result<(), SessionError> +where + User: SubModuleUser, { for (name, arity) in exports.iter().cloned() { - if !submodule.module_decl.exports.contains(&(name.clone(), arity)) { + if !submodule + .module_decl + .exports + .contains(&(name.clone(), arity)) + { continue; } @@ -175,9 +200,10 @@ pub fn use_qualified_module(user: &mut User, submodule: &Module, exports: Ok(()) } -pub fn use_module(user: &mut User, submodule: &Module) - -> Result<(), SessionError> -{ +pub fn use_module( + user: &mut User, + submodule: &Module, +) -> Result<(), SessionError> { for (name, arity) in submodule.module_decl.exports.iter().cloned() { if !user.import_decl(name, arity, submodule) { return Err(SessionError::ModuleDoesNotContainExport); @@ -208,31 +234,53 @@ impl SubModuleUser for Module { self.code_dir.insert((name, arity), idx); } - fn use_qualified_module(&mut self, _: &mut CodeRepo, _: MachineFlags, submodule: &Module, - exports: &Vec) - -> Result<(), SessionError> - { + fn use_qualified_module( + &mut self, + _: &mut CodeRepo, + _: MachineFlags, + submodule: &Module, + exports: &Vec, + ) -> Result<(), SessionError> { use_qualified_module(self, submodule, exports)?; - (self.user_term_expansions.0).0.extend((submodule.term_expansions.0).0.iter().cloned()); - self.user_term_expansions.1.extend(submodule.term_expansions.1.iter().cloned()); + (self.user_term_expansions.0) + .0 + .extend((submodule.term_expansions.0).0.iter().cloned()); + self.user_term_expansions + .1 + .extend(submodule.term_expansions.1.iter().cloned()); - (self.user_goal_expansions.0).0.extend((submodule.goal_expansions.0).0.iter().cloned()); - self.user_goal_expansions.1.extend(submodule.goal_expansions.1.iter().cloned()); + (self.user_goal_expansions.0) + .0 + .extend((submodule.goal_expansions.0).0.iter().cloned()); + self.user_goal_expansions + .1 + .extend(submodule.goal_expansions.1.iter().cloned()); Ok(()) } - fn use_module(&mut self, _: &mut CodeRepo, _: MachineFlags, submodule: &Module) - -> Result<(), SessionError> - { + fn use_module( + &mut self, + _: &mut CodeRepo, + _: MachineFlags, + submodule: &Module, + ) -> Result<(), SessionError> { use_module(self, submodule)?; - (self.user_term_expansions.0).0.extend((submodule.term_expansions.0).0.iter().cloned()); - self.user_term_expansions.1.extend(submodule.term_expansions.1.iter().cloned()); - - (self.user_goal_expansions.0).0.extend((submodule.goal_expansions.0).0.iter().cloned()); - self.user_goal_expansions.1.extend(submodule.goal_expansions.1.iter().cloned()); + (self.user_term_expansions.0) + .0 + .extend((submodule.term_expansions.0).0.iter().cloned()); + self.user_term_expansions + .1 + .extend(submodule.term_expansions.1.iter().cloned()); + + (self.user_goal_expansions.0) + .0 + .extend((submodule.goal_expansions.0).0.iter().cloned()); + self.user_goal_expansions + .1 + .extend(submodule.goal_expansions.1.iter().cloned()); Ok(()) } diff --git a/src/prolog/machine/or_stack.rs b/src/prolog/machine/or_stack.rs index 5fc9fab0..d6b76b36 100644 --- a/src/prolog/machine/or_stack.rs +++ b/src/prolog/machine/or_stack.rs @@ -9,29 +9,29 @@ pub struct Frame { pub e: usize, pub cp: LocalCodePtr, pub attr_var_init_b: usize, - pub b: usize, + pub b: usize, pub bp: CodePtr, pub tr: usize, pub pstr_tr: usize, pub h: usize, pub b0: usize, - args: Vec + args: Vec, } impl Frame { - fn new(global_index: usize, - e: usize, - cp: LocalCodePtr, - attr_var_init_b: usize, - b: usize, - bp: CodePtr, - tr: usize, - pstr_tr: usize, - h: usize, - b0: usize, - n: usize) - -> Self - { + fn new( + global_index: usize, + e: usize, + cp: LocalCodePtr, + attr_var_init_b: usize, + b: usize, + bp: CodePtr, + tr: usize, + pstr_tr: usize, + h: usize, + b0: usize, + n: usize, + ) -> Self { Frame { global_index, e, @@ -43,7 +43,7 @@ impl Frame { pstr_tr, h, b0, - args: vec![Addr::HeapCell(0); n] + args: vec![Addr::HeapCell(0); n], } } @@ -59,20 +59,33 @@ impl OrStack { OrStack(Vec::new()) } - pub fn push(&mut self, - global_index: usize, - e: usize, - cp: LocalCodePtr, - attr_var_init_b: usize, - b: usize, - bp: CodePtr, - tr: usize, - pstr_tr: usize, - h: usize, - b0: usize, - n: usize) - { - self.0.push(Frame::new(global_index, e, cp, attr_var_init_b, b, bp, tr, pstr_tr, h, b0, n)); + pub fn push( + &mut self, + global_index: usize, + e: usize, + cp: LocalCodePtr, + attr_var_init_b: usize, + b: usize, + bp: CodePtr, + tr: usize, + pstr_tr: usize, + h: usize, + b0: usize, + n: usize, + ) { + self.0.push(Frame::new( + global_index, + e, + cp, + attr_var_init_b, + b, + bp, + tr, + pstr_tr, + h, + b0, + n, + )); } #[inline] @@ -87,7 +100,7 @@ impl OrStack { pub fn clear(&mut self) { self.0.clear() } - + pub fn top(&self) -> Option<&Frame> { self.0.last() } @@ -97,7 +110,7 @@ impl OrStack { pub fn truncate(&mut self, new_b: usize) { self.0.truncate(new_b); } - + pub fn is_empty(&self) -> bool { self.0.is_empty() } diff --git a/src/prolog/machine/system_calls.rs b/src/prolog/machine/system_calls.rs index f00583ee..81a634df 100644 --- a/src/prolog/machine/system_calls.rs +++ b/src/prolog/machine/system_calls.rs @@ -12,9 +12,9 @@ use prolog::machine::copier::*; use prolog::machine::machine_errors::*; use prolog::machine::machine_indices::*; use prolog::machine::machine_state::*; -use prolog::machine::toplevel::{to_op_decl}; +use prolog::machine::toplevel::to_op_decl; use prolog::ordered_float::OrderedFloat; -use prolog::read::{PrologStream, readline}; +use prolog::read::{readline, PrologStream}; use prolog::rug::Integer; use indexmap::{IndexMap, IndexSet}; @@ -29,25 +29,31 @@ struct BrentAlgState { hare: usize, tortoise: usize, power: usize, - steps: usize + steps: usize, } impl BrentAlgState { fn new(hare: usize) -> Self { - BrentAlgState { hare, tortoise: hare, power: 2, steps: 1 } + BrentAlgState { + hare, + tortoise: hare, + power: 2, + steps: 1, + } } } fn scan_for_trust_me(code: &Code, jmp_offsets: &mut VecDeque, after_idx: &mut usize) { - for (idx, instr) in code[*after_idx ..].iter().enumerate() { + for (idx, instr) in code[*after_idx..].iter().enumerate() { match instr { &Line::Choice(ChoiceInstruction::TrustMe) - | &Line::IndexedChoice(IndexedChoiceInstruction::Trust(..)) => { + | &Line::IndexedChoice(IndexedChoiceInstruction::Trust(..)) => { *after_idx += idx; return; - }, - &Line::Control(ControlInstruction::JmpBy(_, offset, ..)) => - jmp_offsets.push_back(*after_idx + idx + offset), + } + &Line::Control(ControlInstruction::JmpBy(_, offset, ..)) => { + jmp_offsets.push_back(*after_idx + idx + offset) + } _ => {} } } @@ -62,50 +68,48 @@ fn is_builtin_predicate(name: &ClauseName) -> bool { impl MachineState { // a step in Brent's algorithm. - fn brents_alg_step(&self, brent_st: &mut BrentAlgState) -> Option - { + fn brents_alg_step(&self, brent_st: &mut BrentAlgState) -> Option { match self.heap[brent_st.hare].clone() { - HeapCellValue::NamedStr(..) => - Some(CycleSearchResult::NotList), - HeapCellValue::Addr(addr) => - match self.store(self.deref(addr)) { - Addr::Con(Constant::EmptyList) => - Some(CycleSearchResult::ProperList(brent_st.steps)), - Addr::HeapCell(_) | Addr::StackCell(..) => - Some(CycleSearchResult::PartialList(brent_st.steps, brent_st.hare)), - Addr::Con(Constant::String(ref s)) - if self.flags.double_quotes.is_chars() => - Some(CycleSearchResult::String(brent_st.steps, s.clone())), - Addr::Lis(l) => { - brent_st.hare = l + 1; - brent_st.steps += 1; - - if brent_st.tortoise == brent_st.hare { - return Some(CycleSearchResult::NotList); - } else if brent_st.steps == brent_st.power { - brent_st.tortoise = brent_st.hare; - brent_st.power <<= 1; - } + HeapCellValue::NamedStr(..) => Some(CycleSearchResult::NotList), + HeapCellValue::Addr(addr) => match self.store(self.deref(addr)) { + Addr::Con(Constant::EmptyList) => { + Some(CycleSearchResult::ProperList(brent_st.steps)) + } + Addr::HeapCell(_) | Addr::StackCell(..) => Some(CycleSearchResult::PartialList( + brent_st.steps, + brent_st.hare, + )), + Addr::Con(Constant::String(ref s)) if self.flags.double_quotes.is_chars() => { + Some(CycleSearchResult::String(brent_st.steps, s.clone())) + } + Addr::Lis(l) => { + brent_st.hare = l + 1; + brent_st.steps += 1; + + if brent_st.tortoise == brent_st.hare { + return Some(CycleSearchResult::NotList); + } else if brent_st.steps == brent_st.power { + brent_st.tortoise = brent_st.hare; + brent_st.power <<= 1; + } - None - }, - _ => - Some(CycleSearchResult::NotList) + None } + _ => Some(CycleSearchResult::NotList), + }, } } - pub(super) fn detect_cycles_with_max(&self, max_steps: usize, addr: Addr) -> CycleSearchResult - { + pub(super) fn detect_cycles_with_max(&self, max_steps: usize, addr: Addr) -> CycleSearchResult { let addr = self.store(self.deref(addr)); let hare = match addr { Addr::Lis(offset) if max_steps > 0 => offset + 1, Addr::Lis(offset) => return CycleSearchResult::UntouchedList(offset), Addr::Con(Constant::EmptyList) => return CycleSearchResult::EmptyList, - Addr::Con(Constant::String(ref s)) - if !self.flags.double_quotes.is_atom() => - return CycleSearchResult::String(0, s.clone()), - _ => return CycleSearchResult::NotList + Addr::Con(Constant::String(ref s)) if !self.flags.double_quotes.is_atom() => { + return CycleSearchResult::String(0, s.clone()) + } + _ => return CycleSearchResult::NotList, }; let mut brent_st = BrentAlgState::new(hare); @@ -121,16 +125,15 @@ impl MachineState { } } - pub(super) fn detect_cycles(&self, addr: Addr) -> CycleSearchResult - { + pub(super) fn detect_cycles(&self, addr: Addr) -> CycleSearchResult { let addr = self.store(self.deref(addr)); let hare = match addr { Addr::Lis(offset) => offset + 1, Addr::Con(Constant::EmptyList) => return CycleSearchResult::EmptyList, - Addr::Con(Constant::String(ref s)) - if !self.flags.double_quotes.is_atom() => - return CycleSearchResult::String(0, s.clone()), - _ => return CycleSearchResult::NotList + Addr::Con(Constant::String(ref s)) if !self.flags.double_quotes.is_atom() => { + return CycleSearchResult::String(0, s.clone()) + } + _ => return CycleSearchResult::NotList, }; let mut brent_st = BrentAlgState::new(hare); @@ -156,55 +159,72 @@ impl MachineState { let max_steps = self.store(self.deref(self[temp_v!(2)].clone())); match max_steps { - Addr::Con(Constant::Integer(ref max_steps)) => + Addr::Con(Constant::Integer(ref max_steps)) => { if max_steps.to_isize().map(|i| i >= -1).unwrap_or(false) { let n = self.store(self.deref(self[temp_v!(1)].clone())); match n { Addr::Con(Constant::Integer(ref n)) if n == &0 => { let xs0 = self[temp_v!(3)].clone(); - let xs = self[temp_v!(4)].clone(); + let xs = self[temp_v!(4)].clone(); self.unify(xs0, xs); - }, + } _ => { let (max_steps, search_result) = if let Some(max_steps) = max_steps.to_isize() { - (max_steps, if max_steps == -1 { - self.detect_cycles(self[temp_v!(3)].clone()) - } else { - self.detect_cycles_with_max(max_steps as usize, - self[temp_v!(3)].clone()) - }) + ( + max_steps, + if max_steps == -1 { + self.detect_cycles(self[temp_v!(3)].clone()) + } else { + self.detect_cycles_with_max( + max_steps as usize, + self[temp_v!(3)].clone(), + ) + }, + ) } else { (-1, self.detect_cycles(self[temp_v!(3)].clone())) }; match search_result { - CycleSearchResult::String(n, s) => + CycleSearchResult::String(n, s) => { if max_steps == -1 { - self.finalize_skip_max_list(n + s.len(), - Addr::Con(Constant::EmptyList)) + self.finalize_skip_max_list( + n + s.len(), + Addr::Con(Constant::EmptyList), + ) } else { let i = (max_steps as usize) - n; if s.len() < i { - self.finalize_skip_max_list(n + s.len(), - Addr::Con(Constant::EmptyList)) + self.finalize_skip_max_list( + n + s.len(), + Addr::Con(Constant::EmptyList), + ) } else { - let s = StringList::new(s.char_span(i), s.is_expandable()); - self.finalize_skip_max_list(i + n, - Addr::Con(Constant::String(s))) + let s = + StringList::new(s.char_span(i), s.is_expandable()); + self.finalize_skip_max_list( + i + n, + Addr::Con(Constant::String(s)), + ) } - }, - CycleSearchResult::UntouchedList(l) => - self.finalize_skip_max_list(0, Addr::Lis(l)), - CycleSearchResult::EmptyList => - self.finalize_skip_max_list(0, Addr::Con(Constant::EmptyList)), - CycleSearchResult::PartialList(n, hc) => - self.finalize_skip_max_list(n, Addr::HeapCell(hc)), - CycleSearchResult::ProperList(n) => - self.finalize_skip_max_list(n, Addr::Con(Constant::EmptyList)), + } + } + CycleSearchResult::UntouchedList(l) => { + self.finalize_skip_max_list(0, Addr::Lis(l)) + } + CycleSearchResult::EmptyList => { + self.finalize_skip_max_list(0, Addr::Con(Constant::EmptyList)) + } + CycleSearchResult::PartialList(n, hc) => { + self.finalize_skip_max_list(n, Addr::HeapCell(hc)) + } + CycleSearchResult::ProperList(n) => { + self.finalize_skip_max_list(n, Addr::Con(Constant::EmptyList)) + } CycleSearchResult::NotList => { let xs0 = self[temp_v!(3)].clone(); self.finalize_skip_max_list(0, xs0); @@ -214,15 +234,17 @@ impl MachineState { } } else { self.fail = true; - }, + } + } Addr::HeapCell(_) | Addr::StackCell(..) => { let stub = MachineError::functor_stub(clause_name!("$skip_max_list"), 4); return Err(self.error_form(MachineError::instantiation_error(), stub)); - }, + } addr => { let stub = MachineError::functor_stub(clause_name!("$skip_max_list"), 4); - return Err(self.error_form(MachineError::type_error(ValidType::Integer, addr), - stub)); + return Err( + self.error_form(MachineError::type_error(ValidType::Integer, addr), stub) + ); } }; @@ -240,11 +262,10 @@ impl MachineState { self.block } - fn copy_findall_solution(&mut self, lh_offset: usize, copy_target: Addr) -> usize - { + fn copy_findall_solution(&mut self, lh_offset: usize, copy_target: Addr) -> usize { let threshold = self.lifted_heap.len() - lh_offset; - let mut copy_ball_term = CopyBallTerm::new(&mut self.and_stack, &mut self.heap, - &mut self.lifted_heap); + let mut copy_ball_term = + CopyBallTerm::new(&mut self.and_stack, &mut self.heap, &mut self.lifted_heap); copy_ball_term.push(HeapCellValue::Addr(Addr::Lis(threshold + 1))); copy_ball_term.push(HeapCellValue::Addr(Addr::HeapCell(threshold + 3))); @@ -266,7 +287,8 @@ impl MachineState { } fn truncate_if_no_lifted_heap_diff(&mut self, addr_constr: AddrConstr) - where AddrConstr: Fn(usize) -> Addr + where + AddrConstr: Fn(usize) -> Addr, { match self.store(self.deref(self[temp_v!(1)].clone())) { Addr::Con(Constant::Usize(lh_offset)) => { @@ -274,11 +296,11 @@ impl MachineState { self.lifted_heap.truncate(lh_offset); } else { let threshold = self.lifted_heap.len() - lh_offset; - self.lifted_heap.push(HeapCellValue::Addr(addr_constr(threshold))); + self.lifted_heap + .push(HeapCellValue::Addr(addr_constr(threshold))); } - }, - _ => - self.fail = true + } + _ => self.fail = true, } } @@ -286,7 +308,7 @@ impl MachineState { match db_ref { &DBRef::NamedPred(ref name, arity, _) => { let key = (name.clone(), arity); - let mut iter = indices.code_dir.range(key ..).skip(1); + let mut iter = indices.code_dir.range(key..).skip(1); while let Some(((name, arity), idx)) = iter.next() { if idx.is_undefined() { @@ -301,45 +323,55 @@ impl MachineState { let a2 = self[temp_v!(2)].clone(); if let Some(r) = a2.as_var() { - let spec = get_clause_spec(name.clone(), *arity, - composite_op!(&indices.op_dir)); + let spec = + get_clause_spec(name.clone(), *arity, composite_op!(&indices.op_dir)); self.bind(r, Addr::DBRef(DBRef::NamedPred(name.clone(), *arity, spec))); return; } } self.fail = true; - }, + } &DBRef::Op(_, spec, ref name, ref op_dir, _) => { let fixity = match spec { XF | YF => Fixity::Post, FX | FY => Fixity::Pre, - _ => Fixity::In + _ => Fixity::In, }; let key = OrderedOpDirKey(name.clone(), fixity); - match op_dir.range(key ..).skip(1).next() { + match op_dir.range(key..).skip(1).next() { Some((OrderedOpDirKey(name, _), (priority, spec))) => { let a2 = self[temp_v!(2)].clone(); if let Some(r) = a2.as_var() { - self.bind(r, Addr::DBRef(DBRef::Op(*priority, *spec, name.clone(), - op_dir.clone(), - SharedOpDesc::new(*priority, *spec)))); + self.bind( + r, + Addr::DBRef(DBRef::Op( + *priority, + *spec, + name.clone(), + op_dir.clone(), + SharedOpDesc::new(*priority, *spec), + )), + ); } else { self.fail = true; } - }, - None => self.fail = true + } + None => self.fail = true, } } } } - fn int_to_char_code(&mut self, n: &Integer, stub: &'static str, arity: usize) - -> Result - { + fn int_to_char_code( + &mut self, + n: &Integer, + stub: &'static str, + arity: usize, + ) -> Result { if let Some(c) = n.to_u8() { Ok(c) } else { @@ -351,16 +383,23 @@ impl MachineState { } } - fn parse_number_from_string(&mut self, mut string: String, indices: &IndexStore, stub: MachineStub) - -> CallResult - { - let nx = self[temp_v!(2)].clone(); + fn parse_number_from_string( + &mut self, + mut string: String, + indices: &IndexStore, + stub: MachineStub, + ) -> CallResult { + let nx = self[temp_v!(2)].clone(); if let Some(c) = string.chars().last() { if layout_char!(c) { - let (line_num, col_num) = string.chars().fold((0, 0), |(line_num, col_num), c| - if new_line_char!(c) { (1 + line_num, 0) } else { (line_num, col_num + 1) } - ); + let (line_num, col_num) = string.chars().fold((0, 0), |(line_num, col_num), c| { + if new_line_char!(c) { + (1 + line_num, 0) + } else { + (line_num, col_num + 1) + } + }); let err = ParserError::UnexpectedChar(c, line_num, col_num); let h = self.heap.h; @@ -373,8 +412,7 @@ impl MachineState { string.push('.'); let mut stream = parsing_stream(std::io::Cursor::new(string)); - let mut parser = Parser::new(&mut stream, indices.atom_tbl.clone(), - self.machine_flags()); + let mut parser = Parser::new(&mut stream, indices.atom_tbl.clone(), self.machine_flags()); match parser.read_term(composite_op!(&indices.op_dir)) { Err(err) => { @@ -382,15 +420,19 @@ impl MachineState { let err = MachineError::syntax_error(h, err); return Err(self.error_form(err, stub)); - }, - Ok(Term::Constant(_, Constant::Rational(n))) => - self.unify(nx, Addr::Con(Constant::Rational(n))), - Ok(Term::Constant(_, Constant::Float(n))) => - self.unify(nx, Addr::Con(Constant::Float(n))), - Ok(Term::Constant(_, Constant::Integer(n))) => - self.unify(nx, Addr::Con(Constant::Integer(n))), - Ok(Term::Constant(_, Constant::CharCode(c))) => - self.unify(nx, Addr::Con(Constant::CharCode(c))), + } + Ok(Term::Constant(_, Constant::Rational(n))) => { + self.unify(nx, Addr::Con(Constant::Rational(n))) + } + Ok(Term::Constant(_, Constant::Float(n))) => { + self.unify(nx, Addr::Con(Constant::Float(n))) + } + Ok(Term::Constant(_, Constant::Integer(n))) => { + self.unify(nx, Addr::Con(Constant::Integer(n))) + } + Ok(Term::Constant(_, Constant::CharCode(c))) => { + self.unify(nx, Addr::Con(Constant::CharCode(c))) + } _ => { let err = ParserError::ParseBigInt(0, 0); @@ -404,8 +446,7 @@ impl MachineState { Ok(()) } - fn create_instruction_functors(&mut self, code: &Code, first_idx: usize) -> Vec - { + fn create_instruction_functors(&mut self, code: &Code, first_idx: usize) -> Vec { let mut queue = VecDeque::new(); let mut functors = vec![]; let mut h = self.heap.h; @@ -418,27 +459,25 @@ impl MachineState { loop { match &code[last_idx] { &Line::Choice(ChoiceInstruction::TryMeElse(..)) - | &Line::IndexedChoice(IndexedChoiceInstruction::Try(..)) => { + | &Line::IndexedChoice(IndexedChoiceInstruction::Try(..)) => { last_idx += 1; scan_for_trust_me(code, &mut queue, &mut last_idx); - }, + } &Line::Control(ControlInstruction::JmpBy(_, offset, _, false)) => { queue.push_back(last_idx + offset); last_idx += 1; - }, + } &Line::Control(ControlInstruction::JmpBy(_, offset, _, true)) => { queue.push_back(last_idx + offset); break; - }, + } &Line::Control(ControlInstruction::Proceed) - | &Line::Control(ControlInstruction::CallClause(_, _, _, true, _)) => - break, - _ => - last_idx += 1 + | &Line::Control(ControlInstruction::CallClause(_, _, _, true, _)) => break, + _ => last_idx += 1, }; } - for instr in &code[first_idx .. last_idx + 1] { + for instr in &code[first_idx..last_idx + 1] { let section = instr.to_functor(h); functors.push(Addr::HeapCell(h)); @@ -450,16 +489,15 @@ impl MachineState { functors } - pub(super) - fn system_call(&mut self, - ct: &SystemClauseType, - code_repo: &CodeRepo, - indices: &mut IndexStore, - call_policy: &mut Box, - cut_policy: &mut Box, - current_input_stream: &mut PrologStream) - -> CallResult - { + pub(super) fn system_call( + &mut self, + ct: &SystemClauseType, + code_repo: &CodeRepo, + indices: &mut IndexStore, + call_policy: &mut Box, + cut_policy: &mut Box, + current_input_stream: &mut PrologStream, + ) -> CallResult { match ct { &SystemClauseType::AbolishClause => { let p = self.cp; @@ -467,28 +505,28 @@ impl MachineState { self.p = CodePtr::DynamicTransaction(trans_type, p); return Ok(()); - }, + } &SystemClauseType::AbolishModuleClause => { let p = self.cp; let trans_type = DynamicTransactionType::ModuleAbolish; self.p = CodePtr::DynamicTransaction(trans_type, p); return Ok(()); - }, + } &SystemClauseType::AssertDynamicPredicateToFront => { let p = self.cp; let trans_type = DynamicTransactionType::Assert(DynamicAssertPlace::Front); self.p = CodePtr::DynamicTransaction(trans_type, p); return Ok(()); - }, + } &SystemClauseType::AssertDynamicPredicateToBack => { let p = self.cp; let trans_type = DynamicTransactionType::Assert(DynamicAssertPlace::Back); self.p = CodePtr::DynamicTransaction(trans_type, p); return Ok(()); - }, + } &SystemClauseType::AtomChars => { let a1 = self[temp_v!(1)].clone(); @@ -499,42 +537,45 @@ impl MachineState { let a2 = self[temp_v!(2)].clone(); self.unify(a2, list_of_chars); - }, + } Addr::Con(Constant::Atom(name, _)) => { let iter = name.as_str().chars().map(|c| Addr::Con(Constant::Char(c))); let list_of_chars = Addr::HeapCell(self.heap.to_list(iter)); let a2 = self[temp_v!(2)].clone(); self.unify(a2, list_of_chars); - }, + } Addr::Con(Constant::EmptyList) => { let a2 = self[temp_v!(2)].clone(); - let chars = vec![Addr::Con(Constant::Char('[')), - Addr::Con(Constant::Char(']'))]; + let chars = vec![ + Addr::Con(Constant::Char('[')), + Addr::Con(Constant::Char(']')), + ]; let list_of_chars = Addr::HeapCell(self.heap.to_list(chars.into_iter())); self.unify(a2, list_of_chars); - }, + } ref addr if addr.is_ref() => { let stub = MachineError::functor_stub(clause_name!("atom_chars"), 2); match self.try_from_list(temp_v!(2), stub.clone()) { Err(e) => return Err(e), - Ok(addrs) => - match self.try_char_list(addrs) { - Ok(string) => { - let chars = clause_name!(string, indices.atom_tbl); - self.unify(addr.clone(), Addr::Con(Constant::Atom(chars, None))); - }, - Err(err) => - return Err(self.error_form(err, stub)) + Ok(addrs) => match self.try_char_list(addrs) { + Ok(string) => { + let chars = clause_name!(string, indices.atom_tbl); + self.unify( + addr.clone(), + Addr::Con(Constant::Atom(chars, None)), + ); } + Err(err) => return Err(self.error_form(err, stub)), + }, } - }, - _ => unreachable!() + } + _ => unreachable!(), }; - }, + } &SystemClauseType::AtomCodes => { let a1 = self[temp_v!(1)].clone(); @@ -545,24 +586,29 @@ impl MachineState { let a2 = self[temp_v!(2)].clone(); self.unify(a2, list_of_codes); - }, + } Addr::Con(Constant::Atom(name, _)) => { - let iter = name.as_str().chars().map(|c| Addr::Con(Constant::CharCode(c as u8))); + let iter = name + .as_str() + .chars() + .map(|c| Addr::Con(Constant::CharCode(c as u8))); let list_of_codes = Addr::HeapCell(self.heap.to_list(iter)); let a2 = self[temp_v!(2)].clone(); self.unify(a2, list_of_codes); - }, + } Addr::Con(Constant::EmptyList) => { let a2 = self[temp_v!(2)].clone(); - let chars = vec![Addr::Con(Constant::CharCode('[' as u8)), - Addr::Con(Constant::CharCode(']' as u8))]; + let chars = vec![ + Addr::Con(Constant::CharCode('[' as u8)), + Addr::Con(Constant::CharCode(']' as u8)), + ]; let list_of_codes = Addr::HeapCell(self.heap.to_list(chars.into_iter())); self.unify(a2, list_of_codes); - }, + } ref addr if addr.is_ref() => { let stub = MachineError::functor_stub(clause_name!("atom_codes"), 2); @@ -576,11 +622,13 @@ impl MachineState { &Addr::Con(Constant::Integer(ref n)) => { let c = self.int_to_char_code(&n, "atom_codes", 2)?; chars.push(c as char); - }, - &Addr::Con(Constant::CharCode(c)) => - chars.push(c as char), + } + &Addr::Con(Constant::CharCode(c)) => chars.push(c as char), _ => { - let err = MachineError::type_error(ValidType::Integer, addr.clone()); + let err = MachineError::type_error( + ValidType::Integer, + addr.clone(), + ); return Err(self.error_form(err, stub)); } } @@ -590,10 +638,10 @@ impl MachineState { self.unify(addr.clone(), Addr::Con(Constant::Atom(chars, None))); } } - }, - _ => unreachable!() + } + _ => unreachable!(), }; - }, + } &SystemClauseType::AtomLength => { let a1 = self[temp_v!(1)].clone(); @@ -601,98 +649,92 @@ impl MachineState { Addr::Con(Constant::Atom(name, _)) => name, Addr::Con(Constant::EmptyList) => clause_name!("[]"), Addr::Con(Constant::Char(c)) => clause_name!(c.to_string(), indices.atom_tbl), - _ => unreachable!() + _ => unreachable!(), }; let len = Integer::from(atom.as_str().len()); - let a2 = self[temp_v!(2)].clone(); + let a2 = self[temp_v!(2)].clone(); self.unify(a2, Addr::Con(Constant::Integer(len))); - }, + } &SystemClauseType::CharsToNumber => { let stub = MachineError::functor_stub(clause_name!("number_chars"), 2); match self.try_from_list(temp_v!(1), stub.clone()) { Err(e) => return Err(e), - Ok(addrs) => - match self.try_char_list(addrs) { - Ok(string) => - self.parse_number_from_string(string, indices, stub)?, - Err(err) => - return Err(self.error_form(err, stub)) - } + Ok(addrs) => match self.try_char_list(addrs) { + Ok(string) => self.parse_number_from_string(string, indices, stub)?, + Err(err) => return Err(self.error_form(err, stub)), + }, } - }, + } &SystemClauseType::NumberToChars => { let n = self[temp_v!(1)].clone(); let chs = self[temp_v!(2)].clone(); let string = match self.store(self.deref(n)) { - Addr::Con(Constant::Float(OrderedFloat(n))) => - format!("{0:<20?}", n), - Addr::Con(Constant::Integer(n)) => - n.to_string(), - _ => unreachable!() + Addr::Con(Constant::Float(OrderedFloat(n))) => format!("{0:<20?}", n), + Addr::Con(Constant::Integer(n)) => n.to_string(), + _ => unreachable!(), }; let chars = string.trim().chars().map(|c| Addr::Con(Constant::Char(c))); let char_list = Addr::HeapCell(self.heap.to_list(chars)); self.unify(char_list, chs); - }, + } &SystemClauseType::NumberToCodes => { let n = self[temp_v!(1)].clone(); let chs = self[temp_v!(2)].clone(); let string = match self.store(self.deref(n)) { - Addr::Con(Constant::Float(OrderedFloat(n))) => - format!("{0:<20?}", n), - Addr::Con(Constant::Integer(n)) => - n.to_string(), - _ => unreachable!() + Addr::Con(Constant::Float(OrderedFloat(n))) => format!("{0:<20?}", n), + Addr::Con(Constant::Integer(n)) => n.to_string(), + _ => unreachable!(), }; - let codes = string.trim().chars().map(|c| Addr::Con(Constant::CharCode(c as u8))); + let codes = string + .trim() + .chars() + .map(|c| Addr::Con(Constant::CharCode(c as u8))); let codes_list = Addr::HeapCell(self.heap.to_list(codes)); self.unify(codes_list, chs); - }, + } &SystemClauseType::CodesToNumber => { let stub = MachineError::functor_stub(clause_name!("number_codes"), 2); match self.try_from_list(temp_v!(1), stub.clone()) { Err(e) => return Err(e), - Ok(addrs) => - match self.try_code_list(addrs) { - Ok(codes) => { - let string = codes.iter().map(|c| *c as char).collect(); - self.parse_number_from_string(string, indices, stub)? - }, - Err(err) => - return Err(self.error_form(err, stub)) + Ok(addrs) => match self.try_code_list(addrs) { + Ok(codes) => { + let string = codes.iter().map(|c| *c as char).collect(); + self.parse_number_from_string(string, indices, stub)? } + Err(err) => return Err(self.error_form(err, stub)), + }, } - }, + } &SystemClauseType::ModuleAssertDynamicPredicateToFront => { let p = self.cp; let trans_type = DynamicTransactionType::ModuleAssert(DynamicAssertPlace::Front); self.p = CodePtr::DynamicTransaction(trans_type, p); return Ok(()); - }, + } &SystemClauseType::ModuleAssertDynamicPredicateToBack => { let p = self.cp; let trans_type = DynamicTransactionType::ModuleAssert(DynamicAssertPlace::Back); self.p = CodePtr::DynamicTransaction(trans_type, p); return Ok(()); - }, + } &SystemClauseType::LiftedHeapLength => { let a1 = self[temp_v!(1)].clone(); let lh_len = Addr::Con(Constant::Usize(self.lifted_heap.len())); self.unify(a1, lh_len); - }, + } &SystemClauseType::CharCode => { let a1 = self[temp_v!(1)].clone(); @@ -702,50 +744,51 @@ impl MachineState { let a2 = self[temp_v!(2)].clone(); self.unify(Addr::Con(Constant::CharCode(c as u8)), a2); - }, + } Addr::Con(Constant::Char(c)) => { let a2 = self[temp_v!(2)].clone(); self.unify(Addr::Con(Constant::CharCode(c as u8)), a2); - }, + } ref addr if addr.is_ref() => { let a2 = self[temp_v!(2)].clone(); match self.store(self.deref(a2)) { - Addr::Con(Constant::CharCode(code)) => - self.unify(Addr::Con(Constant::Char(code as char)), addr.clone()), + Addr::Con(Constant::CharCode(code)) => { + self.unify(Addr::Con(Constant::Char(code as char)), addr.clone()) + } Addr::Con(Constant::Integer(n)) => { let c = self.int_to_char_code(&n, "char_code", 2)?; self.unify(Addr::Con(Constant::Char(c as char)), addr.clone()); - }, - _ => self.fail = true + } + _ => self.fail = true, }; - }, - _ => unreachable!() + } + _ => unreachable!(), }; - }, + } &SystemClauseType::CheckCutPoint => { let addr = self.store(self.deref(self[temp_v!(1)].clone())); match addr { - Addr::Con(Constant::Usize(old_b)) if self.b <= old_b + 2 => {}, - _ => self.fail = true + Addr::Con(Constant::Usize(old_b)) if self.b <= old_b + 2 => {} + _ => self.fail = true, }; - }, + } &SystemClauseType::FetchGlobalVar => { let key = self[temp_v!(1)].clone(); let key = match self.store(self.deref(key)) { Addr::Con(Constant::Atom(atom, _)) => atom, - _ => unreachable!() + _ => unreachable!(), }; let addr = self[temp_v!(2)].clone(); match indices.global_variables.get(&key).cloned() { Some(sought_addr) => self.unify(addr, sought_addr), - None => self.fail = true + None => self.fail = true, }; - }, + } &SystemClauseType::GetChar => { let result = current_input_stream.next(); let a1 = self[temp_v!(1)].clone(); @@ -755,23 +798,22 @@ impl MachineState { Some(Err(_)) => { let end_of_file = clause_name!("end_of_file"); self.unify(a1, Addr::Con(Constant::Atom(end_of_file, None))); - }, + } None => { let stub = MachineError::functor_stub(clause_name!("get_char"), 1); let err = MachineError::representation_error(RepFlag::Character); let err = self.error_form(err, stub); return Err(err); - }, + } } - }, + } &SystemClauseType::GetModuleClause => { let module = self[temp_v!(3)].clone(); let head = self[temp_v!(1)].clone(); let module = match self.store(self.deref(module)) { - Addr::Con(Constant::Atom(module, _)) => - module, + Addr::Con(Constant::Atom(module, _)) => module, _ => { self.fail = true; return Ok(()); @@ -779,32 +821,32 @@ impl MachineState { }; let subsection = match self.store(self.deref(head)) { - Addr::Str(s) => - match self.heap[s].clone() { - HeapCellValue::NamedStr(arity, name, ..) => - indices.get_clause_subsection(module, name, arity), - _ => unreachable!() - }, - Addr::Con(Constant::Atom(name, _)) => - indices.get_clause_subsection(module, name, 0), - _ => unreachable!() + Addr::Str(s) => match self.heap[s].clone() { + HeapCellValue::NamedStr(arity, name, ..) => { + indices.get_clause_subsection(module, name, arity) + } + _ => unreachable!(), + }, + Addr::Con(Constant::Atom(name, _)) => { + indices.get_clause_subsection(module, name, 0) + } + _ => unreachable!(), }; match subsection { Some(dynamic_predicate_info) => { self.execute_at_index(2, dynamic_predicate_info.clauses_subsection_p); return Ok(()); - }, - None => self.fail = true + } + None => self.fail = true, } - }, + } &SystemClauseType::ModuleHeadIsDynamic => { let module = self[temp_v!(2)].clone(); let head = self[temp_v!(1)].clone(); let module = match self.store(self.deref(module)) { - Addr::Con(Constant::Atom(module, _)) => - module, + Addr::Con(Constant::Atom(module, _)) => module, _ => { self.fail = true; return Ok(()); @@ -812,33 +854,35 @@ impl MachineState { }; self.fail = !match self.store(self.deref(head)) { - Addr::Str(s) => - match self.heap[s].clone() { - HeapCellValue::NamedStr(arity, name, ..) => - indices.get_clause_subsection(module, name, arity).is_some(), - _ => unreachable!() - }, - Addr::Con(Constant::Atom(name, _)) => - indices.get_clause_subsection(module, name, 0).is_some(), - _ => unreachable!() + Addr::Str(s) => match self.heap[s].clone() { + HeapCellValue::NamedStr(arity, name, ..) => { + indices.get_clause_subsection(module, name, arity).is_some() + } + _ => unreachable!(), + }, + Addr::Con(Constant::Atom(name, _)) => { + indices.get_clause_subsection(module, name, 0).is_some() + } + _ => unreachable!(), }; - }, + } &SystemClauseType::HeadIsDynamic => { let head = self[temp_v!(1)].clone(); self.fail = !match self.store(self.deref(head)) { - Addr::Str(s) => - match self.heap[s].clone() { - HeapCellValue::NamedStr(arity, name, ..) => - indices.get_clause_subsection(name.owning_module(), name, arity).is_some(), - _ => unreachable!() - }, - Addr::Con(Constant::Atom(name, _)) => - indices.get_clause_subsection(name.owning_module(), name, 0).is_some(), - _ => unreachable!() + Addr::Str(s) => match self.heap[s].clone() { + HeapCellValue::NamedStr(arity, name, ..) => indices + .get_clause_subsection(name.owning_module(), name, arity) + .is_some(), + _ => unreachable!(), + }, + Addr::Con(Constant::Atom(name, _)) => indices + .get_clause_subsection(name.owning_module(), name, 0) + .is_some(), + _ => unreachable!(), }; - }, - &SystemClauseType::CopyToLiftedHeap => + } + &SystemClauseType::CopyToLiftedHeap => { match self.store(self.deref(self[temp_v!(1)].clone())) { Addr::Con(Constant::Usize(lh_offset)) => { let copy_target = self[temp_v!(2)].clone(); @@ -846,18 +890,21 @@ impl MachineState { let old_threshold = self.copy_findall_solution(lh_offset, copy_target); let new_threshold = self.lifted_heap.len() - lh_offset; - self.lifted_heap[old_threshold] = HeapCellValue::Addr(Addr::HeapCell(new_threshold)); + self.lifted_heap[old_threshold] = + HeapCellValue::Addr(Addr::HeapCell(new_threshold)); - for index in old_threshold + 1 .. self.lifted_heap.len() { + for index in old_threshold + 1..self.lifted_heap.len() { match &mut self.lifted_heap[index] { - &mut HeapCellValue::Addr(ref mut addr) => - *addr -= self.heap.len() + lh_offset, + &mut HeapCellValue::Addr(ref mut addr) => { + *addr -= self.heap.len() + lh_offset + } _ => {} } } - }, - _ => self.fail = true - }, + } + _ => self.fail = true, + } + } &SystemClauseType::DeleteAttribute => { let ls0 = self.store(self.deref(self[temp_v!(1)].clone())); @@ -868,41 +915,48 @@ impl MachineState { self.trail(TrailRef::AttrVarLink(l1 + 1, addr)); } } - }, + } &SystemClauseType::DeleteHeadAttribute => { let addr = self.store(self.deref(self[temp_v!(1)].clone())); match addr { Addr::AttrVar(h) => { - let addr = self.heap[h+1].as_addr(h+1).clone(); + let addr = self.heap[h + 1].as_addr(h + 1).clone(); let addr = self.store(self.deref(addr)); match addr { Addr::Lis(l) => { - self.heap[h+1] = HeapCellValue::Addr(Addr::HeapCell(l+1)); - self.trail(TrailRef::AttrVarLink(h+1, Addr::Lis(l))); - }, - _ => unreachable!() + self.heap[h + 1] = HeapCellValue::Addr(Addr::HeapCell(l + 1)); + self.trail(TrailRef::AttrVarLink(h + 1, Addr::Lis(l))); + } + _ => unreachable!(), } - }, - _ => unreachable!() + } + _ => unreachable!(), } - }, + } &SystemClauseType::DynamicModuleResolution => { let module_name = self.store(self.deref(self[temp_v!(1)].clone())); if let Addr::Con(Constant::Atom(module_name, _)) = module_name { match self.store(self.deref(self[temp_v!(2)].clone())) { - Addr::Str(a) => + Addr::Str(a) => { if let HeapCellValue::NamedStr(arity, name, _) = self.heap[a].clone() { - for i in 1 .. arity + 1 { - self.registers[i] = self.heap[a+i].as_addr(a+i); + for i in 1..arity + 1 { + self.registers[i] = self.heap[a + i].as_addr(a + i); } - return self.module_lookup(indices, (name, arity), module_name, true); - }, - Addr::Con(Constant::Atom(name, _)) => - return self.module_lookup(indices, (name, 0), module_name, true), + return self.module_lookup( + indices, + (name, arity), + module_name, + true, + ); + } + } + Addr::Con(Constant::Atom(name, _)) => { + return self.module_lookup(indices, (name, 0), module_name, true) + } addr => { let stub = MachineError::functor_stub(clause_name!("(:)"), 2); @@ -913,197 +967,199 @@ impl MachineState { } } }; - }, + } &SystemClauseType::EnqueueAttributeGoal => { let addr = self[temp_v!(1)].clone(); self.attr_var_init.attribute_goals.push(addr); - }, + } &SystemClauseType::EnqueueAttributedVar => { let addr = self[temp_v!(1)].clone(); match self.store(self.deref(addr)) { - Addr::AttrVar(h) => - self.attr_var_init.attr_var_queue.push(h), + Addr::AttrVar(h) => self.attr_var_init.attr_var_queue.push(h), _ => {} } - }, + } &SystemClauseType::ExpandGoal => { self.p = CodePtr::Local(LocalCodePtr::UserGoalExpansion(0)); return Ok(()); - }, + } &SystemClauseType::ExpandTerm => { self.p = CodePtr::Local(LocalCodePtr::UserTermExpansion(0)); return Ok(()); - }, + } &SystemClauseType::GetNextDBRef => { let a1 = self[temp_v!(1)].clone(); match self.store(self.deref(a1)) { addr @ Addr::HeapCell(_) - | addr @ Addr::StackCell(..) - | addr @ Addr::AttrVar(_) => { - let mut iter = indices.code_dir.iter(); + | addr @ Addr::StackCell(..) + | addr @ Addr::AttrVar(_) => { + let mut iter = indices.code_dir.iter(); - while let Some(((name, arity), _)) = iter.next() { - if is_builtin_predicate(&name) { - continue; - } + while let Some(((name, arity), _)) = iter.next() { + if is_builtin_predicate(&name) { + continue; + } - let spec = get_clause_spec(name.clone(), *arity, - composite_op!(&indices.op_dir)); - let db_ref = DBRef::NamedPred(name.clone(), *arity, spec); - let r = addr.as_var().unwrap(); + let spec = get_clause_spec( + name.clone(), + *arity, + composite_op!(&indices.op_dir), + ); + let db_ref = DBRef::NamedPred(name.clone(), *arity, spec); + let r = addr.as_var().unwrap(); - self.bind(r, Addr::DBRef(db_ref)); - return return_from_clause!(self.last_call, self); - } + self.bind(r, Addr::DBRef(db_ref)); + return return_from_clause!(self.last_call, self); + } - self.fail = true; - }, + self.fail = true; + } Addr::DBRef(DBRef::Op(..)) => self.fail = true, - Addr::DBRef(ref db_ref) => - self.get_next_db_ref(&indices, db_ref), + Addr::DBRef(ref db_ref) => self.get_next_db_ref(&indices, db_ref), _ => { - self.fail = true; + self.fail = true; } }; - }, + } &SystemClauseType::GetNextOpDBRef => { let a1 = self[temp_v!(1)].clone(); match self.store(self.deref(a1)) { addr @ Addr::HeapCell(_) - | addr @ Addr::StackCell(..) - | addr @ Addr::AttrVar(_) => { - let mut unossified_op_dir = OssifiedOpDir::new(); - - unossified_op_dir.extend(indices.op_dir.iter().filter_map(|(key, op_dir_val)| { - let (name, fixity) = key.clone(); + | addr @ Addr::StackCell(..) + | addr @ Addr::AttrVar(_) => { + let mut unossified_op_dir = OssifiedOpDir::new(); - let prec = op_dir_val.shared_op_desc().prec(); + unossified_op_dir.extend(indices.op_dir.iter().filter_map( + |(key, op_dir_val)| { + let (name, fixity) = key.clone(); - if prec == 0 { - return None; - } + let prec = op_dir_val.shared_op_desc().prec(); - let assoc = op_dir_val.shared_op_desc().assoc(); - - Some((OrderedOpDirKey(name, fixity), (prec, assoc))) - })); - - let ossified_op_dir = Rc::new(unossified_op_dir); + if prec == 0 { + return None; + } - match ossified_op_dir.iter().next() { - Some((OrderedOpDirKey(name, _), (priority, spec))) => { - let db_ref = DBRef::Op(*priority, *spec, name.clone(), - ossified_op_dir.clone(), - SharedOpDesc::new(*priority, *spec)); - let r = addr.as_var().unwrap(); + let assoc = op_dir_val.shared_op_desc().assoc(); - self.bind(r, Addr::DBRef(db_ref)); - }, - None => { - self.fail = true; - return Ok(()); - } - } - }, - Addr::DBRef(DBRef::NamedPred(..)) => - self.fail = true, - Addr::DBRef(ref db_ref) => - self.get_next_db_ref(&indices, db_ref), + Some((OrderedOpDirKey(name, fixity), (prec, assoc))) + }, + )); + + let ossified_op_dir = Rc::new(unossified_op_dir); + + match ossified_op_dir.iter().next() { + Some((OrderedOpDirKey(name, _), (priority, spec))) => { + let db_ref = DBRef::Op( + *priority, + *spec, + name.clone(), + ossified_op_dir.clone(), + SharedOpDesc::new(*priority, *spec), + ); + let r = addr.as_var().unwrap(); + + self.bind(r, Addr::DBRef(db_ref)); + } + None => { + self.fail = true; + return Ok(()); + } + } + } + Addr::DBRef(DBRef::NamedPred(..)) => self.fail = true, + Addr::DBRef(ref db_ref) => self.get_next_db_ref(&indices, db_ref), _ => { self.fail = true; } } - }, + } &SystemClauseType::LookupDBRef => { let a1 = self[temp_v!(1)].clone(); match self.store(self.deref(a1)) { - Addr::DBRef(db_ref) => - match db_ref { - DBRef::NamedPred(name, arity, spec) => { - let a2 = self[temp_v!(2)].clone(); - let a3 = self[temp_v!(3)].clone(); + Addr::DBRef(db_ref) => match db_ref { + DBRef::NamedPred(name, arity, spec) => { + let a2 = self[temp_v!(2)].clone(); + let a3 = self[temp_v!(3)].clone(); - let arity = Integer::from(arity); + let arity = Integer::from(arity); - self.unify(a2, Addr::Con(Constant::Atom(name, spec))); + self.unify(a2, Addr::Con(Constant::Atom(name, spec))); - if !self.fail { - self.unify(a3, Addr::Con(Constant::Integer(arity))); - } - }, - _ => self.fail = true - }, - _ => self.fail = true + if !self.fail { + self.unify(a3, Addr::Con(Constant::Integer(arity))); + } + } + _ => self.fail = true, + }, + _ => self.fail = true, } - }, + } &SystemClauseType::LookupOpDBRef => { let a1 = self[temp_v!(1)].clone(); match self.store(self.deref(a1)) { - Addr::DBRef(db_ref) => - match db_ref { - DBRef::Op(priority, spec, name, _, shared_op_desc) => { - let prec = self[temp_v!(2)].clone(); - let specifier = self[temp_v!(3)].clone(); - let op = self[temp_v!(4)].clone(); - - let spec = match spec { - FX => "fx", - FY => "fy", - XF => "xf", - YF => "yf", - XFX => "xfx", - XFY => "xfy", - YFX => "yfx", - _ => { - self.fail = true; - return Ok(()); - } - }; + Addr::DBRef(db_ref) => match db_ref { + DBRef::Op(priority, spec, name, _, shared_op_desc) => { + let prec = self[temp_v!(2)].clone(); + let specifier = self[temp_v!(3)].clone(); + let op = self[temp_v!(4)].clone(); + + let spec = match spec { + FX => "fx", + FY => "fy", + XF => "xf", + YF => "yf", + XFX => "xfx", + XFY => "xfy", + YFX => "yfx", + _ => { + self.fail = true; + return Ok(()); + } + }; - let a2 = Integer::from(priority); - let a3 = Addr::Con(Constant::Atom(clause_name!(spec), None)); - let a4 = Addr::Con(Constant::Atom(name, Some(shared_op_desc))); + let a2 = Integer::from(priority); + let a3 = Addr::Con(Constant::Atom(clause_name!(spec), None)); + let a4 = Addr::Con(Constant::Atom(name, Some(shared_op_desc))); - self.unify(Addr::Con(Constant::Integer(a2)), prec); + self.unify(Addr::Con(Constant::Integer(a2)), prec); - if !self.fail { - self.unify(a3, specifier); - } + if !self.fail { + self.unify(a3, specifier); + } - if !self.fail { - self.unify(a4, op); - } - }, - _ => self.fail = true - }, - _ => self.fail = true + if !self.fail { + self.unify(a4, op); + } + } + _ => self.fail = true, + }, + _ => self.fail = true, } - }, + } &SystemClauseType::OpDeclaration => { - let priority = self[temp_v!(1)].clone(); + let priority = self[temp_v!(1)].clone(); let specifier = self[temp_v!(2)].clone(); let op = self[temp_v!(3)].clone(); let priority = match self.store(self.deref(priority)) { Addr::Con(Constant::Integer(n)) => n.to_usize().unwrap(), - _ => unreachable!() + _ => unreachable!(), }; let specifier = match self.store(self.deref(specifier)) { Addr::Con(Constant::Atom(name, _)) => name, - _ => unreachable!() + _ => unreachable!(), }; let op = match self.store(self.deref(op)) { Addr::Con(Constant::Atom(name, _)) => name, - Addr::Con(Constant::Char(c)) => - clause_name!(c.to_string(), indices.atom_tbl), - _ => unreachable!() + Addr::Con(Constant::Char(c)) => clause_name!(c.to_string(), indices.atom_tbl), + _ => unreachable!(), }; let module = op.owning_module(); @@ -1120,7 +1176,7 @@ impl MachineState { }); match result { - Ok(()) => {}, + Ok(()) => {} Err(e) => { // 8.14.3.3 l) let e = MachineError::session_error(self.heap.h, e); @@ -1130,11 +1186,13 @@ impl MachineState { return Err(permission_error); } }; - }, - &SystemClauseType::TruncateIfNoLiftedHeapGrowthDiff => - self.truncate_if_no_lifted_heap_diff(|h| Addr::HeapCell(h)), - &SystemClauseType::TruncateIfNoLiftedHeapGrowth => - self.truncate_if_no_lifted_heap_diff(|_| Addr::Con(Constant::EmptyList)), + } + &SystemClauseType::TruncateIfNoLiftedHeapGrowthDiff => { + self.truncate_if_no_lifted_heap_diff(|h| Addr::HeapCell(h)) + } + &SystemClauseType::TruncateIfNoLiftedHeapGrowth => { + self.truncate_if_no_lifted_heap_diff(|_| Addr::Con(Constant::EmptyList)) + } &SystemClauseType::GetAttributedVariableList => { let attr_var = self.store(self.deref(self[temp_v!(1)].clone())); let attr_var_list = match attr_var { @@ -1148,7 +1206,7 @@ impl MachineState { self.bind(Ref::AttrVar(h), attr_var); h + 1 - }, + } _ => { self.fail = true; return Ok(()); @@ -1157,13 +1215,13 @@ impl MachineState { let list_addr = self[temp_v!(2)].clone(); self.unify(Addr::HeapCell(attr_var_list), list_addr); - }, + } &SystemClauseType::GetAttrVarQueueDelimiter => { - let addr = self[temp_v!(1)].clone(); + let addr = self[temp_v!(1)].clone(); let value = Addr::Con(Constant::Usize(self.attr_var_init.attr_var_queue.len())); self.unify(addr, value); - }, + } &SystemClauseType::GetAttrVarQueueBeyond => { let addr = self[temp_v!(1)].clone(); @@ -1175,15 +1233,15 @@ impl MachineState { let list_addr = self[temp_v!(2)].clone(); self.unify(var_list_addr, list_addr); - }, - _ => self.fail = true + } + _ => self.fail = true, } - }, + } &SystemClauseType::GetLiftedHeapFromOffsetDiff => { let lh_offset = self[temp_v!(1)].clone(); match self.store(self.deref(lh_offset)) { - Addr::Con(Constant::Usize(lh_offset)) => + Addr::Con(Constant::Usize(lh_offset)) => { if lh_offset >= self.lifted_heap.len() { let solutions = self[temp_v!(2)].clone(); let diff = self[temp_v!(3)].clone(); @@ -1193,12 +1251,12 @@ impl MachineState { } else { let h = self.heap.h; - for index in lh_offset .. self.lifted_heap.len() { + for index in lh_offset..self.lifted_heap.len() { match self.lifted_heap[index].clone() { - HeapCellValue::Addr(addr) => - self.heap.push(HeapCellValue::Addr(addr + h)), - value => - self.heap.push(value) + HeapCellValue::Addr(addr) => { + self.heap.push(HeapCellValue::Addr(addr + h)) + } + value => self.heap.push(value), } } @@ -1211,27 +1269,28 @@ impl MachineState { let solutions = self[temp_v!(2)].clone(); self.unify(Addr::HeapCell(h), solutions); - }, - _ => self.fail = true + } + } + _ => self.fail = true, } - }, + } &SystemClauseType::GetLiftedHeapFromOffset => { let lh_offset = self[temp_v!(1)].clone(); match self.store(self.deref(lh_offset)) { - Addr::Con(Constant::Usize(lh_offset)) => + Addr::Con(Constant::Usize(lh_offset)) => { if lh_offset >= self.lifted_heap.len() { let solutions = self[temp_v!(2)].clone(); self.unify(solutions, Addr::Con(Constant::EmptyList)); } else { let h = self.heap.h; - for index in lh_offset .. self.lifted_heap.len() { + for index in lh_offset..self.lifted_heap.len() { match self.lifted_heap[index].clone() { - HeapCellValue::Addr(addr) => - self.heap.push(HeapCellValue::Addr(addr + h)), - value => - self.heap.push(value) + HeapCellValue::Addr(addr) => { + self.heap.push(HeapCellValue::Addr(addr + h)) + } + value => self.heap.push(value), } } @@ -1239,27 +1298,25 @@ impl MachineState { let solutions = self[temp_v!(2)].clone(); self.unify(Addr::HeapCell(h), solutions); - }, - _ => self.fail = true + } + } + _ => self.fail = true, } - }, + } &SystemClauseType::GetDoubleQuotes => { let a1 = self[temp_v!(1)].clone(); match self.flags.double_quotes { - DoubleQuotes::Chars => - self.unify(a1, Addr::Con(atom!("chars"))), - DoubleQuotes::Atom => - self.unify(a1, Addr::Con(atom!("atom"))), - DoubleQuotes::Codes => - self.unify(a1, Addr::Con(atom!("codes"))) + DoubleQuotes::Chars => self.unify(a1, Addr::Con(atom!("chars"))), + DoubleQuotes::Atom => self.unify(a1, Addr::Con(atom!("atom"))), + DoubleQuotes::Codes => self.unify(a1, Addr::Con(atom!("codes"))), } - }, + } &SystemClauseType::GetSCCCleaner => { let dest = self[temp_v!(1)].clone(); match cut_policy.downcast_mut::().ok() { - Some(sgc_policy) => + Some(sgc_policy) => { if let Some((addr, b_cutoff, prev_b)) = sgc_policy.pop_cont_pt() { if self.b <= b_cutoff + 1 { self.block = prev_b; @@ -1271,14 +1328,14 @@ impl MachineState { } else { sgc_policy.push_cont_pt(addr, b_cutoff, prev_b); } - }, - None => panic!("expected SCCCutPolicy trait object.") + } + } + None => panic!("expected SCCCutPolicy trait object."), }; self.fail = true; - }, - &SystemClauseType::Halt => - std::process::exit(0), + } + &SystemClauseType::Halt => std::process::exit(0), &SystemClauseType::InstallSCCCleaner => { let addr = self[temp_v!(1)].clone(); let b = self.b; @@ -1289,17 +1346,19 @@ impl MachineState { *cut_policy = Box::new(SCCCutPolicy::new(r_c_w_h, r_c_wo_h)); } - match cut_policy.downcast_mut::().ok() - { + match cut_policy.downcast_mut::().ok() { Some(cut_policy) => { self.install_new_block(temp_v!(2)); cut_policy.push_cont_pt(addr, b, prev_block); - }, - None => panic!("install_cleaner: should have installed \\ - SCCCutPolicy.") + } + None => panic!( + "install_cleaner: should have installed \\ + SCCCutPolicy." + ), }; - }, - &SystemClauseType::InstallInferenceCounter => { // A1 = B, A2 = L + } + &SystemClauseType::InstallInferenceCounter => { + // A1 = B, A2 = L let a1 = self.store(self.deref(self[temp_v!(1)].clone())); let a2 = self.store(self.deref(self[temp_v!(2)].clone())); @@ -1308,8 +1367,7 @@ impl MachineState { } match (a1, a2.clone()) { - (Addr::Con(Constant::Usize(bp)), - Addr::Con(Constant::Integer(n))) => + (Addr::Con(Constant::Usize(bp)), Addr::Con(Constant::Integer(n))) => { match call_policy.downcast_mut::().ok() { Some(call_policy) => { let count = call_policy.add_limit(n, bp); @@ -1318,18 +1376,24 @@ impl MachineState { let a3 = self[temp_v!(3)].clone(); self.unify(a3, count); - }, - None => panic!("install_inference_counter: should have installed \\ - CWILCallPolicy.") - }, + } + None => panic!( + "install_inference_counter: should have installed \\ + CWILCallPolicy." + ), + } + } _ => { - let stub = MachineError::functor_stub(clause_name!("call_with_inference_limit"), 3); - let type_error = self.error_form(MachineError::type_error(ValidType::Integer, a2), - stub); + let stub = MachineError::functor_stub( + clause_name!("call_with_inference_limit"), + 3, + ); + let type_error = + self.error_form(MachineError::type_error(ValidType::Integer, a2), stub); self.throw_exception(type_error) } }; - }, + } &SystemClauseType::ModuleOf => { let module = self.store(self.deref(self[temp_v!(2)].clone())); @@ -1339,38 +1403,36 @@ impl MachineState { let target = self[temp_v!(1)].clone(); self.unify(target, module); - }, - Addr::Str(s) => - match self.heap[s].clone() { - HeapCellValue::NamedStr(_, name, ..) => { - let module = Addr::Con(Constant::Atom(name.owning_module(), None)); - let target = self[temp_v!(1)].clone(); + } + Addr::Str(s) => match self.heap[s].clone() { + HeapCellValue::NamedStr(_, name, ..) => { + let module = Addr::Con(Constant::Atom(name.owning_module(), None)); + let target = self[temp_v!(1)].clone(); - self.unify(target, module); - }, - _ => self.fail = true - }, - _ => self.fail = true + self.unify(target, module); + } + _ => self.fail = true, + }, + _ => self.fail = true, }; - }, + } &SystemClauseType::NoSuchPredicate => { let head = self[temp_v!(1)].clone(); self.fail = match self.store(self.deref(head)) { - Addr::Str(s) => - match self.heap[s].clone() { - HeapCellValue::NamedStr(arity, name, op_spec) => { - let module = name.owning_module(); - indices.predicate_exists(name, module, arity, op_spec) - }, - _ => unreachable!() - }, + Addr::Str(s) => match self.heap[s].clone() { + HeapCellValue::NamedStr(arity, name, op_spec) => { + let module = name.owning_module(); + indices.predicate_exists(name, module, arity, op_spec) + } + _ => unreachable!(), + }, Addr::Con(Constant::Atom(name, spec)) => { let module = name.owning_module(); let spec = fetch_atom_op_spec(name.clone(), spec, &indices.op_dir); indices.predicate_exists(name, module, 0, spec) - }, + } head => { let err = MachineError::type_error(ValidType::Callable, head); let stub = MachineError::functor_stub(clause_name!("clause"), 2); @@ -1378,49 +1440,50 @@ impl MachineState { return Err(self.error_form(err, stub)); } }; - }, + } &SystemClauseType::RedoAttrVarBindings => { let bindings = mem::replace(&mut self.attr_var_init.bindings, vec![]); for (h, addr) in bindings { self.heap[h] = HeapCellValue::Addr(addr); } - }, + } &SystemClauseType::ResetGlobalVarAtKey => { let key = self[temp_v!(1)].clone(); let key = match self.store(self.deref(key)) { Addr::Con(Constant::Atom(atom, _)) => atom, - _ => unreachable!() + _ => unreachable!(), }; indices.global_variables.remove(&key); - }, + } &SystemClauseType::RemoveCallPolicyCheck => { - let restore_default = - match call_policy.downcast_mut::().ok() { - Some(call_policy) => { - let a1 = self.store(self.deref(self[temp_v!(1)].clone())); + let restore_default = match call_policy.downcast_mut::().ok() { + Some(call_policy) => { + let a1 = self.store(self.deref(self[temp_v!(1)].clone())); - if let Addr::Con(Constant::Usize(bp)) = a1 { - if call_policy.is_empty() && bp == self.b { - Some(call_policy.into_inner()) - } else { - None - } + if let Addr::Con(Constant::Usize(bp)) = a1 { + if call_policy.is_empty() && bp == self.b { + Some(call_policy.into_inner()) } else { - panic!("remove_call_policy_check: expected Usize in A1."); + None } - }, - None => panic!("remove_call_policy_check: requires \\ - CWILCallPolicy.") - }; + } else { + panic!("remove_call_policy_check: expected Usize in A1."); + } + } + None => panic!( + "remove_call_policy_check: requires \\ + CWILCallPolicy." + ), + }; if let Some(new_policy) = restore_default { *call_policy = new_policy; } - }, - &SystemClauseType::RemoveInferenceCounter => + } + &SystemClauseType::RemoveInferenceCounter => { match call_policy.downcast_mut::().ok() { Some(call_policy) => { let a1 = self.store(self.deref(self[temp_v!(1)].clone())); @@ -1435,36 +1498,38 @@ impl MachineState { } else { panic!("remove_inference_counter: expected Usize in A1."); } - }, - None => panic!("remove_inference_counter: requires \\ - CWILCallPolicy.") - }, - &SystemClauseType::REPL(repl_code_ptr) => - return self.repl_redirect(repl_code_ptr), + } + None => panic!( + "remove_inference_counter: requires \\ + CWILCallPolicy." + ), + } + } + &SystemClauseType::REPL(repl_code_ptr) => return self.repl_redirect(repl_code_ptr), &SystemClauseType::ModuleRetractClause => { let p = self.cp; let trans_type = DynamicTransactionType::ModuleRetract; self.p = CodePtr::DynamicTransaction(trans_type, p); return Ok(()); - }, + } &SystemClauseType::RetractClause => { let p = self.cp; let trans_type = DynamicTransactionType::Retract; self.p = CodePtr::DynamicTransaction(trans_type, p); return Ok(()); - }, + } &SystemClauseType::ReturnFromAttributeGoals => { self.deallocate(); self.p = CodePtr::Local(LocalCodePtr::TopLevel(0, 0)); return Ok(()); - }, + } &SystemClauseType::ReturnFromVerifyAttr => { let e = self.e; let frame_len = self.and_stack[e].len(); - for i in 1 .. frame_len - 1 { + for i in 1..frame_len - 1 { self[RegType::Temp(i)] = self.and_stack[e][i].clone(); } @@ -1480,7 +1545,7 @@ impl MachineState { self.deallocate(); return Ok(()); - }, + } &SystemClauseType::RestoreCutPolicy => { let restore_default = if let Ok(cut_policy) = cut_policy.downcast_ref::() { @@ -1492,38 +1557,42 @@ impl MachineState { if restore_default { *cut_policy = Box::new(DefaultCutPolicy {}); } + } + &SystemClauseType::SetCutPoint(r) => { + if cut_policy.cut(self, r) { + return Ok(()); + } + } + &SystemClauseType::SetCutPointByDefault(r) => deref_cut(self, r), + &SystemClauseType::SetDoubleQuotes => match self[temp_v!(1)].clone() { + Addr::Con(Constant::Atom(ref atom, _)) if atom.as_str() == "chars" => { + self.flags.double_quotes = DoubleQuotes::Chars + } + Addr::Con(Constant::Atom(ref atom, _)) if atom.as_str() == "atom" => { + self.flags.double_quotes = DoubleQuotes::Atom + } + Addr::Con(Constant::Atom(ref atom, _)) if atom.as_str() == "codes" => { + self.flags.double_quotes = DoubleQuotes::Codes + } + _ => self.fail = true, }, - &SystemClauseType::SetCutPoint(r) => if cut_policy.cut(self, r) { - return Ok(()); - }, - &SystemClauseType::SetCutPointByDefault(r) => - deref_cut(self, r), - &SystemClauseType::SetDoubleQuotes => - match self[temp_v!(1)].clone() { - Addr::Con(Constant::Atom(ref atom, _)) if atom.as_str() == "chars" => - self.flags.double_quotes = DoubleQuotes::Chars, - Addr::Con(Constant::Atom(ref atom, _)) if atom.as_str() == "atom" => - self.flags.double_quotes = DoubleQuotes::Atom, - Addr::Con(Constant::Atom(ref atom, _)) if atom.as_str() == "codes" => - self.flags.double_quotes = DoubleQuotes::Codes, - _ => self.fail = true - }, &SystemClauseType::InferenceLevel => { let a1 = self[temp_v!(1)].clone(); let a2 = self.store(self.deref(self[temp_v!(2)].clone())); match a2 { - Addr::Con(Constant::Usize(bp)) => + Addr::Con(Constant::Usize(bp)) => { if self.b <= bp + 1 { let a2 = Addr::Con(atom!("!")); self.unify(a1, a2); } else { let a2 = Addr::Con(atom!("true")); self.unify(a1, a2); - }, - _ => self.fail = true + } + } + _ => self.fail = true, }; - }, + } &SystemClauseType::CleanUpBlock => { let nb = self.store(self.deref(self[temp_v!(1)].clone())); @@ -1535,10 +1604,10 @@ impl MachineState { self.b = self.or_stack[nb - 1].b; self.or_stack.truncate(self.b); } - }, - _ => self.fail = true + } + _ => self.fail = true, }; - }, + } &SystemClauseType::EraseBall => self.ball.reset(), &SystemClauseType::Fail => self.fail = true, &SystemClauseType::GetBall => { @@ -1557,55 +1626,60 @@ impl MachineState { match addr.as_var() { Some(r) => self.bind(r, ball), - _ => self.fail = true + _ => self.fail = true, }; - }, + } &SystemClauseType::GetCurrentBlock => { let c = Constant::Usize(self.block); let addr = self[temp_v!(1)].clone(); self.write_constant_to_var(addr, c); - }, + } &SystemClauseType::GetBValue => { let a1 = self[temp_v!(1)].clone(); let a2 = Addr::Con(Constant::Usize(self.b)); self.unify(a1, a2); - }, + } &SystemClauseType::GetClause => { let head = self[temp_v!(1)].clone(); let subsection = match self.store(self.deref(head)) { - Addr::Str(s) => - match self.heap[s].clone() { - HeapCellValue::NamedStr(arity, name, ..) => - indices.get_clause_subsection(name.owning_module(), name, arity), - _ => unreachable!() - }, - Addr::Con(Constant::Atom(name, _)) => - indices.get_clause_subsection(name.owning_module(), name, 0), - _ => unreachable!() + Addr::Str(s) => match self.heap[s].clone() { + HeapCellValue::NamedStr(arity, name, ..) => { + indices.get_clause_subsection(name.owning_module(), name, arity) + } + _ => unreachable!(), + }, + Addr::Con(Constant::Atom(name, _)) => { + indices.get_clause_subsection(name.owning_module(), name, 0) + } + _ => unreachable!(), }; match subsection { Some(dynamic_predicate_info) => { self.execute_at_index(2, dynamic_predicate_info.clauses_subsection_p); return Ok(()); - }, - _ => unreachable!() + } + _ => unreachable!(), } - }, + } &SystemClauseType::GetCutPoint => { let a1 = self[temp_v!(1)].clone(); let a2 = Addr::Con(Constant::Usize(self.b0)); self.unify(a1, a2); - }, + } &SystemClauseType::InstallNewBlock => { self.install_new_block(temp_v!(1)); - }, + } &SystemClauseType::ReadTerm => { - match self.read(current_input_stream, indices.atom_tbl.clone(), &indices.op_dir) { + match self.read( + current_input_stream, + indices.atom_tbl.clone(), + &indices.op_dir, + ) { Ok(term_write_result) => { let a1 = self[temp_v!(1)].clone(); self.unify(Addr::HeapCell(term_write_result.heap_loc), a1); @@ -1623,7 +1697,8 @@ impl MachineState { let h = self.heap.h; let spec = fetch_atom_op_spec(clause_name!("="), None, &indices.op_dir); - self.heap.push(HeapCellValue::NamedStr(2, clause_name!("="), spec)); + self.heap + .push(HeapCellValue::NamedStr(2, clause_name!("="), spec)); self.heap.push(HeapCellValue::Addr(Addr::Con(var_atom))); self.heap.push(HeapCellValue::Addr(binding)); @@ -1631,10 +1706,11 @@ impl MachineState { } let a2 = self[temp_v!(2)].clone(); - let list_offset = Addr::HeapCell(self.heap.to_list(list_of_var_eqs.into_iter())); + let list_offset = + Addr::HeapCell(self.heap.to_list(list_of_var_eqs.into_iter())); self.unify(list_offset, a2); - }, + } Err(err) => { if let ParserError::UnexpectedEOF = err { std::process::exit(0); @@ -1650,38 +1726,41 @@ impl MachineState { return Err(self.error_form(syntax_error, stub)); } } - }, + } &SystemClauseType::ResetBlock => { let addr = self.deref(self[temp_v!(1)].clone()); self.reset_block(addr); - }, + } &SystemClauseType::SetBall => self.set_ball(), - &SystemClauseType::SkipMaxList => if let Err(err) = self.skip_max_list() { - return Err(err); - }, + &SystemClauseType::SkipMaxList => { + if let Err(err) = self.skip_max_list() { + return Err(err); + } + } &SystemClauseType::StoreGlobalVar => { let key = self[temp_v!(1)].clone(); let key = match self.store(self.deref(key)) { Addr::Con(Constant::Atom(atom, _)) => atom, - _ => unreachable!() + _ => unreachable!(), }; let value = self[temp_v!(2)].clone(); indices.global_variables.insert(key, value); } - &SystemClauseType::Succeed => {}, + &SystemClauseType::Succeed => {} &SystemClauseType::TermVariables => { let a1 = self[temp_v!(1)].clone(); let mut seen_vars = IndexSet::new(); for item in self.acyclic_pre_order_iter(a1) { match item { - HeapCellValue::Addr(addr) => + HeapCellValue::Addr(addr) => { if addr.is_ref() { seen_vars.insert(addr); - }, + } + } _ => {} } } @@ -1690,40 +1769,40 @@ impl MachineState { let a2 = self[temp_v!(2)].clone(); self.unify(a2, outcome); - }, - &SystemClauseType::TruncateLiftedHeapTo => + } + &SystemClauseType::TruncateLiftedHeapTo => { match self.store(self.deref(self[temp_v!(1)].clone())) { - Addr::Con(Constant::Usize(lh_offset)) => - self.lifted_heap.truncate(lh_offset), - _ => self.fail = true - }, + Addr::Con(Constant::Usize(lh_offset)) => self.lifted_heap.truncate(lh_offset), + _ => self.fail = true, + } + } &SystemClauseType::UnifyWithOccursCheck => { let a1 = self[temp_v!(1)].clone(); let a2 = self[temp_v!(2)].clone(); self.unify_with_occurs_check(a1, a2); - }, - &SystemClauseType::UnwindStack => - self.unwind_stack(), - &SystemClauseType::Variant => - self.fail = self.structural_eq_test(), + } + &SystemClauseType::UnwindStack => self.unwind_stack(), + &SystemClauseType::Variant => self.fail = self.structural_eq_test(), &SystemClauseType::WAMInstructions => { - let name = self[temp_v!(1)].clone(); + let name = self[temp_v!(1)].clone(); let arity = self[temp_v!(2)].clone(); let name = match self.store(self.deref(name)) { Addr::Con(Constant::Atom(name, _)) => name, - _ => unreachable!() + _ => unreachable!(), }; let arity = match self.store(self.deref(arity)) { Addr::Con(Constant::Integer(n)) => n, - _ => unreachable!() + _ => unreachable!(), }; - let first_idx = match indices.code_dir.get(&(name.clone(), arity.to_usize().unwrap())) + let first_idx = match indices + .code_dir + .get(&(name.clone(), arity.to_usize().unwrap())) { - Some(ref idx) => + Some(ref idx) => { if let Some(idx) = idx.local() { idx } else { @@ -1731,18 +1810,25 @@ impl MachineState { let stub = MachineError::functor_stub(name.clone(), arity); let h = self.heap.h; - let err = MachineError::existence_error(h, ExistenceError::Procedure(name, arity)); + let err = MachineError::existence_error( + h, + ExistenceError::Procedure(name, arity), + ); let err = self.error_form(err, stub); self.throw_exception(err); return Ok(()); - }, + } + } None => { let arity = arity.to_usize().unwrap(); let stub = MachineError::functor_stub(name.clone(), arity); let h = self.heap.h; - let err = MachineError::existence_error(h, ExistenceError::Procedure(name, arity)); + let err = MachineError::existence_error( + h, + ExistenceError::Procedure(name, arity), + ); let err = self.error_form(err, stub); self.throw_exception(err); @@ -1751,11 +1837,11 @@ impl MachineState { }; let functors = self.create_instruction_functors(&code_repo.code, first_idx); - let listing = Addr::HeapCell(self.heap.to_list(functors.into_iter())); + let listing = Addr::HeapCell(self.heap.to_list(functors.into_iter())); let listing_var = self[temp_v!(3)].clone(); self.unify(listing, listing_var); - }, + } &SystemClauseType::WriteTerm => { let addr = self[temp_v!(1)].clone(); @@ -1785,40 +1871,39 @@ impl MachineState { for addr in addrs { match addr { - Addr::Str(s) => - match &self.heap[s] { - &HeapCellValue::NamedStr(2, ref name, _) - if name.as_str() == "=" => { - let atom = self.heap[s+1].as_addr(s+1); - let var = self.heap[s+2].as_addr(s+2); - - let atom = match self.store(self.deref(atom)) { - Addr::Con(Constant::Atom(atom, _)) => atom.to_string(), - Addr::Con(Constant::Char(c)) => c.to_string(), - _ => unreachable!() - }; - - let var = self.store(self.deref(var)); - - if var_names.contains_key(&var) { - continue; - } - - var_names.insert(var, atom); - }, - _ => unreachable!() - }, - _ => unreachable!() + Addr::Str(s) => match &self.heap[s] { + &HeapCellValue::NamedStr(2, ref name, _) + if name.as_str() == "=" => + { + let atom = self.heap[s + 1].as_addr(s + 1); + let var = self.heap[s + 2].as_addr(s + 2); + + let atom = match self.store(self.deref(atom)) { + Addr::Con(Constant::Atom(atom, _)) => atom.to_string(), + Addr::Con(Constant::Char(c)) => c.to_string(), + _ => unreachable!(), + }; + + let var = self.store(self.deref(var)); + + if var_names.contains_key(&var) { + continue; + } + + var_names.insert(var, atom); + } + _ => unreachable!(), + }, + _ => unreachable!(), } } printer.var_names = var_names; - }, - Err(err) => - return Err(err) + } + Err(err) => return Err(err), } - let output = printer.print(addr); + let output = printer.print(addr); print!("{}", output.result()); stdout().flush().unwrap(); } diff --git a/src/prolog/machine/term_expansion.rs b/src/prolog/machine/term_expansion.rs index ed6707bf..c90d239c 100644 --- a/src/prolog/machine/term_expansion.rs +++ b/src/prolog/machine/term_expansion.rs @@ -1,10 +1,10 @@ use prolog_parser::ast::*; use prolog_parser::parser::*; -use prolog::machine::*; use prolog::machine::machine_indices::HeapCellValue; -use prolog::rug::Integer; +use prolog::machine::*; use prolog::rug::ops::Pow; +use prolog::rug::Integer; use std::cell::Cell; use std::collections::VecDeque; @@ -12,8 +12,7 @@ use std::io::Read; use std::iter::Rev; use std::vec::IntoIter; -fn unfold_by_str_once(term: &mut Term, s: &str) -> Option<(Term, Term)> -{ +fn unfold_by_str_once(term: &mut Term, s: &str) -> Option<(Term, Term)> { if let &mut Term::Clause(_, ref name, ref mut subterms, _) = term { if name.as_str() == s && subterms.len() == 2 { let snd = *subterms.pop().unwrap(); @@ -26,8 +25,7 @@ fn unfold_by_str_once(term: &mut Term, s: &str) -> Option<(Term, Term)> None } -pub fn unfold_by_str(mut term: Term, s: &str) -> Vec -{ +pub fn unfold_by_str(mut term: Term, s: &str) -> Vec { let mut terms = vec![]; while let Some((fst, snd)) = unfold_by_str_once(&mut term, s) { @@ -40,22 +38,24 @@ pub fn unfold_by_str(mut term: Term, s: &str) -> Vec } pub fn fold_by_str(terms: I, mut term: Term, sym: ClauseName) -> Term - where I: DoubleEndedIterator +where + I: DoubleEndedIterator, { for prec in terms.rev() { - term = Term::Clause(Cell::default(), sym.clone(), - vec![Box::new(prec), Box::new(term)], - None); + term = Term::Clause( + Cell::default(), + sym.clone(), + vec![Box::new(prec), Box::new(term)], + None, + ); } term } -fn extract_from_list(head: Box, tail: Box) - -> Result>, ParserError> -{ +fn extract_from_list(head: Box, tail: Box) -> Result>, ParserError> { let mut terms = vec![*head]; - let mut tail = *tail; + let mut tail = *tail; while let Term::Cons(_, head, next_tail) = tail { terms.push(*head); @@ -81,19 +81,19 @@ pub struct TermStream<'a, R: Read> { pub struct ExpansionAdditionResult { term_expansion_additions: (Predicate, VecDeque), - goal_expansion_additions: (Predicate, VecDeque) + goal_expansion_additions: (Predicate, VecDeque), } impl ExpansionAdditionResult { pub fn take_term_expansions(&mut self) -> (Predicate, VecDeque) { - let tes = mem::replace(&mut self.term_expansion_additions.0, Predicate::new()); + let tes = mem::replace(&mut self.term_expansion_additions.0, Predicate::new()); let teqs = mem::replace(&mut self.term_expansion_additions.1, VecDeque::from(vec![])); (tes, teqs) } pub fn take_goal_expansions(&mut self) -> (Predicate, VecDeque) { - let ges = mem::replace(&mut self.goal_expansion_additions.0, Predicate::new()); + let ges = mem::replace(&mut self.goal_expansion_additions.0, Predicate::new()); let geqs = mem::replace(&mut self.goal_expansion_additions.1, VecDeque::from(vec![])); (ges, geqs) @@ -109,17 +109,24 @@ impl<'a, R: Read> Drop for TermStream<'a, R> { } impl<'a, R: Read> TermStream<'a, R> { - pub fn new(src: &'a mut ParsingStream, atom_tbl: TabledData, flags: MachineFlags, wam: &'a mut Machine) - -> Self - { + pub fn new( + src: &'a mut ParsingStream, + atom_tbl: TabledData, + flags: MachineFlags, + wam: &'a mut Machine, + ) -> Self { TermStream { stack: Vec::new(), - term_expansion_lens: wam.code_repo.term_dir_entry_len((clause_name!("term_expansion"), 2)), - goal_expansion_lens: wam.code_repo.term_dir_entry_len((clause_name!("goal_expansion"), 2)), + term_expansion_lens: wam + .code_repo + .term_dir_entry_len((clause_name!("term_expansion"), 2)), + goal_expansion_lens: wam + .code_repo + .term_dir_entry_len((clause_name!("goal_expansion"), 2)), wam, parser: Parser::new(src, atom_tbl, flags), in_module: false, - flags + flags, } } @@ -134,11 +141,11 @@ impl<'a, R: Read> TermStream<'a, R> { CompileTimeHook::UserTermExpansion => { self.term_expansion_lens.0 += len; self.term_expansion_lens.1 += queue_len; - }, + } CompileTimeHook::UserGoalExpansion => { self.goal_expansion_lens.0 += len; self.goal_expansion_lens.1 += queue_len; - }, + } _ => {} } } @@ -169,27 +176,34 @@ impl<'a, R: Read> TermStream<'a, R> { Ok(self.stack.is_empty() && self.parser.eof()?) } - pub fn rollback_expansion_code(&mut self) -> Result - { + pub fn rollback_expansion_code(&mut self) -> Result { let te_len = self.term_expansion_lens.0; let te_queue_len = self.term_expansion_lens.1; let ge_len = self.goal_expansion_lens.0; let ge_queue_len = self.goal_expansion_lens.1; - let term_expansion_additions = - self.wam.code_repo.truncate_terms((clause_name!("term_expansion"), 2), - te_len, te_queue_len); - let goal_expansion_additions = - self.wam.code_repo.truncate_terms((clause_name!("goal_expansion"), 2), - ge_len, ge_queue_len); - - self.wam.code_repo.compile_hook(CompileTimeHook::TermExpansion, self.flags)?; - self.wam.code_repo.compile_hook(CompileTimeHook::GoalExpansion, self.flags)?; + let term_expansion_additions = self.wam.code_repo.truncate_terms( + (clause_name!("term_expansion"), 2), + te_len, + te_queue_len, + ); + let goal_expansion_additions = self.wam.code_repo.truncate_terms( + (clause_name!("goal_expansion"), 2), + ge_len, + ge_queue_len, + ); + + self.wam + .code_repo + .compile_hook(CompileTimeHook::TermExpansion, self.flags)?; + self.wam + .code_repo + .compile_hook(CompileTimeHook::GoalExpansion, self.flags)?; Ok(ExpansionAdditionResult { term_expansion_additions, - goal_expansion_additions + goal_expansion_additions, }) } @@ -198,34 +212,37 @@ impl<'a, R: Read> TermStream<'a, R> { Term::Cons(_, head, tail) => { let iter = extract_from_list(head, tail)?; Ok(self.stack.extend(iter)) - }, - Term::Clause(..) | Term::Constant(_, Constant::Atom(..)) => - Ok(self.stack.push(term)), - _ => - Err(ParserError::ExpectedTopLevelTerm) + } + Term::Clause(..) | Term::Constant(_, Constant::Atom(..)) => Ok(self.stack.push(term)), + _ => Err(ParserError::ExpectedTopLevelTerm), } } - fn parse_expansion_output(&self, term_string: &str, op_dir: &OpDir) -> Result - { + fn parse_expansion_output( + &self, + term_string: &str, + op_dir: &OpDir, + ) -> Result { let mut stream = parsing_stream(term_string.trim().as_bytes()); let mut parser = Parser::new(&mut stream, self.parser.get_atom_tbl(), self.flags); - parser.read_term(composite_op!(self.in_module, &self.wam.indices.op_dir, op_dir)) + parser.read_term(composite_op!( + self.in_module, + &self.wam.indices.op_dir, + op_dir + )) } - pub fn read_term(&mut self, op_dir: &OpDir) -> Result - { + pub fn read_term(&mut self, op_dir: &OpDir) -> Result { let mut machine_st = MachineState::new(); loop { while let Some(term) = self.stack.pop() { - match machine_st.try_expand_term(self.wam, &term, CompileTimeHook::TermExpansion) - { + match machine_st.try_expand_term(self.wam, &term, CompileTimeHook::TermExpansion) { Some(term_string) => { let term = self.parse_expansion_output(term_string.as_str(), op_dir)?; self.enqueue_term(term)? - }, + } None => { let term = self.run_goal_expanders(&mut machine_st, op_dir, term)?; return Ok(term); @@ -234,16 +251,21 @@ impl<'a, R: Read> TermStream<'a, R> { } self.parser.reset(); - let term = self.parser.read_term(composite_op!(self.in_module, &self.wam.indices.op_dir, - op_dir))?; + let term = self.parser.read_term(composite_op!( + self.in_module, + &self.wam.indices.op_dir, + op_dir + ))?; self.stack.push(term); } } - pub(crate) - fn run_goal_expanders(&mut self, machine_st: &mut MachineState, op_dir: &OpDir, term: Term) - -> Result - { + pub(crate) fn run_goal_expanders( + &mut self, + machine_st: &mut MachineState, + op_dir: &OpDir, + term: Term, + ) -> Result { match term { Term::Clause(cell, name, mut terms, arity) => { let mut new_terms = { @@ -251,45 +273,50 @@ impl<'a, R: Read> TermStream<'a, R> { (":-", 2) => { let comma_term = *terms.pop().unwrap(); unfold_by_str(comma_term, ",") - }, + } ("?-", 1) => unfold_by_str(*terms.pop().unwrap(), ","), - _ => return Ok(Term::Clause(cell, name, terms, arity)) + _ => return Ok(Term::Clause(cell, name, terms, arity)), }; self.expand_goals(machine_st, op_dir, VecDeque::from(old_terms))? }; let initial_term = new_terms.pop().unwrap(); - terms.push(Box::new(fold_by_str(new_terms.into_iter(), initial_term, - clause_name!(",")))); + terms.push(Box::new(fold_by_str( + new_terms.into_iter(), + initial_term, + clause_name!(","), + ))); Ok(Term::Clause(cell, name, terms, arity)) - }, - _ => - Ok(term) + } + _ => Ok(term), } } - fn expand_goals(&mut self, machine_st: &mut MachineState, op_dir: &OpDir, mut terms: VecDeque) - -> Result, ParserError> - { + fn expand_goals( + &mut self, + machine_st: &mut MachineState, + op_dir: &OpDir, + mut terms: VecDeque, + ) -> Result, ParserError> { let mut results = vec![]; while let Some(term) = terms.pop_front() { - match machine_st.try_expand_term(self.wam, &term, CompileTimeHook::GoalExpansion) - { + match machine_st.try_expand_term(self.wam, &term, CompileTimeHook::GoalExpansion) { Some(term_string) => { println!("trying to goal expand {}", term_string); let term = self.parse_expansion_output(term_string.as_str(), op_dir)?; match term { - Term::Cons(_, head, tail) => + Term::Cons(_, head, tail) => { for term in extract_from_list(head, tail)? { terms.push_front(term); - }, - term => terms.push_front(term) + } + } + term => terms.push_front(term), }; - }, - None => results.push(term) + } + None => results.push(term), } } @@ -298,9 +325,7 @@ impl<'a, R: Read> TermStream<'a, R> { } impl MachineState { - pub(super) - fn print_with_locs(&self, addr: Addr, op_dir: &OpDir) -> PrinterOutputter - { + pub(super) fn print_with_locs(&self, addr: Addr, op_dir: &OpDir) -> PrinterOutputter { let output = PrinterOutputter::new(); let mut printer = HCPrinter::from_heap_locs(&self, op_dir, output); let mut max_var_length = 0; @@ -327,9 +352,12 @@ impl MachineState { output } - fn try_expand_term(&mut self, wam: &mut Machine, term: &Term, hook: CompileTimeHook) - -> Option - { + fn try_expand_term( + &mut self, + wam: &mut Machine, + term: &Term, + hook: CompileTimeHook, + ) -> Option { let term_write_result = write_term_to_heap(term, self); let h = self.heap.h; @@ -340,7 +368,12 @@ impl MachineState { let code = vec![call_clause!(ClauseType::Hook(hook), 2, 0, true)]; wam.code_repo.cached_query = code; - self.query_stepper(&mut wam.indices, &mut wam.policies, &mut wam.code_repo, &mut readline::input_stream()); + self.query_stepper( + &mut wam.indices, + &mut wam.policies, + &mut wam.code_repo, + &mut readline::input_stream(), + ); if self.fail { self.reset(); diff --git a/src/prolog/machine/toplevel.rs b/src/prolog/machine/toplevel.rs index 7d582eee..a330ad9d 100644 --- a/src/prolog/machine/toplevel.rs +++ b/src/prolog/machine/toplevel.rs @@ -3,50 +3,56 @@ use prolog_parser::tabled_rc::*; use prolog::forms::*; use prolog::iterators::*; -use prolog::machine::*; use prolog::machine::machine_errors::*; use prolog::machine::machine_indices::*; use prolog::machine::machine_state::MachineState; use prolog::machine::term_expansion::*; +use prolog::machine::*; use indexmap::{IndexMap, IndexSet}; use std::borrow::BorrowMut; -use std::collections::VecDeque; use std::cell::Cell; +use std::collections::VecDeque; use std::io::Read; use std::mem; use std::rc::Rc; struct CompositeIndices<'a, 'b> { local: &'a mut IndexStore, - static_code_dir: Option<&'b CodeDir> + static_code_dir: Option<&'b CodeDir>, } macro_rules! composite_indices { - ($in_module: expr, $local: expr, $static_code_dir: expr) => ( - CompositeIndices { local: $local, - static_code_dir: if $in_module { - None - } else { - Some($static_code_dir) - }} - ); - ($local: expr) => ( - CompositeIndices { local: $local, static_code_dir: None } - ) + ($in_module: expr, $local: expr, $static_code_dir: expr) => { + CompositeIndices { + local: $local, + static_code_dir: if $in_module { + None + } else { + Some($static_code_dir) + }, + } + }; + ($local: expr) => { + CompositeIndices { + local: $local, + static_code_dir: None, + } + }; } -impl<'a, 'b> CompositeIndices<'a, 'b> -{ +impl<'a, 'b> CompositeIndices<'a, 'b> { fn get_code_index(&mut self, name: ClauseName, arity: usize) -> CodeIndex { - let idx_opt = self.local.code_dir.get(&(name.clone(), arity)) - .or_else(|| { - match &self.static_code_dir { - &Some(ref code_dir) => code_dir.get(&(name.clone(), arity)), - _ => None - } - }).cloned(); + let idx_opt = self + .local + .code_dir + .get(&(name.clone(), arity)) + .or_else(|| match &self.static_code_dir { + &Some(ref code_dir) => code_dir.get(&(name.clone(), arity)), + _ => None, + }) + .cloned(); if let Some(idx) = idx_opt { self.local.code_dir.insert((name, arity), idx.clone()); @@ -58,24 +64,31 @@ impl<'a, 'b> CompositeIndices<'a, 'b> } } - fn get_clause_type(&mut self, name: ClauseName, arity: usize, spec: Option) -> ClauseType - { + fn get_clause_type( + &mut self, + name: ClauseName, + arity: usize, + spec: Option, + ) -> ClauseType { match ClauseType::from(name, arity, spec) { ClauseType::Named(name, arity, _) => { let idx = self.get_code_index(name.clone(), arity); ClauseType::Named(name, arity, idx.clone()) - }, + } ClauseType::Op(name, spec, _) => { let idx = self.get_code_index(name.clone(), arity); ClauseType::Op(name, spec, idx.clone()) - }, - ct => ct + } + ct => ct, } } } -fn as_compile_time_hook(name: &str, arity: usize, terms: &Vec>) -> Option -{ +fn as_compile_time_hook( + name: &str, + arity: usize, + terms: &Vec>, +) -> Option { match (name, arity) { ("term_expansion", 2) => Some(CompileTimeHook::TermExpansion), ("goal_expansion", 2) => Some(CompileTimeHook::GoalExpansion), @@ -84,19 +97,21 @@ fn as_compile_time_hook(name: &str, arity: usize, terms: &Vec>) -> Opt if name.as_str() == "user" { if let &Term::Clause(_, ref name, ref terms, _) = &terms[1].as_ref() { return match name.as_str() { - "term_expansion" if terms.len() == 2 => - Some(CompileTimeHook::UserTermExpansion), - "goal_expansion" if terms.len() == 2 => - Some(CompileTimeHook::UserGoalExpansion), - _ => None - } + "term_expansion" if terms.len() == 2 => { + Some(CompileTimeHook::UserTermExpansion) + } + "goal_expansion" if terms.len() == 2 => { + Some(CompileTimeHook::UserGoalExpansion) + } + _ => None, + }; } } } None - }, - _ => None + } + _ => None, } } @@ -115,69 +130,73 @@ fn is_compile_time_hook(name: &ClauseName, terms: &Vec>) -> Option); -pub fn to_op_decl(prec: usize, spec: &str, name: ClauseName) -> Result -{ +pub fn to_op_decl(prec: usize, spec: &str, name: ClauseName) -> Result { match spec { "xfx" => Ok(OpDecl(prec, XFX, name)), "xfy" => Ok(OpDecl(prec, XFY, name)), "yfx" => Ok(OpDecl(prec, YFX, name)), - "fx" => Ok(OpDecl(prec, FX, name)), - "fy" => Ok(OpDecl(prec, FY, name)), - "xf" => Ok(OpDecl(prec, XF, name)), - "yf" => Ok(OpDecl(prec, YF, name)), - _ => Err(ParserError::InconsistentEntry) + "fx" => Ok(OpDecl(prec, FX, name)), + "fy" => Ok(OpDecl(prec, FY, name)), + "xf" => Ok(OpDecl(prec, XF, name)), + "yf" => Ok(OpDecl(prec, YF, name)), + _ => Err(ParserError::InconsistentEntry), } } -fn setup_op_decl(mut terms: Vec>) -> Result -{ +fn setup_op_decl(mut terms: Vec>) -> Result { let name = match *terms.pop().unwrap() { Term::Constant(_, Constant::Atom(name, _)) => name, - _ => return Err(ParserError::InconsistentEntry) + _ => return Err(ParserError::InconsistentEntry), }; let spec = match *terms.pop().unwrap() { Term::Constant(_, Constant::Atom(name, _)) => name, - _ => return Err(ParserError::InconsistentEntry) + _ => return Err(ParserError::InconsistentEntry), }; let prec = match *terms.pop().unwrap() { - Term::Constant(_, Constant::Integer(bi)) => - match bi.to_usize() { - Some(n) if n <= 1200 => n, - _ => return Err(ParserError::InconsistentEntry) - }, - _ => return Err(ParserError::InconsistentEntry) + Term::Constant(_, Constant::Integer(bi)) => match bi.to_usize() { + Some(n) if n <= 1200 => n, + _ => return Err(ParserError::InconsistentEntry), + }, + _ => return Err(ParserError::InconsistentEntry), }; to_op_decl(prec, spec.as_str(), name) } -fn setup_predicate_indicator(mut term: Term) -> Result -{ +fn setup_predicate_indicator(mut term: Term) -> Result { match term { Term::Clause(_, ref name, ref mut terms, Some(_)) - if name.as_str() == "/" && terms.len() == 2 => { - let arity = *terms.pop().unwrap(); - let name = *terms.pop().unwrap(); - - let arity = arity.to_constant().and_then(|c| c.to_integer()) - .and_then(|n| n.to_usize()) - .ok_or(ParserError::InvalidModuleExport)?; - - let name = name.to_constant().and_then(|c| c.to_atom()) - .ok_or(ParserError::InvalidModuleExport)?; - - Ok((name, arity)) - }, - _ => Err(ParserError::InvalidModuleExport) + if name.as_str() == "/" && terms.len() == 2 => + { + let arity = *terms.pop().unwrap(); + let name = *terms.pop().unwrap(); + + let arity = arity + .to_constant() + .and_then(|c| c.to_integer()) + .and_then(|n| n.to_usize()) + .ok_or(ParserError::InvalidModuleExport)?; + + let name = name + .to_constant() + .and_then(|c| c.to_atom()) + .ok_or(ParserError::InvalidModuleExport)?; + + Ok((name, arity)) + } + _ => Err(ParserError::InvalidModuleExport), } } -fn setup_module_decl(mut terms: Vec>) -> Result -{ +fn setup_module_decl(mut terms: Vec>) -> Result { let mut export_list = *terms.pop().unwrap(); - let name = terms.pop().unwrap().to_constant().and_then(|c| c.to_atom()) + let name = terms + .pop() + .unwrap() + .to_constant() + .and_then(|c| c.to_atom()) .ok_or(ParserError::InvalidModuleDecl)?; let mut exports = Vec::new(); @@ -194,38 +213,42 @@ fn setup_module_decl(mut terms: Vec>) -> Result>) -> Result -{ +fn setup_use_module_decl(mut terms: Vec>) -> Result { match *terms.pop().unwrap() { Term::Clause(_, ref name, ref mut terms, None) - if name.as_str() == "library" && terms.len() == 1 => { - terms.pop().unwrap().to_constant() - .and_then(|c| c.to_atom()) - .map(|c| ModuleSource::Library(c)) - .ok_or(ParserError::InvalidUseModuleDecl) - }, - Term::Constant(_, Constant::Atom(ref name, _)) => - Ok(ModuleSource::File(name.clone())), - _ => Err(ParserError::InvalidUseModuleDecl) + if name.as_str() == "library" && terms.len() == 1 => + { + terms + .pop() + .unwrap() + .to_constant() + .and_then(|c| c.to_atom()) + .map(|c| ModuleSource::Library(c)) + .ok_or(ParserError::InvalidUseModuleDecl) + } + Term::Constant(_, Constant::Atom(ref name, _)) => Ok(ModuleSource::File(name.clone())), + _ => Err(ParserError::InvalidUseModuleDecl), } } type UseModuleExport = (ModuleSource, Vec); -fn setup_qualified_import(mut terms: Vec>) -> Result -{ +fn setup_qualified_import(mut terms: Vec>) -> Result { let mut export_list = *terms.pop().unwrap(); let module_src = match *terms.pop().unwrap() { Term::Clause(_, ref name, ref mut terms, None) - if name.as_str() == "library" && terms.len() == 1 => { - terms.pop().unwrap().to_constant() - .and_then(|c| c.to_atom()) - .map(|c| ModuleSource::Library(c)) - .ok_or(ParserError::InvalidUseModuleDecl) - }, - Term::Constant(_, Constant::Atom(ref name, _)) => - Ok(ModuleSource::File(name.clone())), - _ => Err(ParserError::InvalidUseModuleDecl) + if name.as_str() == "library" && terms.len() == 1 => + { + terms + .pop() + .unwrap() + .to_constant() + .and_then(|c| c.to_atom()) + .map(|c| ModuleSource::Library(c)) + .ok_or(ParserError::InvalidUseModuleDecl) + } + Term::Constant(_, Constant::Atom(ref name, _)) => Ok(ModuleSource::File(name.clone())), + _ => Err(ParserError::InvalidUseModuleDecl), }?; let mut exports = Vec::new(); @@ -242,12 +265,11 @@ fn setup_qualified_import(mut terms: Vec>) -> Result>) -> Result -{ +fn setup_declaration(mut terms: Vec>) -> Result { let term = *terms.pop().unwrap(); match term { - Term::Clause(_, name, mut terms, _) => + Term::Clause(_, name, mut terms, _) => { if name.as_str() == "op" && terms.len() == 3 { Ok(Declaration::Op(setup_op_decl(terms)?)) } else if name.as_str() == "module" && terms.len() == 2 { @@ -265,53 +287,51 @@ fn setup_declaration(mut terms: Vec>) -> Result return Err(ParserError::InconsistentEntry) + } + } + _ => return Err(ParserError::InconsistentEntry), } } -fn is_consistent(tl: &TopLevel, clauses: &Vec) -> bool -{ +fn is_consistent(tl: &TopLevel, clauses: &Vec) -> bool { match clauses.first() { Some(ref cl) => tl.name() == cl.name() && tl.arity() == cl.arity(), - None => true + None => true, } } -fn deque_to_packet(head: TopLevel, deque: VecDeque) -> TopLevelPacket -{ +fn deque_to_packet(head: TopLevel, deque: VecDeque) -> TopLevelPacket { match head { TopLevel::Query(query) => TopLevelPacket::Query(query, deque), - tl => TopLevelPacket::Decl(tl, deque) + tl => TopLevelPacket::Decl(tl, deque), } } -fn merge_clauses(tls: &mut VecDeque) -> Result -{ +fn merge_clauses(tls: &mut VecDeque) -> Result { let mut clauses: Vec = vec![]; while let Some(tl) = tls.pop_front() { match tl { - TopLevel::Query(_) if clauses.is_empty() && tls.is_empty() => - return Ok(tl), - TopLevel::Declaration(_) if clauses.is_empty() => - return Ok(tl), - TopLevel::Query(_) => - return Err(ParserError::InconsistentEntry), - TopLevel::Fact(_) if is_consistent(&tl, &clauses) => + TopLevel::Query(_) if clauses.is_empty() && tls.is_empty() => return Ok(tl), + TopLevel::Declaration(_) if clauses.is_empty() => return Ok(tl), + TopLevel::Query(_) => return Err(ParserError::InconsistentEntry), + TopLevel::Fact(_) if is_consistent(&tl, &clauses) => { if let TopLevel::Fact(fact) = tl { let clause = PredicateClause::Fact(fact); clauses.push(clause); - }, - TopLevel::Rule(_) if is_consistent(&tl, &clauses) => + } + } + TopLevel::Rule(_) if is_consistent(&tl, &clauses) => { if let TopLevel::Rule(rule) = tl { let clause = PredicateClause::Rule(rule); clauses.push(clause); - }, - TopLevel::Predicate(_) if is_consistent(&tl, &clauses) => + } + } + TopLevel::Predicate(_) if is_consistent(&tl, &clauses) => { if let TopLevel::Predicate(pred) = tl { clauses.extend(pred.clauses().into_iter()) - }, + } + } _ => { tls.push_front(tl); break; @@ -333,8 +353,9 @@ fn append_preds(preds: &mut Vec) -> Predicate { fn mark_cut_variables_as(terms: &mut Vec, name: ClauseName) { for term in terms.iter_mut() { match term { - &mut Term::Constant(_, Constant::Atom(ref mut var, _)) if var.as_str() == "!" => - *var = name.clone(), + &mut Term::Constant(_, Constant::Atom(ref mut var, _)) if var.as_str() == "!" => { + *var = name.clone() + } _ => {} } } @@ -343,7 +364,7 @@ fn mark_cut_variables_as(terms: &mut Vec, name: ClauseName) { fn mark_cut_variable(term: &mut Term) -> bool { let cut_var_found = match term { &mut Term::Constant(_, Constant::Atom(ref var, _)) if var.as_str() == "!" => true, - _ => false + _ => false, }; if cut_var_found { @@ -369,19 +390,20 @@ fn flatten_hook(mut term: Term) -> Term { match (name.as_str(), terms.len()) { (":-", 2) => { let inner_term = match terms.first_mut().map(|term| term.borrow_mut()) { - Some(&mut Term::Clause(_, ref name, ref mut inner_terms, _)) => + Some(&mut Term::Clause(_, ref name, ref mut inner_terms, _)) => { if name.as_str() == ":" && inner_terms.len() == 2 { Some(*inner_terms.pop().unwrap()) } else { None - }, - _ => None + } + } + _ => None, }; if let Some(inner_term) = inner_term { mem::swap(&mut terms[0], &mut Box::new(inner_term)); } - }, + } (":", 2) => return *terms.pop().unwrap(), _ => {} } @@ -392,7 +414,7 @@ fn flatten_hook(mut term: Term) -> Term { pub enum TopLevelPacket { Query(Vec, VecDeque), - Decl(TopLevel, VecDeque) + Decl(TopLevel, VecDeque), } struct RelationWorker { @@ -403,31 +425,30 @@ struct RelationWorker { impl RelationWorker { fn new(flags: MachineFlags) -> Self { - RelationWorker { dynamic_clauses: vec![], - flags, - queue: VecDeque::new() } + RelationWorker { + dynamic_clauses: vec![], + flags, + queue: VecDeque::new(), + } } - fn setup_fact(&mut self, term: Term, assume_dyn: bool) -> Result - { + fn setup_fact(&mut self, term: Term, assume_dyn: bool) -> Result { match term { Term::Clause(..) | Term::Constant(_, Constant::Atom(..)) => { - let tail = Term::Constant(Cell::default(), - Constant::Atom(clause_name!("true"), None)); + let tail = + Term::Constant(Cell::default(), Constant::Atom(clause_name!("true"), None)); if assume_dyn { self.dynamic_clauses.push((term.clone(), tail)); } Ok(term) - }, - _ => - Err(ParserError::InadmissibleFact) + } + _ => Err(ParserError::InadmissibleFact), } } - fn compute_head(&self, term: &Term) -> Vec - { + fn compute_head(&self, term: &Term) -> Vec { let mut vars = IndexSet::new(); for term in post_order_iter(term) { @@ -442,8 +463,7 @@ impl RelationWorker { .collect() } - fn fabricate_rule_body(&self, vars: &Vec, body_term: Term) -> Term - { + fn fabricate_rule_body(&self, vars: &Vec, body_term: Term) -> Term { let vars_of_head = vars.iter().cloned().map(Box::new).collect(); let head_term = Term::Clause(Cell::default(), clause_name!(""), vars_of_head, None); @@ -456,8 +476,7 @@ impl RelationWorker { // the terms form the body of the rule. We create a head, by // gathering variables from the body of terms and recording them // in the head clause. - fn fabricate_rule(&self, body_term: Term) -> (JumpStub, VecDeque) - { + fn fabricate_rule(&self, body_term: Term) -> (JumpStub, VecDeque) { // collect the vars of body_term into a head, return the num_vars // (the arity) as well. let vars = self.compute_head(&body_term); @@ -466,30 +485,31 @@ impl RelationWorker { (vars, VecDeque::from(vec![rule])) } - fn fabricate_disjunct(&self, body_term: Term) -> (JumpStub, VecDeque) - { + fn fabricate_disjunct(&self, body_term: Term) -> (JumpStub, VecDeque) { let vars = self.compute_head(&body_term); - let clauses: Vec<_> = unfold_by_str(body_term, ";").into_iter() + let clauses: Vec<_> = unfold_by_str(body_term, ";") + .into_iter() .map(|term| { let mut subterms = unfold_by_str(term, ","); mark_cut_variables(&mut subterms); let term = subterms.pop().unwrap(); fold_by_str(subterms.into_iter(), term, clause_name!(",")) - }).collect(); + }) + .collect(); - let results = clauses.into_iter() + let results = clauses + .into_iter() .map(|clause| self.fabricate_rule_body(&vars, clause)) .collect(); (vars, results) } - fn fabricate_if_then(&self, prec: Term, conq: Term) -> (JumpStub, VecDeque) - { + fn fabricate_if_then(&self, prec: Term, conq: Term) -> (JumpStub, VecDeque) { let mut prec_seq = unfold_by_str(prec, ","); - let comma_sym = clause_name!(","); - let cut_sym = atom!("!"); + let comma_sym = clause_name!(","); + let cut_sym = atom!("!"); prec_seq.push(Term::Constant(Cell::default(), cut_sym)); @@ -500,70 +520,87 @@ impl RelationWorker { mark_cut_variables(&mut conq_seq); prec_seq.extend(conq_seq.into_iter()); - let back_term = Box::new(prec_seq.pop().unwrap()); + let back_term = Box::new(prec_seq.pop().unwrap()); let front_term = Box::new(prec_seq.pop().unwrap()); - let body_term = Term::Clause(Cell::default(), comma_sym.clone(), - vec![front_term, back_term], None); + let body_term = Term::Clause( + Cell::default(), + comma_sym.clone(), + vec![front_term, back_term], + None, + ); self.fabricate_rule(fold_by_str(prec_seq.into_iter(), body_term, comma_sym)) } - fn to_query_term(&mut self, indices: &mut CompositeIndices, term: Term) -> Result - { + fn to_query_term( + &mut self, + indices: &mut CompositeIndices, + term: Term, + ) -> Result { match term { - Term::Constant(_, Constant::Atom(name, fixity)) => + Term::Constant(_, Constant::Atom(name, fixity)) => { if name.as_str() == "!" || name.as_str() == "blocked_!" { Ok(QueryTerm::BlockedCut) } else { let ct = indices.get_clause_type(name, 0, fixity); Ok(QueryTerm::Clause(Cell::default(), ct, vec![], false)) - }, - Term::Var(_, ref v) if v.as_str() == "!" => - Ok(QueryTerm::UnblockedCut(Cell::default())), - Term::Clause(r, name, mut terms, fixity) => - match (name.as_str(), terms.len()) { - (";", 2) => { - let term = Term::Clause(r, name.clone(), terms, fixity); - let (stub, clauses) = self.fabricate_disjunct(term); - - self.queue.push_back(clauses); - Ok(QueryTerm::Jump(stub)) - }, - ("->", 2) => { - let conq = *terms.pop().unwrap(); - let prec = *terms.pop().unwrap(); - - let (stub, clauses) = self.fabricate_if_then(prec, conq); - - self.queue.push_back(clauses); - Ok(QueryTerm::Jump(stub)) - }, - ("$get_level", 1) => - if let Term::Var(_, ref var) = *terms[0] { - Ok(QueryTerm::GetLevelAndUnify(Cell::default(), var.clone())) - } else { - Err(ParserError::InadmissibleQueryTerm) - }, - ("partial_string", 2) => { - let ct = ClauseType::BuiltIn(BuiltInClauseType::PartialString); - return Ok(QueryTerm::Clause(Cell::default(), ct, terms, false)); - }, - _ => { - let ct = indices.get_clause_type(name, terms.len(), fixity); - Ok(QueryTerm::Clause(Cell::default(), ct, terms, false)) + } + } + Term::Var(_, ref v) if v.as_str() == "!" => { + Ok(QueryTerm::UnblockedCut(Cell::default())) + } + Term::Clause(r, name, mut terms, fixity) => match (name.as_str(), terms.len()) { + (";", 2) => { + let term = Term::Clause(r, name.clone(), terms, fixity); + let (stub, clauses) = self.fabricate_disjunct(term); + + self.queue.push_back(clauses); + Ok(QueryTerm::Jump(stub)) + } + ("->", 2) => { + let conq = *terms.pop().unwrap(); + let prec = *terms.pop().unwrap(); + + let (stub, clauses) = self.fabricate_if_then(prec, conq); + + self.queue.push_back(clauses); + Ok(QueryTerm::Jump(stub)) + } + ("$get_level", 1) => { + if let Term::Var(_, ref var) = *terms[0] { + Ok(QueryTerm::GetLevelAndUnify(Cell::default(), var.clone())) + } else { + Err(ParserError::InadmissibleQueryTerm) } - }, - Term::Var(..) => - Ok(QueryTerm::Clause(Cell::default(), ClauseType::CallN, vec![Box::new(term)], false)), - _ => Err(ParserError::InadmissibleQueryTerm) + } + ("partial_string", 2) => { + let ct = ClauseType::BuiltIn(BuiltInClauseType::PartialString); + return Ok(QueryTerm::Clause(Cell::default(), ct, terms, false)); + } + _ => { + let ct = indices.get_clause_type(name, terms.len(), fixity); + Ok(QueryTerm::Clause(Cell::default(), ct, terms, false)) + } + }, + Term::Var(..) => Ok(QueryTerm::Clause( + Cell::default(), + ClauseType::CallN, + vec![Box::new(term)], + false, + )), + _ => Err(ParserError::InadmissibleQueryTerm), } } // never blocks cuts in the consequent. - fn prepend_if_then(&self, prec: Term, conq: Term, queue: &mut VecDeque>, - blocks_cuts: bool) - { + fn prepend_if_then( + &self, + prec: Term, + conq: Term, + queue: &mut VecDeque>, + blocks_cuts: bool, + ) { let cut_symb = atom!("blocked_!"); let mut terms_seq = unfold_by_str(prec, ","); @@ -584,10 +621,13 @@ impl RelationWorker { } } - fn pre_query_term(&mut self, indices: &mut CompositeIndices, term: Term) -> Result - { + fn pre_query_term( + &mut self, + indices: &mut CompositeIndices, + term: Term, + ) -> Result { match term { - Term::Clause(r, name, mut subterms, fixity) => + Term::Clause(r, name, mut subterms, fixity) => { if subterms.len() == 1 && name.as_str() == "$call_with_default_policy" { self.to_query_term(indices, *subterms.pop().unwrap()) .map(|mut query_term| { @@ -596,15 +636,18 @@ impl RelationWorker { }) } else { self.to_query_term(indices, Term::Clause(r, name, subterms, fixity)) - }, - _ => self.to_query_term(indices, term) + } + } + _ => self.to_query_term(indices, term), } } - fn setup_query(&mut self, indices: &mut CompositeIndices, terms: Vec>, - blocks_cuts: bool) - -> Result, ParserError> - { + fn setup_query( + &mut self, + indices: &mut CompositeIndices, + terms: Vec>, + blocks_cuts: bool, + ) -> Result, ParserError> { let mut query_terms = vec![]; let mut work_queue = VecDeque::from(terms); @@ -637,11 +680,14 @@ impl RelationWorker { Ok(query_terms) } - fn setup_hook(&mut self, hook: CompileTimeHook, indices: &mut CompositeIndices, term: Term) - -> Result - { + fn setup_hook( + &mut self, + hook: CompileTimeHook, + indices: &mut CompositeIndices, + term: Term, + ) -> Result { match flatten_hook(term) { - Term::Clause(r, name, terms, _) => + Term::Clause(r, name, terms, _) => { if name == hook.name() && terms.len() == hook.arity() { let term = self.setup_fact(Term::Clause(r, name, terms, None), false)?; Ok((hook, PredicateClause::Fact(term), VecDeque::from(vec![]))) @@ -652,17 +698,21 @@ impl RelationWorker { Ok((hook, PredicateClause::Rule(rule), results_queue)) } else { Err(ParserError::InvalidHook) - }, - _ => Err(ParserError::InvalidHook) + } + } + _ => Err(ParserError::InvalidHook), } } - fn setup_rule(&mut self, indices: &mut CompositeIndices, mut terms: Vec>, - blocks_cuts: bool, assume_dyn: bool) - -> Result - { + fn setup_rule( + &mut self, + indices: &mut CompositeIndices, + mut terms: Vec>, + blocks_cuts: bool, + assume_dyn: bool, + ) -> Result { let head = *terms.first().cloned().unwrap(); - let post_head_terms: Vec<_> = terms.drain(1 .. ).collect(); + let post_head_terms: Vec<_> = terms.drain(1..).collect(); let tail = *post_head_terms.first().cloned().unwrap(); @@ -671,57 +721,84 @@ impl RelationWorker { } let mut query_terms = self.setup_query(indices, post_head_terms, blocks_cuts)?; - let clauses = query_terms.drain(1 ..).collect(); + let clauses = query_terms.drain(1..).collect(); let qt = query_terms.pop().unwrap(); match *terms.pop().unwrap() { - Term::Clause(_, name, terms, _) => - Ok(Rule { head: (name, terms, qt), clauses }), - Term::Constant(_, Constant::Atom(name, _)) => - Ok(Rule { head: (name, vec![], qt), clauses }), - _ => Err(ParserError::InvalidRuleHead) + Term::Clause(_, name, terms, _) => Ok(Rule { + head: (name, terms, qt), + clauses, + }), + Term::Constant(_, Constant::Atom(name, _)) => Ok(Rule { + head: (name, vec![], qt), + clauses, + }), + _ => Err(ParserError::InvalidRuleHead), } } - fn try_term_to_query(&mut self, indices: &mut CompositeIndices, terms: Vec>, blocks_cuts: bool) - -> Result - { + fn try_term_to_query( + &mut self, + indices: &mut CompositeIndices, + terms: Vec>, + blocks_cuts: bool, + ) -> Result { match setup_declaration(terms.iter().cloned().collect()) { - Ok(Declaration::Op(..)) => {}, // this is now a predicate call in the query context. + Ok(Declaration::Op(..)) => {} // this is now a predicate call in the query context. Ok(decl) => return Ok(TopLevel::Declaration(decl)), _ => {} }; - Ok(TopLevel::Query(self.setup_query(indices, terms, blocks_cuts)?)) + Ok(TopLevel::Query(self.setup_query( + indices, + terms, + blocks_cuts, + )?)) } - fn try_term_to_tl(&mut self, indices: &mut CompositeIndices, term: Term, blocks_cuts: bool) - -> Result - { + fn try_term_to_tl( + &mut self, + indices: &mut CompositeIndices, + term: Term, + blocks_cuts: bool, + ) -> Result { match term { - Term::Clause(r, name, terms, fixity) => + Term::Clause(r, name, terms, fixity) => { if let Some(hook) = is_compile_time_hook(&name, &terms) { let term = Term::Clause(r, name, terms, fixity); let (hook, clause, queue) = self.setup_hook(hook, indices, term)?; - Ok(TopLevel::Declaration(Declaration::Hook(hook, clause, queue))) + Ok(TopLevel::Declaration(Declaration::Hook( + hook, clause, queue, + ))) } else if name.as_str() == "?-" { self.try_term_to_query(indices, terms, blocks_cuts) } else if name.as_str() == ":-" && terms.len() == 2 { - Ok(TopLevel::Rule(self.setup_rule(indices, terms, blocks_cuts, true)?)) + Ok(TopLevel::Rule(self.setup_rule( + indices, + terms, + blocks_cuts, + true, + )?)) } else if name.as_str() == ":-" && terms.len() == 1 { Ok(TopLevel::Declaration(setup_declaration(terms)?)) } else { let term = Term::Clause(r, name, terms, fixity); Ok(TopLevel::Fact(try!(self.setup_fact(term, true)))) - }, - term => Ok(TopLevel::Fact(try!(self.setup_fact(term, true)))) + } + } + term => Ok(TopLevel::Fact(try!(self.setup_fact(term, true)))), } } - fn try_terms_to_tls(&mut self, indices: &mut CompositeIndices, terms: I, blocks_cuts: bool) - -> Result, ParserError> - where I: IntoIterator + fn try_terms_to_tls( + &mut self, + indices: &mut CompositeIndices, + terms: I, + blocks_cuts: bool, + ) -> Result, ParserError> + where + I: IntoIterator, { let mut results = VecDeque::new(); @@ -732,8 +809,10 @@ impl RelationWorker { Ok(results) } - fn parse_queue(&mut self, indices: &mut CompositeIndices) -> Result, ParserError> - { + fn parse_queue( + &mut self, + indices: &mut CompositeIndices, + ) -> Result, ParserError> { let mut queue = VecDeque::new(); while let Some(terms) = self.queue.pop_front() { @@ -746,21 +825,30 @@ impl RelationWorker { fn absorb(&mut self, other: RelationWorker) { self.queue.extend(other.queue.into_iter()); - self.dynamic_clauses.extend(other.dynamic_clauses.into_iter()); + self.dynamic_clauses + .extend(other.dynamic_clauses.into_iter()); } - fn expand_queue_contents(&mut self, term_stream: &mut TermStream, op_dir: &OpDir) - -> Result<(), SessionError> - where R: Read + fn expand_queue_contents( + &mut self, + term_stream: &mut TermStream, + op_dir: &OpDir, + ) -> Result<(), SessionError> + where + R: Read, { let mut machine_st = MachineState::new(); - let mut new_queue = VecDeque::new(); + let mut new_queue = VecDeque::new(); while let Some(terms) = self.queue.pop_front() { let mut new_terms = VecDeque::new(); for term in terms { - new_terms.push_back(term_stream.run_goal_expanders(&mut machine_st, &op_dir, term)?); + new_terms.push_back(term_stream.run_goal_expanders( + &mut machine_st, + &op_dir, + term, + )?); } new_queue.push_back(new_terms); @@ -770,9 +858,14 @@ impl RelationWorker { } } -fn term_to_toplevel(term_stream: &mut TermStream, code_dir: &mut CodeDir, term: Term, flags: MachineFlags) - -> Result<(TopLevel, RelationWorker), ParserError> - where R: Read +fn term_to_toplevel( + term_stream: &mut TermStream, + code_dir: &mut CodeDir, + term: Term, + flags: MachineFlags, +) -> Result<(TopLevel, RelationWorker), ParserError> +where + R: Read, { let mut rel_worker = RelationWorker::new(flags); let mut indices = composite_indices!(false, &mut term_stream.wam.indices, code_dir); @@ -782,13 +875,17 @@ fn term_to_toplevel(term_stream: &mut TermStream, code_dir: &mut CodeDir, Ok((tl, rel_worker)) } -pub -fn stream_to_toplevel(mut buffer: ParsingStream, wam: &mut Machine) - -> Result -{ +pub fn stream_to_toplevel( + mut buffer: ParsingStream, + wam: &mut Machine, +) -> Result { let flags = wam.machine_flags(); - let mut term_stream = TermStream::new(&mut buffer, wam.indices.atom_tbl(), - wam.machine_flags(), wam); + let mut term_stream = TermStream::new( + &mut buffer, + wam.indices.atom_tbl(), + wam.machine_flags(), + wam, + ); term_stream.add_to_top("?- "); @@ -811,74 +908,94 @@ pub struct TopLevelBatchWorker<'a, R: Read> { rel_worker: RelationWorker, pub(crate) results: Vec<(Predicate, VecDeque)>, pub(crate) dynamic_clause_map: DynamicClauseMap, - pub(crate) in_module: bool + pub(crate) in_module: bool, } impl<'a, R: Read> TopLevelBatchWorker<'a, R> { - - pub fn new(inner: &'a mut ParsingStream, atom_tbl: TabledData, - flags: MachineFlags, wam: &'a mut Machine) - -> Self - { + pub fn new( + inner: &'a mut ParsingStream, + atom_tbl: TabledData, + flags: MachineFlags, + wam: &'a mut Machine, + ) -> Self { let term_stream = TermStream::new(inner, atom_tbl, flags, wam); - TopLevelBatchWorker { term_stream, - rel_worker: RelationWorker::new(flags), - results: vec![], - dynamic_clause_map: IndexMap::new(), - in_module: false } + TopLevelBatchWorker { + term_stream, + rel_worker: RelationWorker::new(flags), + results: vec![], + dynamic_clause_map: IndexMap::new(), + in_module: false, + } } - fn try_term_to_tl(&self, indices: &mut IndexStore, term: Term) - -> Result<(TopLevel, RelationWorker), SessionError> - { + fn try_term_to_tl( + &self, + indices: &mut IndexStore, + term: Term, + ) -> Result<(TopLevel, RelationWorker), SessionError> { let mut new_rel_worker = RelationWorker::new(self.rel_worker.flags); - let mut indices = composite_indices!(self.in_module, indices, - &self.term_stream.wam.indices.code_dir); - - Ok((new_rel_worker.try_term_to_tl(&mut indices, term, true)?, new_rel_worker)) + let mut indices = composite_indices!( + self.in_module, + indices, + &self.term_stream.wam.indices.code_dir + ); + + Ok(( + new_rel_worker.try_term_to_tl(&mut indices, term, true)?, + new_rel_worker, + )) } - fn process_result(&mut self, indices: &mut IndexStore, preds: &mut Vec) - -> Result<(), SessionError> - { - self.rel_worker.expand_queue_contents(&mut self.term_stream, &indices.op_dir)?; - - let mut indices = composite_indices!(self.in_module, indices, - &mut self.term_stream.wam.indices.code_dir); - - let queue = self.rel_worker.parse_queue(&mut indices)?; + fn process_result( + &mut self, + indices: &mut IndexStore, + preds: &mut Vec, + ) -> Result<(), SessionError> { + self.rel_worker + .expand_queue_contents(&mut self.term_stream, &indices.op_dir)?; + + let mut indices = composite_indices!( + self.in_module, + indices, + &mut self.term_stream.wam.indices.code_dir + ); + + let queue = self.rel_worker.parse_queue(&mut indices)?; let result = (append_preds(preds), queue); let in_situ_code_dir = &mut self.term_stream.wam.indices.in_situ_code_dir; - self.term_stream.wam.code_repo.add_in_situ_result(&result, in_situ_code_dir, - self.term_stream.flags)?; + self.term_stream.wam.code_repo.add_in_situ_result( + &result, + in_situ_code_dir, + self.term_stream.flags, + )?; Ok(self.results.push(result)) } fn take_dynamic_clauses(&mut self) { let (name, arity) = match self.rel_worker.dynamic_clauses.first() { - Some((head, _)) => - (head.name().unwrap(), head.arity()), - None => - return + Some((head, _)) => (head.name().unwrap(), head.arity()), + None => return, }; match self.dynamic_clause_map.get_mut(&(name.clone(), arity)) { Some(ref mut entry) => { entry.clear(); // don't treat dynamic predicates as if they're discontiguous. - entry.extend(self.rel_worker.dynamic_clauses.drain(0 ..)); - }, + entry.extend(self.rel_worker.dynamic_clauses.drain(0..)); + } _ => { self.rel_worker.dynamic_clauses.clear(); } } } - pub fn consume(&mut self, indices: &mut IndexStore) -> Result, SessionError> - { + pub fn consume( + &mut self, + indices: &mut IndexStore, + ) -> Result, SessionError> { let mut preds = vec![]; while !self.term_stream.eof()? { @@ -902,7 +1019,7 @@ impl<'a, R: Read> TopLevelBatchWorker<'a, R> { TopLevel::Rule(rule) => preds.push(PredicateClause::Rule(rule)), TopLevel::Predicate(pred) => preds.extend(pred.0), TopLevel::Declaration(decl) => return Ok(Some(decl)), - TopLevel::Query(_) => return Err(SessionError::NamelessEntry) + TopLevel::Query(_) => return Err(SessionError::NamelessEntry), } } diff --git a/src/prolog/macros.rs b/src/prolog/macros.rs index 4c800ffe..ec17b8e1 100644 --- a/src/prolog/macros.rs +++ b/src/prolog/macros.rs @@ -1,40 +1,40 @@ macro_rules! interm { - ($n: expr) => ( + ($n: expr) => { ArithmeticTerm::Interm($n) - ) + }; } macro_rules! heap_str { - ($s:expr) => ( + ($s:expr) => { HeapCellValue::Addr(Addr::Str($s)) - ) + }; } macro_rules! heap_integer { - ($i:expr) => ( + ($i:expr) => { HeapCellValue::Addr(Addr::Con(Constant::Integer($i))) - ) + }; } macro_rules! heap_cell { - ($i:expr) => ( + ($i:expr) => { HeapCellValue::Addr(Addr::HeapCell($i)) - ) + }; } macro_rules! heap_con { - ($i:expr) => ( + ($i:expr) => { HeapCellValue::Addr(Addr::Con($i)) - ) + }; } macro_rules! heap_atom { - ($name:expr) => ( + ($name:expr) => { HeapCellValue::Addr(Addr::Con(atom!($name))) - ); - ($name:expr, $tbl:expr) => ( + }; + ($name:expr, $tbl:expr) => { HeapCellValue::Addr(Addr::Con(atom!($name, $tbl))) - ) + }; } macro_rules! functor { @@ -53,147 +53,158 @@ macro_rules! functor { } macro_rules! is_atom { - ($r:expr) => ( + ($r:expr) => { call_clause!(ClauseType::Inlined(InlinedClauseType::IsAtom($r)), 1, 0) - ) + }; } macro_rules! is_atomic { - ($r:expr) => ( + ($r:expr) => { call_clause!(ClauseType::Inlined(InlinedClauseType::IsAtomic($r)), 1, 0) - ) + }; } macro_rules! is_integer { - ($r:expr) => ( + ($r:expr) => { call_clause!(ClauseType::Inlined(InlinedClauseType::IsInteger($r)), 1, 0) - ) + }; } macro_rules! is_compound { - ($r:expr) => ( + ($r:expr) => { call_clause!(ClauseType::Inlined(InlinedClauseType::IsCompound($r)), 1, 0) - ) + }; } macro_rules! is_float { - ($r:expr) => ( + ($r:expr) => { call_clause!(ClauseType::Inlined(InlinedClauseType::IsFloat($r)), 1, 0) - ) + }; } macro_rules! is_rational { - ($r:expr) => ( + ($r:expr) => { call_clause!(ClauseType::Inlined(InlinedClauseType::IsRational($r)), 1, 0) - ) + }; } - macro_rules! is_nonvar { - ($r:expr) => ( + ($r:expr) => { call_clause!(ClauseType::Inlined(InlinedClauseType::IsNonVar($r)), 1, 0) - ) + }; } macro_rules! is_string { - ($r:expr) => ( + ($r:expr) => { call_clause!(ClauseType::Inlined(InlinedClauseType::IsString($r)), 1, 0) - ) + }; } macro_rules! is_var { - ($r:expr) => ( + ($r:expr) => { call_clause!(ClauseType::Inlined(InlinedClauseType::IsVar($r)), 1, 0) - ) + }; } macro_rules! is_partial_string { - ($r:expr) => ( - call_clause!(ClauseType::Inlined(InlinedClauseType::IsPartialString($r)), 1, 0) - ) + ($r:expr) => { + call_clause!( + ClauseType::Inlined(InlinedClauseType::IsPartialString($r)), + 1, + 0 + ) + }; } macro_rules! call_clause { - ($ct:expr, $arity:expr, $pvs:expr) => ( - Line::Control(ControlInstruction::CallClause($ct, $arity, $pvs, false, false)) - ); - ($ct:expr, $arity:expr, $pvs:expr, $lco:expr) => ( - Line::Control(ControlInstruction::CallClause($ct, $arity, $pvs, $lco, false)) - ) + ($ct:expr, $arity:expr, $pvs:expr) => { + Line::Control(ControlInstruction::CallClause( + $ct, $arity, $pvs, false, false, + )) + }; + ($ct:expr, $arity:expr, $pvs:expr, $lco:expr) => { + Line::Control(ControlInstruction::CallClause( + $ct, $arity, $pvs, $lco, false, + )) + }; } macro_rules! call_clause_by_default { - ($ct:expr, $arity:expr, $pvs:expr) => ( - Line::Control(ControlInstruction::CallClause($ct, $arity, $pvs, false, true)) - ); - ($ct:expr, $arity:expr, $pvs:expr, $lco:expr) => ( - Line::Control(ControlInstruction::CallClause($ct, $arity, $pvs, $lco, true)) - ) + ($ct:expr, $arity:expr, $pvs:expr) => { + Line::Control(ControlInstruction::CallClause( + $ct, $arity, $pvs, false, true, + )) + }; + ($ct:expr, $arity:expr, $pvs:expr, $lco:expr) => { + Line::Control(ControlInstruction::CallClause( + $ct, $arity, $pvs, $lco, true, + )) + }; } macro_rules! proceed { - () => ( + () => { Line::Control(ControlInstruction::Proceed) - ) + }; } macro_rules! is_call { - ($r:expr, $at:expr) => ( + ($r:expr, $at:expr) => { call_clause!(ClauseType::BuiltIn(BuiltInClauseType::Is($r, $at)), 2, 0) - ) + }; } macro_rules! is_call_by_default { - ($r:expr, $at:expr) => ( + ($r:expr, $at:expr) => { call_clause_by_default!(ClauseType::BuiltIn(BuiltInClauseType::Is($r, $at)), 2, 0) - ) + }; } macro_rules! set_cp { - ($r:expr) => ( + ($r:expr) => { call_clause!(ClauseType::System(SystemClauseType::SetCutPoint($r)), 1, 0) - ) + }; } macro_rules! succeed { - () => ( + () => { call_clause!(ClauseType::System(SystemClauseType::Succeed), 0, 0) - ) + }; } macro_rules! fail { - () => ( + () => { call_clause!(ClauseType::System(SystemClauseType::Fail), 0, 0) - ) + }; } macro_rules! compare_number_instr { ($cmp: expr, $at_1: expr, $at_2: expr) => {{ let ct = ClauseType::Inlined(InlinedClauseType::CompareNumber($cmp, $at_1, $at_2)); call_clause!(ct, 2, 0) - }} + }}; } macro_rules! jmp_call { - ($arity:expr, $offset:expr, $pvs:expr) => ( + ($arity:expr, $offset:expr, $pvs:expr) => { Line::Control(ControlInstruction::JmpBy($arity, $offset, $pvs, false)) - ) + }; } macro_rules! try_eval_session { - ($e:expr) => ( + ($e:expr) => { match $e { Ok(result) => result, - Err(e) => return EvalSession::from(e) + Err(e) => return EvalSession::from(e), } - ) + }; } macro_rules! return_from_clause { ($lco:expr, $machine_st:expr) => {{ if let CodePtr::VerifyAttrInterrupt(_) = $machine_st.p { return Ok(()); } - + if $lco { $machine_st.p = CodePtr::Local($machine_st.cp); } else { @@ -201,19 +212,19 @@ macro_rules! return_from_clause { } Ok(()) - }} + }}; } macro_rules! dir_entry { - ($idx:expr) => ( + ($idx:expr) => { CodePtr::Local(LocalCodePtr::DirEntry($idx)) - ) + }; } macro_rules! in_situ_dir_entry { - ($idx:expr) => ( + ($idx:expr) => { CodePtr::Local(LocalCodePtr::InSituDirEntry($idx)) - ) + }; } macro_rules! set_code_index { @@ -222,64 +233,69 @@ macro_rules! set_code_index { idx.0 = $ip; idx.1 = $mod_name.clone(); - }} + }}; } macro_rules! index_store { - ($atom_tbl:expr, $code_dir:expr, $op_dir:expr, $modules:expr) => ( - IndexStore { atom_tbl: $atom_tbl, - code_dir: $code_dir, - dynamic_code_dir: DynamicCodeDir::new(), - global_variables: GlobalVarDir::new(), - in_situ_code_dir: InSituCodeDir::new(), - op_dir: $op_dir, - modules: $modules } - ) + ($atom_tbl:expr, $code_dir:expr, $op_dir:expr, $modules:expr) => { + IndexStore { + atom_tbl: $atom_tbl, + code_dir: $code_dir, + dynamic_code_dir: DynamicCodeDir::new(), + global_variables: GlobalVarDir::new(), + in_situ_code_dir: InSituCodeDir::new(), + op_dir: $op_dir, + modules: $modules, + } + }; } macro_rules! default_index_store { - ($atom_tbl:expr) => ( + ($atom_tbl:expr) => { index_store!($atom_tbl, CodeDir::new(), default_op_dir(), IndexMap::new()) - ) + }; } macro_rules! put_constant { - ($lvl:expr, $cons:expr, $r:expr) => ( + ($lvl:expr, $cons:expr, $r:expr) => { QueryInstruction::PutConstant($lvl, $cons, $r) - ) + }; } macro_rules! top_level_code_ptr { - ($p:expr, $q_sz:expr) => ( + ($p:expr, $q_sz:expr) => { CodePtr::Local(LocalCodePtr::TopLevel($p, $q_sz)) - ) + }; } macro_rules! get_level_and_unify { - ($r: expr) => ( + ($r: expr) => { Line::Cut(CutInstruction::GetLevelAndUnify($r)) - ) + }; } macro_rules! unwind_protect { - ($e: expr, $protected: expr) => ( + ($e: expr, $protected: expr) => { match $e { - Err(e) => { $protected; return Err(e); }, + Err(e) => { + $protected; + return Err(e); + } _ => {} } - ) + }; } macro_rules! discard_result { - ($f: expr) => ( + ($f: expr) => { match $f { - _ => () + _ => (), } - ) + }; } macro_rules! ar_reg { - ($r: expr) => ( + ($r: expr) => { ArithmeticTerm::Reg($r) - ) + }; } diff --git a/src/prolog/mod.rs b/src/prolog/mod.rs index 6575f500..c98c3f27 100644 --- a/src/prolog/mod.rs +++ b/src/prolog/mod.rs @@ -3,20 +3,22 @@ extern crate ordered_float; extern crate prolog_parser; extern crate rug; -#[macro_use] mod macros; -pub mod instructions; +#[macro_use] +mod macros; mod clause_types; -#[macro_use] mod allocator; -mod fixtures; -pub mod machine; -mod forms; +pub mod instructions; +#[macro_use] +mod allocator; mod arithmetic; mod codegen; mod debray_allocator; +mod fixtures; +mod forms; mod heap_iter; +pub mod heap_print; mod indexing; -pub mod write; mod iterators; -pub mod heap_print; -mod targets; +pub mod machine; pub mod read; +mod targets; +pub mod write; diff --git a/src/prolog/read.rs b/src/prolog/read.rs index 3eda829d..ddebca49 100644 --- a/src/prolog/read.rs +++ b/src/prolog/read.rs @@ -26,8 +26,7 @@ impl<'a> TermRef<'a> { pub type PrologStream = ParsingStream>; #[cfg(feature = "readline_rs_compat")] -pub mod readline -{ +pub mod readline { use prolog_parser::ast::*; use readline_rs_compat::readline::*; use std::io::{Error, Read}; @@ -35,11 +34,11 @@ pub mod readline #[derive(Clone, Copy)] pub enum LineMode { Single, - Multi + Multi, } pub struct ReadlineStream { - pending_input: String + pending_input: String, } impl ReadlineStream { @@ -53,8 +52,8 @@ pub mod readline Some(text) => { self.pending_input += &text; Ok(self.write_to_buf(buf)) - }, - None => Err(Error::last_os_error()) + } + None => Err(Error::last_os_error()), } } @@ -73,7 +72,7 @@ pub mod readline let output_len = self.split_pending(buf, split_idx); if split_idx < self.pending_input.len() { - self.pending_input = self.pending_input[split_idx ..].to_string(); + self.pending_input = self.pending_input[split_idx..].to_string(); } else { self.pending_input.clear(); } @@ -144,13 +143,12 @@ pub mod readline } #[cfg(not(feature = "readline_rs_compat"))] -pub mod readline -{ +pub mod readline { use prolog_parser::ast::*; - use std::io::{BufReader, Read, Stdin, stdin}; + use std::io::{stdin, BufReader, Read, Stdin}; struct StdinWrapper { - buf: BufReader + buf: BufReader, } impl Read for StdinWrapper { @@ -161,15 +159,20 @@ pub mod readline #[inline] pub fn input_stream() -> ::PrologStream { - let reader: Box = Box::new(StdinWrapper { buf: BufReader::new(stdin()) }); + let reader: Box = Box::new(StdinWrapper { + buf: BufReader::new(stdin()), + }); parsing_stream(reader) } } impl MachineState { - pub fn read(&mut self, inner: &mut PrologStream, atom_tbl: TabledData, op_dir: &OpDir) - -> Result - { + pub fn read( + &mut self, + inner: &mut PrologStream, + atom_tbl: TabledData, + op_dir: &OpDir, + ) -> Result { let mut parser = Parser::new(inner, atom_tbl, self.flags); let term = parser.read_term(composite_op!(op_dir))?; @@ -182,8 +185,12 @@ fn push_stub_addr(machine_st: &mut MachineState) { machine_st.heap.push(HeapCellValue::Addr(Addr::HeapCell(h))); } -fn modify_head_of_queue(machine_st: &mut MachineState, queue: &mut SubtermDeque, term: TermRef, h: usize) -{ +fn modify_head_of_queue( + machine_st: &mut MachineState, + queue: &mut SubtermDeque, + term: TermRef, + h: usize, +) { if let Some((arity, site_h)) = queue.pop_front() { machine_st.heap[site_h] = HeapCellValue::Addr(term.as_addr(h)); @@ -198,9 +205,7 @@ pub struct TermWriteResult { pub(crate) var_dict: HeapVarDict, } -pub(crate) -fn write_term_to_heap(term: &Term, machine_st: &mut MachineState) -> TermWriteResult -{ +pub(crate) fn write_term_to_heap(term: &Term, machine_st: &mut MachineState) -> TermWriteResult { let heap_loc = machine_st.heap.h; let mut queue = SubtermDeque::new(); @@ -211,8 +216,8 @@ fn write_term_to_heap(term: &Term, machine_st: &mut MachineState) -> TermWriteRe match &term { &TermRef::Cons(lvl, ..) => { - queue.push_back((2, h+1)); - machine_st.heap.push(HeapCellValue::Addr(Addr::Lis(h+1))); + queue.push_back((2, h + 1)); + machine_st.heap.push(HeapCellValue::Addr(Addr::Lis(h + 1))); push_stub_addr(machine_st); push_stub_addr(machine_st); @@ -220,25 +225,27 @@ fn write_term_to_heap(term: &Term, machine_st: &mut MachineState) -> TermWriteRe if let Level::Root = lvl { continue; } - }, + } &TermRef::Clause(lvl, _, ref ct, subterms) => { - queue.push_back((subterms.len(), h+1)); + queue.push_back((subterms.len(), h + 1)); let named = HeapCellValue::NamedStr(subterms.len(), ct.name(), ct.spec()); machine_st.heap.push(named); - for _ in 0 .. subterms.len() { + for _ in 0..subterms.len() { push_stub_addr(machine_st); } if let Level::Root = lvl { continue; } - }, - &TermRef::AnonVar(Level::Root) | &TermRef::Constant(Level::Root, ..) => - machine_st.heap.push(HeapCellValue::Addr(term.as_addr(h))), - &TermRef::Var(Level::Root, ..) => - machine_st.heap.push(HeapCellValue::Addr(term.as_addr(h))), + } + &TermRef::AnonVar(Level::Root) | &TermRef::Constant(Level::Root, ..) => { + machine_st.heap.push(HeapCellValue::Addr(term.as_addr(h))) + } + &TermRef::Var(Level::Root, ..) => { + machine_st.heap.push(HeapCellValue::Addr(term.as_addr(h))) + } &TermRef::AnonVar(_) => { if let Some((arity, site_h)) = queue.pop_front() { if arity > 1 { @@ -247,7 +254,7 @@ fn write_term_to_heap(term: &Term, machine_st: &mut MachineState) -> TermWriteRe } continue; - }, + } &TermRef::Var(_, _, ref var) => { if let Some((arity, site_h)) = queue.pop_front() { if let Some(addr) = var_dict.get(var).cloned() { @@ -262,7 +269,7 @@ fn write_term_to_heap(term: &Term, machine_st: &mut MachineState) -> TermWriteRe } continue; - }, + } _ => {} }; diff --git a/src/prolog/targets.rs b/src/prolog/targets.rs index b5718723..f0d2297c 100644 --- a/src/prolog/targets.rs +++ b/src/prolog/targets.rs @@ -6,7 +6,7 @@ use prolog::instructions::*; use prolog::iterators::*; pub trait CompilationTarget<'a> { - type Iterator : Iterator>; + type Iterator: Iterator>; fn iter(&'a Term) -> Self::Iterator; @@ -43,8 +43,7 @@ impl<'a> CompilationTarget<'a> for FactInstruction { FactInstruction::GetConstant(lvl, constant, reg) } - fn to_structure(ct: ClauseType, arity: usize, reg: RegType) -> Self - { + fn to_structure(ct: ClauseType, arity: usize, reg: RegType) -> Self { FactInstruction::GetStructure(ct, arity, reg) } @@ -59,7 +58,7 @@ impl<'a> CompilationTarget<'a> for FactInstruction { fn is_void_instr(&self) -> bool { match self { &FactInstruction::UnifyVoid(_) => true, - _ => false + _ => false, } } @@ -125,7 +124,7 @@ impl<'a> CompilationTarget<'a> for QueryInstruction { fn is_void_instr(&self) -> bool { match self { &QueryInstruction::SetVoid(_) => true, - _ => false + _ => false, } } diff --git a/src/prolog/write.rs b/src/prolog/write.rs index c8f9d8e4..ff53b3a5 100644 --- a/src/prolog/write.rs +++ b/src/prolog/write.rs @@ -4,25 +4,24 @@ use prolog::instructions::*; use prolog::machine::machine_errors::*; use prolog::machine::machine_indices::*; -use termion::input::TermRead; use termion::event::Key; +use termion::input::TermRead; -use std::io::stdin; use std::fmt; +use std::io::stdin; impl fmt::Display for LocalCodePtr { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - LocalCodePtr::DirEntry(p) => - write!(f, "LocalCodePtr::DirEntry({})", p), - LocalCodePtr::InSituDirEntry(p) => - write!(f, "LocalCodePtr::InSituDirEntry({})", p), - LocalCodePtr::TopLevel(cn, p) => - write!(f, "LocalCodePtr::TopLevel({}, {})", cn, p), - LocalCodePtr::UserGoalExpansion(p) => - write!(f, "LocalCodePtr::UserGoalExpansion({})", p), - LocalCodePtr::UserTermExpansion(p) => - write!(f, "LocalCodePtr::UserTermExpansion({})", p), + LocalCodePtr::DirEntry(p) => write!(f, "LocalCodePtr::DirEntry({})", p), + LocalCodePtr::InSituDirEntry(p) => write!(f, "LocalCodePtr::InSituDirEntry({})", p), + LocalCodePtr::TopLevel(cn, p) => write!(f, "LocalCodePtr::TopLevel({}, {})", cn, p), + LocalCodePtr::UserGoalExpansion(p) => { + write!(f, "LocalCodePtr::UserGoalExpansion({})", p) + } + LocalCodePtr::UserTermExpansion(p) => { + write!(f, "LocalCodePtr::UserTermExpansion({})", p) + } } } } @@ -30,10 +29,10 @@ impl fmt::Display for LocalCodePtr { impl fmt::Display for REPLCodePtr { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - REPLCodePtr::CompileBatch => - write!(f, "REPLCodePtr::CompileBatch"), - REPLCodePtr::SubmitQueryAndPrintResults => + REPLCodePtr::CompileBatch => write!(f, "REPLCodePtr::CompileBatch"), + REPLCodePtr::SubmitQueryAndPrintResults => { write!(f, "REPLCodePtr::SubmitQueryAndPrintResults") + } } } } @@ -41,10 +40,8 @@ impl fmt::Display for REPLCodePtr { impl fmt::Display for IndexPtr { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - &IndexPtr::Undefined => - write!(f, "undefined"), - &IndexPtr::Index(i) => - write!(f, "{}", i) + &IndexPtr::Undefined => write!(f, "undefined"), + &IndexPtr::Index(i) => write!(f, "{}", i), } } } @@ -52,26 +49,24 @@ impl fmt::Display for IndexPtr { impl fmt::Display for FactInstruction { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - &FactInstruction::GetConstant(lvl, ref constant, ref r) => - write!(f, "get_constant {}, {}{}", constant, lvl, r.reg_num()), - &FactInstruction::GetList(lvl, ref r) => - write!(f, "get_list {}{}", lvl, r.reg_num()), - &FactInstruction::GetStructure(ref ct, ref arity, ref r) => - write!(f, "get_structure {}/{}, {}", ct.name(), arity, r), - &FactInstruction::GetValue(ref x, ref a) => - write!(f, "get_value {}, A{}", x, a), - &FactInstruction::GetVariable(ref x, ref a) => - write!(f, "fact:get_variable {}, A{}", x, a), - &FactInstruction::UnifyConstant(ref constant) => - write!(f, "unify_constant {}", constant), - &FactInstruction::UnifyVariable(ref r) => - write!(f, "unify_variable {}", r), - &FactInstruction::UnifyLocalValue(ref r) => - write!(f, "unify_local_value {}", r), - &FactInstruction::UnifyValue(ref r) => - write!(f, "unify_value {}", r), - &FactInstruction::UnifyVoid(n) => - write!(f, "unify_void {}", n) + &FactInstruction::GetConstant(lvl, ref constant, ref r) => { + write!(f, "get_constant {}, {}{}", constant, lvl, r.reg_num()) + } + &FactInstruction::GetList(lvl, ref r) => write!(f, "get_list {}{}", lvl, r.reg_num()), + &FactInstruction::GetStructure(ref ct, ref arity, ref r) => { + write!(f, "get_structure {}/{}, {}", ct.name(), arity, r) + } + &FactInstruction::GetValue(ref x, ref a) => write!(f, "get_value {}, A{}", x, a), + &FactInstruction::GetVariable(ref x, ref a) => { + write!(f, "fact:get_variable {}, A{}", x, a) + } + &FactInstruction::UnifyConstant(ref constant) => { + write!(f, "unify_constant {}", constant) + } + &FactInstruction::UnifyVariable(ref r) => write!(f, "unify_variable {}", r), + &FactInstruction::UnifyLocalValue(ref r) => write!(f, "unify_local_value {}", r), + &FactInstruction::UnifyValue(ref r) => write!(f, "unify_value {}", r), + &FactInstruction::UnifyVoid(n) => write!(f, "unify_void {}", n), } } } @@ -79,30 +74,24 @@ impl fmt::Display for FactInstruction { impl fmt::Display for QueryInstruction { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - &QueryInstruction::GetVariable(ref x, ref a) => - write!(f, "query:get_variable {}, A{}", x, a), - &QueryInstruction::PutConstant(lvl, ref constant, ref r) => - write!(f, "put_constant {}, {}{}", constant, lvl, r.reg_num()), - &QueryInstruction::PutList(lvl, ref r) => - write!(f, "put_list {}{}", lvl, r.reg_num()), - &QueryInstruction::PutStructure(ref ct, ref arity, ref r) => - write!(f, "put_structure {}/{}, {}", ct.name(), arity, r), - &QueryInstruction::PutUnsafeValue(y, a) => - write!(f, "put_unsafe_value Y{}, A{}", y, a), - &QueryInstruction::PutValue(ref x, ref a) => - write!(f, "put_value {}, A{}", x, a), - &QueryInstruction::PutVariable(ref x, ref a) => - write!(f, "put_variable {}, A{}", x, a), - &QueryInstruction::SetConstant(ref constant) => - write!(f, "set_constant {}", constant), - &QueryInstruction::SetLocalValue(ref r) => - write!(f, "set_local_value {}", r), - &QueryInstruction::SetVariable(ref r) => - write!(f, "set_variable {}", r), - &QueryInstruction::SetValue(ref r) => - write!(f, "set_value {}", r), - &QueryInstruction::SetVoid(n) => - write!(f, "set_void {}", n) + &QueryInstruction::GetVariable(ref x, ref a) => { + write!(f, "query:get_variable {}, A{}", x, a) + } + &QueryInstruction::PutConstant(lvl, ref constant, ref r) => { + write!(f, "put_constant {}, {}{}", constant, lvl, r.reg_num()) + } + &QueryInstruction::PutList(lvl, ref r) => write!(f, "put_list {}{}", lvl, r.reg_num()), + &QueryInstruction::PutStructure(ref ct, ref arity, ref r) => { + write!(f, "put_structure {}/{}, {}", ct.name(), arity, r) + } + &QueryInstruction::PutUnsafeValue(y, a) => write!(f, "put_unsafe_value Y{}, A{}", y, a), + &QueryInstruction::PutValue(ref x, ref a) => write!(f, "put_value {}, A{}", x, a), + &QueryInstruction::PutVariable(ref x, ref a) => write!(f, "put_variable {}, A{}", x, a), + &QueryInstruction::SetConstant(ref constant) => write!(f, "set_constant {}", constant), + &QueryInstruction::SetLocalValue(ref r) => write!(f, "set_local_value {}", r), + &QueryInstruction::SetVariable(ref r) => write!(f, "set_variable {}", r), + &QueryInstruction::SetValue(ref r) => write!(f, "set_value {}", r), + &QueryInstruction::SetVoid(n) => write!(f, "set_void {}", n), } } } @@ -134,15 +123,12 @@ impl fmt::Display for CompareTermQT { impl fmt::Display for ClauseType { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - &ClauseType::System(SystemClauseType::SetCutPoint(r)) => - write!(f, "$set_cp({})", r), - &ClauseType::Named(ref name, _, ref idx) - | &ClauseType::Op(ref name, _, ref idx) => - { + &ClauseType::System(SystemClauseType::SetCutPoint(r)) => write!(f, "$set_cp({})", r), + &ClauseType::Named(ref name, _, ref idx) | &ClauseType::Op(ref name, _, ref idx) => { let idx = idx.0.borrow(); write!(f, "{}:{}/{}", idx.1, name, idx.0) - }, - ref ct => write!(f, "{}", ct.name()) + } + ref ct => write!(f, "{}", ct.name()), } } } @@ -150,13 +136,18 @@ impl fmt::Display for ClauseType { impl fmt::Display for HeapCellValue { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - &HeapCellValue::Addr(ref addr) => - write!(f, "{}", addr), - &HeapCellValue::NamedStr(arity, ref name, Some(ref cell)) => - write!(f, "{}/{} (op, priority: {}, spec: {})", name.as_str(), arity, - cell.prec(), cell.assoc()), - &HeapCellValue::NamedStr(arity, ref name, None) => + &HeapCellValue::Addr(ref addr) => write!(f, "{}", addr), + &HeapCellValue::NamedStr(arity, ref name, Some(ref cell)) => write!( + f, + "{}/{} (op, priority: {}, spec: {})", + name.as_str(), + arity, + cell.prec(), + cell.assoc() + ), + &HeapCellValue::NamedStr(arity, ref name, None) => { write!(f, "{}/{}", name.as_str(), arity) + } } } } @@ -164,9 +155,10 @@ impl fmt::Display for HeapCellValue { impl fmt::Display for DBRef { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - &DBRef::NamedPred(ref name, arity, _) => write!(f, "db_ref:named:{}/{}", name, arity), - &DBRef::Op(priority, spec, ref name, ..) => write!(f, "db_ref:op({}, {}, {})", priority, - spec, name) + &DBRef::NamedPred(ref name, arity, _) => write!(f, "db_ref:named:{}/{}", name, arity), + &DBRef::Op(priority, spec, ref name, ..) => { + write!(f, "db_ref:op({}, {}, {})", priority, spec, name) + } } } } @@ -179,8 +171,8 @@ impl fmt::Display for Addr { &Addr::Lis(l) => write!(f, "Addr::Lis({})", l), &Addr::AttrVar(h) => write!(f, "Addr::AttrVar({})", h), &Addr::HeapCell(h) => write!(f, "Addr::HeapCell({})", h), - &Addr::StackCell(fr, sc)=> write!(f, "Addr::StackCell({}, {})", fr, sc), - &Addr::Str(s) => write!(f, "Addr::Str({})", s) + &Addr::StackCell(fr, sc) => write!(f, "Addr::StackCell({}, {})", fr, sc), + &Addr::Str(s) => write!(f, "Addr::Str({})", s), } } } @@ -188,24 +180,27 @@ impl fmt::Display for Addr { impl fmt::Display for ControlInstruction { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - &ControlInstruction::Allocate(num_cells) => - write!(f, "allocate {}", num_cells), - &ControlInstruction::CallClause(ref ct, arity, pvs, true, true) => - write!(f, "call_with_default_policy {}/{}, {}", ct, arity, pvs), - &ControlInstruction::CallClause(ref ct, arity, pvs, false, true) => - write!(f, "execute_with_default_policy {}/{}, {}", ct, arity, pvs), - &ControlInstruction::CallClause(ref ct, arity, pvs, true, false) => - write!(f, "execute {}/{}, {}", ct, arity, pvs), - &ControlInstruction::CallClause(ref ct, arity, pvs, false, false) => - write!(f, "call {}/{}, {}", ct, arity, pvs), - &ControlInstruction::Deallocate => - write!(f, "deallocate"), - &ControlInstruction::JmpBy(arity, offset, pvs, false) => - write!(f, "jmp_by_call {}/{}, {}", offset, arity, pvs), - &ControlInstruction::JmpBy(arity, offset, pvs, true) => - write!(f, "jmp_by_execute {}/{}, {}", offset, arity, pvs), - &ControlInstruction::Proceed => - write!(f, "proceed"), + &ControlInstruction::Allocate(num_cells) => write!(f, "allocate {}", num_cells), + &ControlInstruction::CallClause(ref ct, arity, pvs, true, true) => { + write!(f, "call_with_default_policy {}/{}, {}", ct, arity, pvs) + } + &ControlInstruction::CallClause(ref ct, arity, pvs, false, true) => { + write!(f, "execute_with_default_policy {}/{}, {}", ct, arity, pvs) + } + &ControlInstruction::CallClause(ref ct, arity, pvs, true, false) => { + write!(f, "execute {}/{}, {}", ct, arity, pvs) + } + &ControlInstruction::CallClause(ref ct, arity, pvs, false, false) => { + write!(f, "call {}/{}, {}", ct, arity, pvs) + } + &ControlInstruction::Deallocate => write!(f, "deallocate"), + &ControlInstruction::JmpBy(arity, offset, pvs, false) => { + write!(f, "jmp_by_call {}/{}, {}", offset, arity, pvs) + } + &ControlInstruction::JmpBy(arity, offset, pvs, true) => { + write!(f, "jmp_by_execute {}/{}, {}", offset, arity, pvs) + } + &ControlInstruction::Proceed => write!(f, "proceed"), } } } @@ -213,12 +208,9 @@ impl fmt::Display for ControlInstruction { impl fmt::Display for IndexedChoiceInstruction { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - &IndexedChoiceInstruction::Try(offset) => - write!(f, "try {}", offset), - &IndexedChoiceInstruction::Retry(offset) => - write!(f, "retry {}", offset), - &IndexedChoiceInstruction::Trust(offset) => - write!(f, "trust {}", offset) + &IndexedChoiceInstruction::Try(offset) => write!(f, "try {}", offset), + &IndexedChoiceInstruction::Retry(offset) => write!(f, "retry {}", offset), + &IndexedChoiceInstruction::Trust(offset) => write!(f, "trust {}", offset), } } } @@ -226,16 +218,13 @@ impl fmt::Display for IndexedChoiceInstruction { impl fmt::Display for ChoiceInstruction { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - &ChoiceInstruction::TryMeElse(offset) => - write!(f, "try_me_else {}", offset), - &ChoiceInstruction::DefaultRetryMeElse(offset) => - write!(f, "retry_me_else_by_default {}", offset), - &ChoiceInstruction::RetryMeElse(offset) => - write!(f, "retry_me_else {}", offset), - &ChoiceInstruction::DefaultTrustMe => - write!(f, "trust_me_by_default"), - &ChoiceInstruction::TrustMe => - write!(f, "trust_me") + &ChoiceInstruction::TryMeElse(offset) => write!(f, "try_me_else {}", offset), + &ChoiceInstruction::DefaultRetryMeElse(offset) => { + write!(f, "retry_me_else_by_default {}", offset) + } + &ChoiceInstruction::RetryMeElse(offset) => write!(f, "retry_me_else {}", offset), + &ChoiceInstruction::DefaultTrustMe => write!(f, "trust_me_by_default"), + &ChoiceInstruction::TrustMe => write!(f, "trust_me"), } } } @@ -243,12 +232,15 @@ impl fmt::Display for ChoiceInstruction { impl fmt::Display for IndexingInstruction { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - &IndexingInstruction::SwitchOnTerm(v, c, l, s) => - write!(f, "switch_on_term {}, {}, {}, {}", v, c, l, s), - &IndexingInstruction::SwitchOnConstant(num_cs, _) => - write!(f, "switch_on_constant {}", num_cs), - &IndexingInstruction::SwitchOnStructure(num_ss, _) => + &IndexingInstruction::SwitchOnTerm(v, c, l, s) => { + write!(f, "switch_on_term {}, {}, {}, {}", v, c, l, s) + } + &IndexingInstruction::SwitchOnConstant(num_cs, _) => { + write!(f, "switch_on_constant {}", num_cs) + } + &IndexingInstruction::SwitchOnStructure(num_ss, _) => { write!(f, "switch_on_structure {}", num_ss) + } } } } @@ -256,25 +248,28 @@ impl fmt::Display for IndexingInstruction { impl fmt::Display for SessionError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - &SessionError::CannotOverwriteBuiltIn(ref msg) => - write!(f, "cannot overwrite {}", msg), - &SessionError::CannotOverwriteImport(ref msg) => - write!(f, "cannot overwrite import {}", msg), - &SessionError::InvalidFileName(ref filename) => - write!(f, "filename {} is invalid", filename), + &SessionError::CannotOverwriteBuiltIn(ref msg) => write!(f, "cannot overwrite {}", msg), + &SessionError::CannotOverwriteImport(ref msg) => { + write!(f, "cannot overwrite import {}", msg) + } + &SessionError::InvalidFileName(ref filename) => { + write!(f, "filename {} is invalid", filename) + } &SessionError::ModuleNotFound => write!(f, "module not found."), - &SessionError::ModuleDoesNotContainExport => - write!(f, "module does not contain claimed export."), - &SessionError::NoModuleDeclaration(ref name) => - write!(f, "file {}.pl lacks an expected module declaration.", name), - &SessionError::OpIsInfixAndPostFix(_) => - write!(f, "cannot define an op to be both postfix and infix."), - &SessionError::NamelessEntry => - write!(f, "the predicate head is not an atom or clause."), - &SessionError::ParserError(ref e) => - write!(f, "syntax_error({})", e.as_str()), - &SessionError::UserPrompt => - write!(f, "enter predicate at [user] prompt") + &SessionError::ModuleDoesNotContainExport => { + write!(f, "module does not contain claimed export.") + } + &SessionError::NoModuleDeclaration(ref name) => { + write!(f, "file {}.pl lacks an expected module declaration.", name) + } + &SessionError::OpIsInfixAndPostFix(_) => { + write!(f, "cannot define an op to be both postfix and infix.") + } + &SessionError::NamelessEntry => { + write!(f, "the predicate head is not an atom or clause.") + } + &SessionError::ParserError(ref e) => write!(f, "syntax_error({})", e.as_str()), + &SessionError::UserPrompt => write!(f, "enter predicate at [user] prompt"), } } } @@ -284,7 +279,7 @@ impl fmt::Display for Number { match self { &Number::Float(fl) => write!(f, "{}", fl), &Number::Integer(ref bi) => write!(f, "{}", bi), - &Number::Rational(ref r) => write!(f, "{}", r) + &Number::Rational(ref r) => write!(f, "{}", r), } } } @@ -302,80 +297,83 @@ impl fmt::Display for ArithmeticTerm { impl fmt::Display for ArithmeticInstruction { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - &ArithmeticInstruction::Abs(ref a1, ref t) => - write!(f, "abs {}, @{}", a1, t), - &ArithmeticInstruction::Add(ref a1, ref a2, ref t) => - write!(f, "add {}, {}, @{}", a1, a2, t), - &ArithmeticInstruction::Sub(ref a1, ref a2, ref t) => - write!(f, "sub {}, {}, @{}", a1, a2, t), - &ArithmeticInstruction::Mul(ref a1, ref a2, ref t) => - write!(f, "mul {}, {}, @{}", a1, a2, t), - &ArithmeticInstruction::Pow(ref a1, ref a2, ref t) => - write!(f, "** {}, {}, @{}", a1, a2, t), - &ArithmeticInstruction::IntPow(ref a1, ref a2, ref t) => - write!(f, "^ {}, {}, @{}", a1, a2, t), - &ArithmeticInstruction::Div(ref a1, ref a2, ref t) => - write!(f, "div {}, {}, @{}", a1, a2, t), - &ArithmeticInstruction::IDiv(ref a1, ref a2, ref t) => - write!(f, "idiv {}, {}, @{}", a1, a2, t), - &ArithmeticInstruction::Max(ref a1, ref a2, ref t) => - write!(f, "max {}, {}, @{}", a1, a2, t), - &ArithmeticInstruction::Min(ref a1, ref a2, ref t) => - write!(f, "min {}, {}, @{}", a1, a2, t), - &ArithmeticInstruction::IntFloorDiv(ref a1, ref a2, ref t) => - write!(f, "int_floor_div {}, {}, @{}", a1, a2, t), - &ArithmeticInstruction::RDiv(ref a1, ref a2, ref t) => - write!(f, "rdiv {}, {}, @{}", a1, a2, t), - &ArithmeticInstruction::Shl(ref a1, ref a2, ref t) => - write!(f, "shl {}, {}, @{}", a1, a2, t), - &ArithmeticInstruction::Shr(ref a1, ref a2, ref t) => - write!(f, "shr {}, {}, @{}", a1, a2, t), - &ArithmeticInstruction::Xor(ref a1, ref a2, ref t) => - write!(f, "xor {}, {}, @{}", a1, a2, t), - &ArithmeticInstruction::And(ref a1, ref a2, ref t) => - write!(f, "and {}, {}, @{}", a1, a2, t), - &ArithmeticInstruction::Or(ref a1, ref a2, ref t) => - write!(f, "or {}, {}, @{}", a1, a2, t), - &ArithmeticInstruction::Mod(ref a1, ref a2, ref t) => - write!(f, "mod {}, {}, @{}", a1, a2, t), - &ArithmeticInstruction::Rem(ref a1, ref a2, ref t) => - write!(f, "rem {}, {}, @{}", a1, a2, t), - &ArithmeticInstruction::ATan2(ref a1, ref a2, ref t) => - write!(f, "atan2 {}, {}, @{}", a1, a2, t), - &ArithmeticInstruction::Plus(ref a, ref t) => - write!(f, "plus {}, @{}", a, t), - &ArithmeticInstruction::Neg(ref a, ref t) => - write!(f, "neg {}, @{}", a, t), - &ArithmeticInstruction::Cos(ref a, ref t) => - write!(f, "cos {}, @{}", a, t), - &ArithmeticInstruction::Sin(ref a, ref t) => - write!(f, "sin {}, @{}", a, t), - &ArithmeticInstruction::Tan(ref a, ref t) => - write!(f, "tan {}, @{}", a, t), - &ArithmeticInstruction::ATan(ref a, ref t) => - write!(f, "atan {}, @{}", a, t), - &ArithmeticInstruction::ASin(ref a, ref t) => - write!(f, "asin {}, @{}", a, t), - &ArithmeticInstruction::ACos(ref a, ref t) => - write!(f, "acos {}, @{}", a, t), - &ArithmeticInstruction::Log(ref a, ref t) => - write!(f, "log {}, @{}", a, t), - &ArithmeticInstruction::Exp(ref a, ref t) => - write!(f, "exp {}, @{}", a, t), - &ArithmeticInstruction::Sqrt(ref a, ref t) => - write!(f, "sqrt {}, @{}", a, t), - &ArithmeticInstruction::BitwiseComplement(ref a, ref t) => - write!(f, "bitwise_complement {}, @{}", a, t), - &ArithmeticInstruction::Truncate(ref a, ref t) => - write!(f, "truncate {}, @{}", a, t), - &ArithmeticInstruction::Round(ref a, ref t) => - write!(f, "round {}, @{}", a, t), - &ArithmeticInstruction::Ceiling(ref a, ref t) => - write!(f, "ceiling {}, @{}", a, t), - &ArithmeticInstruction::Floor(ref a, ref t) => - write!(f, "floor {}, @{}", a, t), - &ArithmeticInstruction::Float(ref a, ref t) => - write!(f, "float {}, @{}", a, t), + &ArithmeticInstruction::Abs(ref a1, ref t) => write!(f, "abs {}, @{}", a1, t), + &ArithmeticInstruction::Add(ref a1, ref a2, ref t) => { + write!(f, "add {}, {}, @{}", a1, a2, t) + } + &ArithmeticInstruction::Sub(ref a1, ref a2, ref t) => { + write!(f, "sub {}, {}, @{}", a1, a2, t) + } + &ArithmeticInstruction::Mul(ref a1, ref a2, ref t) => { + write!(f, "mul {}, {}, @{}", a1, a2, t) + } + &ArithmeticInstruction::Pow(ref a1, ref a2, ref t) => { + write!(f, "** {}, {}, @{}", a1, a2, t) + } + &ArithmeticInstruction::IntPow(ref a1, ref a2, ref t) => { + write!(f, "^ {}, {}, @{}", a1, a2, t) + } + &ArithmeticInstruction::Div(ref a1, ref a2, ref t) => { + write!(f, "div {}, {}, @{}", a1, a2, t) + } + &ArithmeticInstruction::IDiv(ref a1, ref a2, ref t) => { + write!(f, "idiv {}, {}, @{}", a1, a2, t) + } + &ArithmeticInstruction::Max(ref a1, ref a2, ref t) => { + write!(f, "max {}, {}, @{}", a1, a2, t) + } + &ArithmeticInstruction::Min(ref a1, ref a2, ref t) => { + write!(f, "min {}, {}, @{}", a1, a2, t) + } + &ArithmeticInstruction::IntFloorDiv(ref a1, ref a2, ref t) => { + write!(f, "int_floor_div {}, {}, @{}", a1, a2, t) + } + &ArithmeticInstruction::RDiv(ref a1, ref a2, ref t) => { + write!(f, "rdiv {}, {}, @{}", a1, a2, t) + } + &ArithmeticInstruction::Shl(ref a1, ref a2, ref t) => { + write!(f, "shl {}, {}, @{}", a1, a2, t) + } + &ArithmeticInstruction::Shr(ref a1, ref a2, ref t) => { + write!(f, "shr {}, {}, @{}", a1, a2, t) + } + &ArithmeticInstruction::Xor(ref a1, ref a2, ref t) => { + write!(f, "xor {}, {}, @{}", a1, a2, t) + } + &ArithmeticInstruction::And(ref a1, ref a2, ref t) => { + write!(f, "and {}, {}, @{}", a1, a2, t) + } + &ArithmeticInstruction::Or(ref a1, ref a2, ref t) => { + write!(f, "or {}, {}, @{}", a1, a2, t) + } + &ArithmeticInstruction::Mod(ref a1, ref a2, ref t) => { + write!(f, "mod {}, {}, @{}", a1, a2, t) + } + &ArithmeticInstruction::Rem(ref a1, ref a2, ref t) => { + write!(f, "rem {}, {}, @{}", a1, a2, t) + } + &ArithmeticInstruction::ATan2(ref a1, ref a2, ref t) => { + write!(f, "atan2 {}, {}, @{}", a1, a2, t) + } + &ArithmeticInstruction::Plus(ref a, ref t) => write!(f, "plus {}, @{}", a, t), + &ArithmeticInstruction::Neg(ref a, ref t) => write!(f, "neg {}, @{}", a, t), + &ArithmeticInstruction::Cos(ref a, ref t) => write!(f, "cos {}, @{}", a, t), + &ArithmeticInstruction::Sin(ref a, ref t) => write!(f, "sin {}, @{}", a, t), + &ArithmeticInstruction::Tan(ref a, ref t) => write!(f, "tan {}, @{}", a, t), + &ArithmeticInstruction::ATan(ref a, ref t) => write!(f, "atan {}, @{}", a, t), + &ArithmeticInstruction::ASin(ref a, ref t) => write!(f, "asin {}, @{}", a, t), + &ArithmeticInstruction::ACos(ref a, ref t) => write!(f, "acos {}, @{}", a, t), + &ArithmeticInstruction::Log(ref a, ref t) => write!(f, "log {}, @{}", a, t), + &ArithmeticInstruction::Exp(ref a, ref t) => write!(f, "exp {}, @{}", a, t), + &ArithmeticInstruction::Sqrt(ref a, ref t) => write!(f, "sqrt {}, @{}", a, t), + &ArithmeticInstruction::BitwiseComplement(ref a, ref t) => { + write!(f, "bitwise_complement {}, @{}", a, t) + } + &ArithmeticInstruction::Truncate(ref a, ref t) => write!(f, "truncate {}, @{}", a, t), + &ArithmeticInstruction::Round(ref a, ref t) => write!(f, "round {}, @{}", a, t), + &ArithmeticInstruction::Ceiling(ref a, ref t) => write!(f, "ceiling {}, @{}", a, t), + &ArithmeticInstruction::Floor(ref a, ref t) => write!(f, "floor {}, @{}", a, t), + &ArithmeticInstruction::Float(ref a, ref t) => write!(f, "float {}, @{}", a, t), } } } @@ -383,14 +381,10 @@ impl fmt::Display for ArithmeticInstruction { impl fmt::Display for CutInstruction { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - &CutInstruction::Cut(r) => - write!(f, "cut {}", r), - &CutInstruction::NeckCut => - write!(f, "neck_cut"), - &CutInstruction::GetLevel(r) => - write!(f, "get_level {}", r), - &CutInstruction::GetLevelAndUnify(r) => - write!(f, "get_level_and_unify {}", r) + &CutInstruction::Cut(r) => write!(f, "cut {}", r), + &CutInstruction::NeckCut => write!(f, "neck_cut"), + &CutInstruction::GetLevel(r) => write!(f, "get_level {}", r), + &CutInstruction::GetLevelAndUnify(r) => write!(f, "get_level_and_unify {}", r), } } } @@ -399,27 +393,23 @@ impl fmt::Display for Level { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { &Level::Root | &Level::Shallow => write!(f, "A"), - &Level::Deep => write!(f, "X") + &Level::Deep => write!(f, "X"), } } } pub enum ContinueResult { ContinueQuery, - Conclude + Conclude, } -pub -fn next_keypress() -> ContinueResult -{ +pub fn next_keypress() -> ContinueResult { let stdin = stdin(); for c in stdin.keys() { match c.unwrap() { - Key::Char(' ') | Key::Char(';') => - return ContinueResult::ContinueQuery, - Key::Char('.') => - return ContinueResult::Conclude, + Key::Char(' ') | Key::Char(';') => return ContinueResult::ContinueQuery, + Key::Char('.') => return ContinueResult::Conclude, _ => {} } } diff --git a/src/tests.rs b/src/tests.rs index c876921b..ef247436 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -1,11 +1,11 @@ use prolog_parser::ast::parsing_stream; use prolog::heap_print::*; -use prolog::machine::*; use prolog::machine::compile::*; use prolog::machine::machine_errors::*; use prolog::machine::machine_indices::*; use prolog::machine::toplevel::*; +use prolog::machine::*; use prolog::read::readline; use indexmap::IndexSet; @@ -16,7 +16,7 @@ use std::ops::{Range, RangeFrom}; pub struct TestOutputter { results: Vec>, contents: IndexSet, - focus: String + focus: String, } impl TestOutputter { @@ -34,9 +34,11 @@ impl HCValueOutputter for TestOutputter { type Output = Vec>; fn new() -> Self { - TestOutputter { results: vec![], - contents: IndexSet::new(), - focus: String::new() } + TestOutputter { + results: vec![], + contents: IndexSet::new(), + focus: String::new(), + } } fn append(&mut self, focus: &str) { @@ -85,8 +87,7 @@ impl HCValueOutputter for TestOutputter { } } -pub fn collect_test_output(wam: &mut Machine, alloc_locs: AllocVarDict) -> Vec> -{ +pub fn collect_test_output(wam: &mut Machine, alloc_locs: AllocVarDict) -> Vec> { let mut output = TestOutputter::new(); output = wam.test_heap_view(output); @@ -100,22 +101,23 @@ pub fn collect_test_output(wam: &mut Machine, alloc_locs: AllocVarDict) -> Vec Vec> -{ +pub fn collect_test_output_with_limit( + wam: &mut Machine, + alloc_locs: AllocVarDict, + limit: usize, +) -> Vec> { let mut output = TestOutputter::new(); output = wam.test_heap_view(output); output.cache(); - let mut count = 1; + let mut count = 1; if count == limit { return output.result(); } - while let EvalSession::SubsequentQuerySuccess = wam.continue_query(&alloc_locs) - { + while let EvalSession::SubsequentQuerySuccess = wam.continue_query(&alloc_locs) { output = wam.test_heap_view(output); output.cache(); @@ -130,68 +132,64 @@ pub fn collect_test_output_with_limit(wam: &mut Machine, alloc_locs: AllocVarDic } #[allow(dead_code)] -pub fn submit(wam: &mut Machine, buffer: &str) -> bool -{ +pub fn submit(wam: &mut Machine, buffer: &str) -> bool { wam.reset(); match submit_code(wam, buffer) { - EvalSession::InitialQuerySuccess(_) | - EvalSession::EntrySuccess | - EvalSession::SubsequentQuerySuccess => - true, - _ => false + EvalSession::InitialQuerySuccess(_) + | EvalSession::EntrySuccess + | EvalSession::SubsequentQuerySuccess => true, + _ => false, } } #[allow(dead_code)] -pub fn submit_query(wam: &mut Machine, buffer: &str, result: Vec>) -> bool -{ +pub fn submit_query(wam: &mut Machine, buffer: &str, result: Vec>) -> bool { wam.reset(); match stream_to_toplevel(parsing_stream(buffer.as_bytes()), wam) { - Ok(term) => - match compile_term(wam, term) { - EvalSession::InitialQuerySuccess(alloc_locs) => - result == collect_test_output(wam, alloc_locs), - EvalSession::EntrySuccess => true, - _ => false - }, - Err(_) => panic!("syntax error") + Ok(term) => match compile_term(wam, term) { + EvalSession::InitialQuerySuccess(alloc_locs) => { + result == collect_test_output(wam, alloc_locs) + } + EvalSession::EntrySuccess => true, + _ => false, + }, + Err(_) => panic!("syntax error"), } } #[allow(dead_code)] -pub fn submit_query_without_results(wam: &mut Machine, buffer: &str) -> bool -{ +pub fn submit_query_without_results(wam: &mut Machine, buffer: &str) -> bool { wam.reset(); match stream_to_toplevel(parsing_stream(buffer.as_bytes()), wam) { - Ok(term) => - match compile_term(wam, term) { - EvalSession::InitialQuerySuccess(..) - | EvalSession::EntrySuccess => true, - _ => false - }, - Err(_) => panic!("syntax error") + Ok(term) => match compile_term(wam, term) { + EvalSession::InitialQuerySuccess(..) | EvalSession::EntrySuccess => true, + _ => false, + }, + Err(_) => panic!("syntax error"), } } #[allow(dead_code)] -pub fn submit_query_with_limit(wam: &mut Machine, buffer: &str, - result: Vec>, limit: usize) - -> bool -{ +pub fn submit_query_with_limit( + wam: &mut Machine, + buffer: &str, + result: Vec>, + limit: usize, +) -> bool { wam.reset(); match stream_to_toplevel(parsing_stream(buffer.as_bytes()), wam) { - Ok(term) => - match compile_term(wam, term) { - EvalSession::InitialQuerySuccess(alloc_locs) => - result == collect_test_output_with_limit(wam, alloc_locs, limit), - EvalSession::EntrySuccess => true, - _ => false - }, - Err(_) => panic!("syntax_error") + Ok(term) => match compile_term(wam, term) { + EvalSession::InitialQuerySuccess(alloc_locs) => { + result == collect_test_output_with_limit(wam, alloc_locs, limit) + } + EvalSession::EntrySuccess => true, + _ => false, + }, + Err(_) => panic!("syntax_error"), } } @@ -202,9 +200,9 @@ pub fn submit_code(wam: &mut Machine, buf: &str) -> EvalSession { #[allow(unused_macros)] macro_rules! expand_strs { - ($arr:expr) => ( + ($arr:expr) => { $arr.into_iter().map(|s| String::from(*s)).collect() - ) + }; } #[allow(unused_macros)] @@ -216,9 +214,9 @@ macro_rules! assert_prolog_success_with_limit { #[allow(unused_macros)] macro_rules! assert_prolog_failure { - ($wam: expr, $buf: expr) => ( + ($wam: expr, $buf: expr) => { assert_eq!(submit_query_without_results($wam, $buf), false) - ) + }; } #[allow(unused_macros)] @@ -232,8 +230,7 @@ macro_rules! assert_prolog_success { } #[test] -fn test_queries_on_facts() -{ +fn test_queries_on_facts() { let mut wam = Machine::new(readline::input_stream()); submit(&mut wam, "p(Z, Z)."); @@ -262,7 +259,11 @@ fn test_queries_on_facts() submit(&mut wam, "p(f(X), h(Y, f(a)), Y)."); - assert_prolog_success!(&mut wam, "p(Z, h(Z, W), f(W)).", [["W = f(a)", "Z = f(f(a))"]]); + assert_prolog_success!( + &mut wam, + "p(Z, h(Z, W), f(W)).", + [["W = f(a)", "Z = f(f(a))"]] + ); } #[test] @@ -301,15 +302,27 @@ fn test_queries_on_rules() { submit(&mut wam, "p(f(f(a), g(b), X), g(b), h) :- q(X, Y)."); submit(&mut wam, "q(X, Y)."); - assert_prolog_success!(&mut wam, "p(f(X, Y, Z), g(b), h).", - [["Z = _3", "Y = g(b)", "X = f(a)"]]); + assert_prolog_success!( + &mut wam, + "p(f(X, Y, Z), g(b), h).", + [["Z = _3", "Y = g(b)", "X = f(a)"]] + ); assert_prolog_failure!(&mut wam, "p(f(X, g(Y), Z), g(Z), X)."); - assert_prolog_success!(&mut wam, "p(f(X, g(Y), Z), g(Z), h).", - [["Z = b", "Y = b", "X = f(a)"]]); - assert_prolog_success!(&mut wam, "p(Z, Y, X).", - [["X = h", "Y = g(b)", "Z = f(f(a),g(b),_7)"]]); - assert_prolog_success!(&mut wam, "p(f(X, Y, Z), Y, h).", - [["Y = g(b)", "Z = _3", "X = f(a)"]]); + assert_prolog_success!( + &mut wam, + "p(f(X, g(Y), Z), g(Z), h).", + [["Z = b", "Y = b", "X = f(a)"]] + ); + assert_prolog_success!( + &mut wam, + "p(Z, Y, X).", + [["X = h", "Y = g(b)", "Z = f(f(a),g(b),_7)"]] + ); + assert_prolog_success!( + &mut wam, + "p(f(X, Y, Z), Y, h).", + [["Y = g(b)", "Z = _3", "X = f(a)"]] + ); submit(&mut wam, "p(_, f(_, Y, _)) :- h(Y)."); submit(&mut wam, "h(y)."); @@ -326,19 +339,29 @@ fn test_queries_on_predicates() { submit(&mut wam, "p(X, a). p(b, X)."); assert_prolog_success!(&mut wam, "p(x, Y).", [["Y = a"]]); - assert_prolog_success!(&mut wam, "p(X, a).", [["X = _0"], // 1st case - ["X = b"]]); // 2nd case. - assert_prolog_success!(&mut wam, "p(b, X).", [["X = a"], // 1st case - ["X = _0"]]); // 2nd case. - assert_prolog_success!(&mut wam, "p(X, X).", [["X = a"], - ["X = b"]]); + assert_prolog_success!( + &mut wam, + "p(X, a).", + [ + ["X = _0"], // 1st case + ["X = b"] + ] + ); // 2nd case. + assert_prolog_success!( + &mut wam, + "p(b, X).", + [ + ["X = a"], // 1st case + ["X = _0"] + ] + ); // 2nd case. + assert_prolog_success!(&mut wam, "p(X, X).", [["X = a"], ["X = b"]]); assert_prolog_success!(&mut wam, "p(b, a)."); assert_prolog_failure!(&mut wam, "p(a, b)."); submit(&mut wam, "p(X, Y, a). p(X, a, Y). p(X, Y, a)."); - assert_prolog_success!(&mut wam, "p(c, d, X).", [["X = a"], - ["X = a"]]); + assert_prolog_success!(&mut wam, "p(c, d, X).", [["X = a"], ["X = a"]]); assert_prolog_success!(&mut wam, "p(a, a, a)."); assert_prolog_failure!(&mut wam, "p(b, c, d)."); @@ -351,47 +374,58 @@ fn test_queries_on_predicates() { submit(&mut wam, "q(z)."); - assert_prolog_success_with_limit!(&mut wam, "p(X, b).", [["X = a"], - ["X = a"], - ["X = a"]], - 3); + assert_prolog_success_with_limit!(&mut wam, "p(X, b).", [["X = a"], ["X = a"], ["X = a"]], 3); assert_prolog_success!(&mut wam, "p(x, a)."); - assert_prolog_success_with_limit!(&mut wam, "p(X, Y).", [["X = _0", "Y = a"], - ["Y = _1", "X = a"], - ["Y = _1", "X = a"]], - 3); + assert_prolog_success_with_limit!( + &mut wam, + "p(X, Y).", + [ + ["X = _0", "Y = a"], + ["Y = _1", "X = a"], + ["Y = _1", "X = a"] + ], + 3 + ); submit(&mut wam, "p(X, a). p(X, Y) :- q(Y), p(X, X)."); - assert_prolog_success_with_limit!(&mut wam, "p(X, Y).", [["X = _0", "Y = a"], - ["Y = z", "X = a"]], - 2); + assert_prolog_success_with_limit!( + &mut wam, + "p(X, Y).", + [["X = _0", "Y = a"], ["Y = z", "X = a"]], + 2 + ); assert_prolog_failure!(&mut wam, "p(X, b)."); submit(&mut wam, "p(a, z). p(X, Y) :- q(Y), p(X, Y)."); - assert_prolog_success_with_limit!(&mut wam, "p(X, Y).", [["X = a", "Y = z"], - ["X = a", "Y = z"]], - 2); + assert_prolog_success_with_limit!( + &mut wam, + "p(X, Y).", + [["X = a", "Y = z"], ["X = a", "Y = z"]], + 2 + ); - assert_prolog_success_with_limit!(&mut wam, "p(X, z).", [["X = a"], - ["X = a"]], - 2); + assert_prolog_success_with_limit!(&mut wam, "p(X, z).", [["X = a"], ["X = a"]], 2); assert_prolog_success!(&mut wam, "p(a, z)."); - assert_prolog_success_with_limit!(&mut wam, "p(a, X).", [["X = z"], - ["X = z"]], - 2); + assert_prolog_success_with_limit!(&mut wam, "p(a, X).", [["X = z"], ["X = z"]], 2); assert_prolog_failure!(&mut wam, "p(b, a)."); - submit(&mut wam, "p(X, Y, Z) :- q(X), r(Y), s(Z). - p(a, b, Z) :- q(Z)."); + submit( + &mut wam, + "p(X, Y, Z) :- q(X), r(Y), s(Z). + p(a, b, Z) :- q(Z).", + ); submit(&mut wam, "q(x)."); submit(&mut wam, "r(y)."); submit(&mut wam, "s(z)."); - assert_prolog_success!(&mut wam, "p(X, Y, Z).", [["Y = y", "X = x", "Z = z"], - ["Y = b", "X = a", "Z = x"]]); + assert_prolog_success!( + &mut wam, + "p(X, Y, Z).", + [["Y = y", "X = x", "Z = z"], ["Y = b", "X = a", "Z = x"]] + ); assert_prolog_failure!(&mut wam, "p(a, b, c)."); assert_prolog_success!(&mut wam, "p(a, b, C).", [["C = x"]]); @@ -401,88 +435,120 @@ fn test_queries_on_predicates() { submit(&mut wam, "s(x, t)."); submit(&mut wam, "t(y, u)."); - assert_prolog_success!(&mut wam, "p(X).", [["X = x"], - ["X = y"]]); + assert_prolog_success!(&mut wam, "p(X).", [["X = x"], ["X = y"]]); assert_prolog_success!(&mut wam, "p(x)."); assert_prolog_success!(&mut wam, "p(y)."); assert_prolog_failure!(&mut wam, "p(z)."); - submit(&mut wam, "p(f(f(X)), h(W), Y) :- g(W), h(W), f(X). - p(X, Y, Z) :- h(Y), g(W), z(Z)."); + submit( + &mut wam, + "p(f(f(X)), h(W), Y) :- g(W), h(W), f(X). + p(X, Y, Z) :- h(Y), g(W), z(Z).", + ); submit(&mut wam, "g(f(X)) :- z(X). g(X) :- h(X)."); submit(&mut wam, "h(w). h(x). h(z)."); submit(&mut wam, "f(s)."); submit(&mut wam, "z(Z)."); - assert_prolog_success!(&mut wam, "p(X, Y, Z).", [["Y = h(w)", "X = f(f(s))", "Z = _2"], - ["Y = h(x)", "X = f(f(s))", "Z = _2"], - ["Y = h(z)", "X = f(f(s))", "Z = _2"], - ["Y = w", "Z = _2", "X = _0"], - ["Y = w", "Z = _2", "X = _0"], - ["Y = w", "Z = _2", "X = _0"], - ["Y = w", "Z = _2", "X = _0"], - ["Y = x", "Z = _2", "X = _0"], - ["Y = x", "Z = _2", "X = _0"], - ["Y = x", "Z = _2", "X = _0"], - ["Y = x", "Z = _2", "X = _0"], - ["Y = z", "Z = _2", "X = _0"], - ["Y = z", "Z = _2", "X = _0"], - ["Y = z", "Z = _2", "X = _0"], - ["Y = z", "Z = _2", "X = _0"]]); - assert_prolog_success!(&mut wam, "p(X, X, Z).", [["Z = _1", "X = w"], - ["Z = _1", "X = w"], - ["Z = _1", "X = w"], - ["Z = _1", "X = w"], - ["Z = _1", "X = x"], - ["Z = _1", "X = x"], - ["Z = _1", "X = x"], - ["Z = _1", "X = x"], - ["Z = _1", "X = z"], - ["Z = _1", "X = z"], - ["Z = _1", "X = z"], - ["Z = _1", "X = z"]]); - assert_prolog_success!(&mut wam, "p(f(f(Z)), Y, Z).", [["Y = h(w)", "Z = s"], - ["Y = h(x)", "Z = s"], - ["Y = h(z)", "Z = s"], - ["Y = w", "Z = _1"], - ["Y = w", "Z = _1"], - ["Y = w", "Z = _1"], - ["Y = w", "Z = _1"], - ["Y = x", "Z = _1"], - ["Y = x", "Z = _1"], - ["Y = x", "Z = _1"], - ["Y = x", "Z = _1"], - ["Y = z", "Z = _1"], - ["Y = z", "Z = _1"], - ["Y = z", "Z = _1"], - ["Y = z", "Z = _1"]]); - assert_prolog_success!(&mut wam, "p(X, X, X).", [["X = w"], - ["X = w"], - ["X = w"], - ["X = w"], - ["X = x"], - ["X = x"], - ["X = x"], - ["X = x"], - ["X = z"], - ["X = z"], - ["X = z"], - ["X = z"]]); - assert_prolog_success!(&mut wam, "p(X, Y, X).", [["Y = h(w)", "X = f(f(s))"], - ["Y = h(x)", "X = f(f(s))"], - ["Y = h(z)", "X = f(f(s))"], - ["Y = w", "X = _0"], - ["Y = w", "X = _0"], - ["Y = w", "X = _0"], - ["Y = w", "X = _0"], - ["Y = x", "X = _0"], - ["Y = x", "X = _0"], - ["Y = x", "X = _0"], - ["Y = x", "X = _0"], - ["Y = z", "X = _0"], - ["Y = z", "X = _0"], - ["Y = z", "X = _0"], - ["Y = z", "X = _0"]]); + assert_prolog_success!( + &mut wam, + "p(X, Y, Z).", + [ + ["Y = h(w)", "X = f(f(s))", "Z = _2"], + ["Y = h(x)", "X = f(f(s))", "Z = _2"], + ["Y = h(z)", "X = f(f(s))", "Z = _2"], + ["Y = w", "Z = _2", "X = _0"], + ["Y = w", "Z = _2", "X = _0"], + ["Y = w", "Z = _2", "X = _0"], + ["Y = w", "Z = _2", "X = _0"], + ["Y = x", "Z = _2", "X = _0"], + ["Y = x", "Z = _2", "X = _0"], + ["Y = x", "Z = _2", "X = _0"], + ["Y = x", "Z = _2", "X = _0"], + ["Y = z", "Z = _2", "X = _0"], + ["Y = z", "Z = _2", "X = _0"], + ["Y = z", "Z = _2", "X = _0"], + ["Y = z", "Z = _2", "X = _0"] + ] + ); + assert_prolog_success!( + &mut wam, + "p(X, X, Z).", + [ + ["Z = _1", "X = w"], + ["Z = _1", "X = w"], + ["Z = _1", "X = w"], + ["Z = _1", "X = w"], + ["Z = _1", "X = x"], + ["Z = _1", "X = x"], + ["Z = _1", "X = x"], + ["Z = _1", "X = x"], + ["Z = _1", "X = z"], + ["Z = _1", "X = z"], + ["Z = _1", "X = z"], + ["Z = _1", "X = z"] + ] + ); + assert_prolog_success!( + &mut wam, + "p(f(f(Z)), Y, Z).", + [ + ["Y = h(w)", "Z = s"], + ["Y = h(x)", "Z = s"], + ["Y = h(z)", "Z = s"], + ["Y = w", "Z = _1"], + ["Y = w", "Z = _1"], + ["Y = w", "Z = _1"], + ["Y = w", "Z = _1"], + ["Y = x", "Z = _1"], + ["Y = x", "Z = _1"], + ["Y = x", "Z = _1"], + ["Y = x", "Z = _1"], + ["Y = z", "Z = _1"], + ["Y = z", "Z = _1"], + ["Y = z", "Z = _1"], + ["Y = z", "Z = _1"] + ] + ); + assert_prolog_success!( + &mut wam, + "p(X, X, X).", + [ + ["X = w"], + ["X = w"], + ["X = w"], + ["X = w"], + ["X = x"], + ["X = x"], + ["X = x"], + ["X = x"], + ["X = z"], + ["X = z"], + ["X = z"], + ["X = z"] + ] + ); + assert_prolog_success!( + &mut wam, + "p(X, Y, X).", + [ + ["Y = h(w)", "X = f(f(s))"], + ["Y = h(x)", "X = f(f(s))"], + ["Y = h(z)", "X = f(f(s))"], + ["Y = w", "X = _0"], + ["Y = w", "X = _0"], + ["Y = w", "X = _0"], + ["Y = w", "X = _0"], + ["Y = x", "X = _0"], + ["Y = x", "X = _0"], + ["Y = x", "X = _0"], + ["Y = x", "X = _0"], + ["Y = z", "X = _0"], + ["Y = z", "X = _0"], + ["Y = z", "X = _0"], + ["Y = z", "X = _0"] + ] + ); assert_prolog_failure!(&mut wam, "p(f(f(X)), h(f(X)), Y)."); submit(&mut wam, "p(X) :- f(Y), g(Y), i(X, Y)."); @@ -490,16 +556,20 @@ fn test_queries_on_predicates() { submit(&mut wam, "f(f(a)). f(f(b)). f(f(c))."); submit(&mut wam, "i(X, X)."); - assert_prolog_success!(&mut wam, "p(X).", [["X = f(a)"], - ["X = f(b)"], - ["X = f(c)"]]); + assert_prolog_success!( + &mut wam, + "p(X).", + [["X = f(a)"], ["X = f(b)"], ["X = f(c)"]] + ); submit(&mut wam, "p(X) :- f(f(Y)), g(Y, f(Y)), i(X, f(Y))."); submit(&mut wam, "g(Y, f(Y)) :- g(f(Y))."); - assert_prolog_success!(&mut wam, "p(X).", [["X = f(a)"], - ["X = f(b)"], - ["X = f(c)"]]); + assert_prolog_success!( + &mut wam, + "p(X).", + [["X = f(a)"], ["X = f(b)"], ["X = f(c)"]] + ); } #[test] @@ -507,15 +577,30 @@ fn test_queries_on_cuts() { let mut wam = Machine::new(readline::input_stream()); // test shallow cuts. - submit(&mut wam, "memberchk(X, [X|_]) :- !. - memberchk(X, [_|Xs]) :- memberchk(X, Xs)."); + submit( + &mut wam, + "memberchk(X, [X|_]) :- !. + memberchk(X, [_|Xs]) :- memberchk(X, Xs).", + ); assert_prolog_success!(&mut wam, "memberchk(X, [a,b,c]).", [["X = a"]]); - assert_prolog_success!(&mut wam, "memberchk([X,X], [a,b,c,[d,e],[d,d]]).", [["X = d"]]); - assert_prolog_success!(&mut wam, "memberchk([X,X], [a,b,c,[D,d],[e,e]]).", [["X = d", "D = d"]]); + assert_prolog_success!( + &mut wam, + "memberchk([X,X], [a,b,c,[d,e],[d,d]]).", + [["X = d"]] + ); + assert_prolog_success!( + &mut wam, + "memberchk([X,X], [a,b,c,[D,d],[e,e]]).", + [["X = d", "D = d"]] + ); assert_prolog_failure!(&mut wam, "memberchk([X,X], [a,b,c,[e,d],[f,e]])."); assert_prolog_failure!(&mut wam, "memberchk([X,X,Y], [a,b,c,[e,d],[f,e]])."); - assert_prolog_success!(&mut wam, "memberchk([X,X,Y], [a,b,c,[e,e,d],[f,e]]).", [["X = e", "Y = d"]]); + assert_prolog_success!( + &mut wam, + "memberchk([X,X,Y], [a,b,c,[e,e,d],[f,e]]).", + [["X = e", "Y = d"]] + ); // test deep cuts. submit(&mut wam, "commit :- a, !."); @@ -567,8 +652,7 @@ fn test_queries_on_cuts() { } #[test] -fn test_queries_on_lists() -{ +fn test_queries_on_lists() { let mut wam = Machine::new(readline::input_stream()); submit(&mut wam, "p([Z, W])."); @@ -598,29 +682,58 @@ fn test_queries_on_lists() assert_prolog_failure!(&mut wam, "p([Z | [W]])."); assert_prolog_success!(&mut wam, "p([Z | []]).", [["Z = _0"]]); - submit(&mut wam, "member(X, [X|_]). - member(X, [_|Xs]) :- member(X, Xs)."); + submit( + &mut wam, + "member(X, [X|_]). + member(X, [_|Xs]) :- member(X, Xs).", + ); assert_prolog_failure!(&mut wam, "member(a, [c, [X, Y]])."); assert_prolog_failure!(&mut wam, "member(c, [a, [X, Y]])."); assert_prolog_success!(&mut wam, "member(a, [a, [X, Y]]).", [["X = _2", "Y = _0"]]); - assert_prolog_success!(&mut wam, "member(a, [X, Y, Z]).", [["Y = _2", "X = a", "Z = _0"], - ["Y = a", "X = _4", "Z = _0"], - ["Y = _2", "X = _4", "Z = a"]]); - - assert_prolog_success!(&mut wam, "member([X, X], [a, [X, Y]]).", [["X = _0", "Y = _0"]]); - assert_prolog_success!(&mut wam, "member([X, X], [a, [b, c], [b, b], [Z, x], [d, f]]).", - [["Z = _14", "X = b"], - ["Z = x", "X = x"]]); - assert_prolog_failure!(&mut wam, "member([X, X], [a, [b, c], [b, d], [foo, x], [d, f]])."); - assert_prolog_success!(&mut wam, "member([X, Y], [a, [b, c], [b, b], [Z, x], [d, f]]).", - [["X = b", "Y = c", "Z = _14"], - ["X = b", "Y = b", "Z = _14"], - ["X = _2", "Y = x", "Z = _2"], - ["X = d", "Y = f", "Z = _14"]]); - assert_prolog_failure!(&mut wam, "member([X, Y, Y], [a, [b, c], [b, b], [Z, x], [d, f]])."); - assert_prolog_failure!(&mut wam, "member([X, Y, Z], [a, [b, c], [b, b], [Z, x], [d, f]])."); + assert_prolog_success!( + &mut wam, + "member(a, [X, Y, Z]).", + [ + ["Y = _2", "X = a", "Z = _0"], + ["Y = a", "X = _4", "Z = _0"], + ["Y = _2", "X = _4", "Z = a"] + ] + ); + + assert_prolog_success!( + &mut wam, + "member([X, X], [a, [X, Y]]).", + [["X = _0", "Y = _0"]] + ); + assert_prolog_success!( + &mut wam, + "member([X, X], [a, [b, c], [b, b], [Z, x], [d, f]]).", + [["Z = _14", "X = b"], ["Z = x", "X = x"]] + ); + assert_prolog_failure!( + &mut wam, + "member([X, X], [a, [b, c], [b, d], [foo, x], [d, f]])." + ); + assert_prolog_success!( + &mut wam, + "member([X, Y], [a, [b, c], [b, b], [Z, x], [d, f]]).", + [ + ["X = b", "Y = c", "Z = _14"], + ["X = b", "Y = b", "Z = _14"], + ["X = _2", "Y = x", "Z = _2"], + ["X = d", "Y = f", "Z = _14"] + ] + ); + assert_prolog_failure!( + &mut wam, + "member([X, Y, Y], [a, [b, c], [b, b], [Z, x], [d, f]])." + ); + assert_prolog_failure!( + &mut wam, + "member([X, Y, Z], [a, [b, c], [b, b], [Z, x], [d, f]])." + ); } #[test] @@ -636,138 +749,217 @@ fn test_queries_on_conjuctive_queries() { submit(&mut wam, "p(a, [f(g(X))])."); submit(&mut wam, "q(Y, c)."); - assert_prolog_success!(&mut wam, "p(X, Y), q(Y, Z).", [["Y = [f(g(_9))]", "X = a", "Z = c"]]); + assert_prolog_success!( + &mut wam, + "p(X, Y), q(Y, Z).", + [["Y = [f(g(_9))]", "X = a", "Z = c"]] + ); assert_prolog_failure!(&mut wam, "p(X, Y), q(Y, X)."); - submit(&mut wam, "member(X, [X|_]). - member(X, [_|Xs]) :- member(X, Xs)."); - - assert_prolog_success!(&mut wam, "member(X, [a,b,c]), member(X, [a,b,c]).", - [["X = a"], - ["X = b"], - ["X = c"]]); - assert_prolog_success!(&mut wam, "member(X, [a,b,c]), member(X, [b,c]).", - [["X = b"], - ["X = c"]]); - assert_prolog_success!(&mut wam, "member(X, [a,c]), member(X, [b,c]).", - [["X = c"]]); - assert_prolog_success!(&mut wam, "member(X, [a,b,c,d]), !, member(X, [a,d]).", - [["X = a"]]); + submit( + &mut wam, + "member(X, [X|_]). + member(X, [_|Xs]) :- member(X, Xs).", + ); + + assert_prolog_success!( + &mut wam, + "member(X, [a,b,c]), member(X, [a,b,c]).", + [["X = a"], ["X = b"], ["X = c"]] + ); + assert_prolog_success!( + &mut wam, + "member(X, [a,b,c]), member(X, [b,c]).", + [["X = b"], ["X = c"]] + ); + assert_prolog_success!(&mut wam, "member(X, [a,c]), member(X, [b,c]).", [["X = c"]]); + assert_prolog_success!( + &mut wam, + "member(X, [a,b,c,d]), !, member(X, [a,d]).", + [["X = a"]] + ); assert_prolog_failure!(&mut wam, "member(X, [a,b,c,d]), !, member(X, [e])."); - assert_prolog_success!(&mut wam, "member([X,X],[a,b,c,[d,d],[e,d]]), + assert_prolog_success!( + &mut wam, + "member([X,X],[a,b,c,[d,d],[e,d]]), member(X, [a,b,c,d,e,f,g]), member(Y, [X, a, b, c, d]).", - [["X = d", "Y = d"], - ["X = d", "Y = a"], - ["X = d", "Y = b"], - ["X = d", "Y = c"], - ["X = d", "Y = d"]]); + [ + ["X = d", "Y = d"], + ["X = d", "Y = a"], + ["X = d", "Y = b"], + ["X = d", "Y = c"], + ["X = d", "Y = d"] + ] + ); submit(&mut wam, "p(a, [f(g(X))]). p(X, c) :- c."); submit(&mut wam, "c."); submit(&mut wam, "q(Y, c)."); - assert_prolog_success!(&mut wam, "p(X, Y), q(Y, Z).", - [["X = a", "Z = c", "Y = [f(g(_9))]"], - ["X = _0", "Z = c", "Y = c"]]); - assert_prolog_success!(&mut wam, "p(X, Y), !, q(Y, Z).", - [["Z = c", "Y = [f(g(_9))]", "X = a"]]); - - submit(&mut wam, "q([f(g(x))], Z). q([f(g(y))], Y). q([f(g(z))], a)."); - - assert_prolog_success!(&mut wam, "p(X, Y), q(Y, Z).", - [["Z = _11", "X = a", "Y = [f(g(x))]"], - ["Z = _11", "X = a", "Y = [f(g(y))]"], - ["Z = a", "X = a", "Y = [f(g(z))]"]]); - assert_prolog_success!(&mut wam, "p(X, Y), !, q(Y, Z).", - [["X = a", "Y = [f(g(x))]", "Z = _11"], - ["X = a", "Y = [f(g(y))]", "Z = _11"], - ["X = a", "Y = [f(g(z))]", "Z = a"]]); - assert_prolog_success!(&mut wam, "p(X, Y), !, q(Y, X).", - [["X = a", "Y = [f(g(x))]"], - ["X = a", "Y = [f(g(y))]"], - ["X = a", "Y = [f(g(z))]"]]); - - submit(&mut wam, "p(X, [f(g(x))]). p(X, [f(g(y))]). p(X, [f(g(z))])."); + assert_prolog_success!( + &mut wam, + "p(X, Y), q(Y, Z).", + [ + ["X = a", "Z = c", "Y = [f(g(_9))]"], + ["X = _0", "Z = c", "Y = c"] + ] + ); + assert_prolog_success!( + &mut wam, + "p(X, Y), !, q(Y, Z).", + [["Z = c", "Y = [f(g(_9))]", "X = a"]] + ); + + submit( + &mut wam, + "q([f(g(x))], Z). q([f(g(y))], Y). q([f(g(z))], a).", + ); + + assert_prolog_success!( + &mut wam, + "p(X, Y), q(Y, Z).", + [ + ["Z = _11", "X = a", "Y = [f(g(x))]"], + ["Z = _11", "X = a", "Y = [f(g(y))]"], + ["Z = a", "X = a", "Y = [f(g(z))]"] + ] + ); + assert_prolog_success!( + &mut wam, + "p(X, Y), !, q(Y, Z).", + [ + ["X = a", "Y = [f(g(x))]", "Z = _11"], + ["X = a", "Y = [f(g(y))]", "Z = _11"], + ["X = a", "Y = [f(g(z))]", "Z = a"] + ] + ); + assert_prolog_success!( + &mut wam, + "p(X, Y), !, q(Y, X).", + [ + ["X = a", "Y = [f(g(x))]"], + ["X = a", "Y = [f(g(y))]"], + ["X = a", "Y = [f(g(z))]"] + ] + ); + + submit( + &mut wam, + "p(X, [f(g(x))]). p(X, [f(g(y))]). p(X, [f(g(z))]).", + ); assert_prolog_failure!(&mut wam, "q(f(X), Y), p(X, Y)."); - assert_prolog_success!(&mut wam, "q(X, Y), p(X, Y).", - [["Y = [f(g(x))]", "X = [f(g(x))]"], - ["Y = [f(g(y))]", "X = [f(g(x))]"], - ["Y = [f(g(z))]", "X = [f(g(x))]"], - ["Y = [f(g(x))]", "X = [f(g(y))]"], - ["Y = [f(g(y))]", "X = [f(g(y))]"], - ["Y = [f(g(z))]", "X = [f(g(y))]"]]); - assert_prolog_success!(&mut wam, "p(X, Y), q(X, Y).", - [["Y = [f(g(x))]", "X = [f(g(x))]"], - ["Y = [f(g(x))]", "X = [f(g(y))]"], - ["Y = [f(g(y))]", "X = [f(g(x))]"], - ["Y = [f(g(y))]", "X = [f(g(y))]"], - ["Y = [f(g(z))]", "X = [f(g(x))]"], - ["Y = [f(g(z))]", "X = [f(g(y))]"]]); - assert_prolog_success!(&mut wam, "p(X, Y), q(Y, X).", - [["Y = [f(g(x))]", "X = _10"], - ["Y = [f(g(y))]", "X = _10"], - ["Y = [f(g(z))]", "X = a"]]); - assert_prolog_success!(&mut wam, "q(X, Y), p(Y, X).", - [["Y = _9", "X = [f(g(x))]"], - ["Y = _9", "X = [f(g(y))]"], - ["Y = a" , "X = [f(g(z))]"]]); + assert_prolog_success!( + &mut wam, + "q(X, Y), p(X, Y).", + [ + ["Y = [f(g(x))]", "X = [f(g(x))]"], + ["Y = [f(g(y))]", "X = [f(g(x))]"], + ["Y = [f(g(z))]", "X = [f(g(x))]"], + ["Y = [f(g(x))]", "X = [f(g(y))]"], + ["Y = [f(g(y))]", "X = [f(g(y))]"], + ["Y = [f(g(z))]", "X = [f(g(y))]"] + ] + ); + assert_prolog_success!( + &mut wam, + "p(X, Y), q(X, Y).", + [ + ["Y = [f(g(x))]", "X = [f(g(x))]"], + ["Y = [f(g(x))]", "X = [f(g(y))]"], + ["Y = [f(g(y))]", "X = [f(g(x))]"], + ["Y = [f(g(y))]", "X = [f(g(y))]"], + ["Y = [f(g(z))]", "X = [f(g(x))]"], + ["Y = [f(g(z))]", "X = [f(g(y))]"] + ] + ); + assert_prolog_success!( + &mut wam, + "p(X, Y), q(Y, X).", + [ + ["Y = [f(g(x))]", "X = _10"], + ["Y = [f(g(y))]", "X = _10"], + ["Y = [f(g(z))]", "X = a"] + ] + ); + assert_prolog_success!( + &mut wam, + "q(X, Y), p(Y, X).", + [ + ["Y = _9", "X = [f(g(x))]"], + ["Y = _9", "X = [f(g(y))]"], + ["Y = a", "X = [f(g(z))]"] + ] + ); } #[test] -fn test_queries_on_call_n() -{ +fn test_queries_on_call_n() { let mut wam = Machine::new(readline::input_stream()); - submit(&mut wam, "maplist(_, []). - maplist(P, [X|Xs]) :- call(P, X), maplist(P, Xs)."); + submit( + &mut wam, + "maplist(_, []). + maplist(P, [X|Xs]) :- call(P, X), maplist(P, Xs).", + ); submit(&mut wam, "f(a). f(b). f(c)."); - assert_prolog_success!(&mut wam, "maplist(f, [X,Y,Z]).", - [["X = a", "Y = a", "Z = a"], - ["X = a", "Y = a", "Z = b"], - ["X = a", "Y = a", "Z = c"], - ["X = a", "Y = b", "Z = a"], - ["X = a", "Y = b", "Z = b"], - ["X = a", "Y = b", "Z = c"], - ["X = a", "Y = c", "Z = a"], - ["X = a", "Y = c", "Z = b"], - ["X = a", "Y = c", "Z = c"], - ["X = b", "Y = a", "Z = a"], - ["X = b", "Y = a", "Z = b"], - ["X = b", "Y = a", "Z = c"], - ["X = b", "Y = b", "Z = a"], - ["X = b", "Y = b", "Z = b"], - ["X = b", "Y = b", "Z = c"], - ["X = b", "Y = c", "Z = a"], - ["X = b", "Y = c", "Z = b"], - ["X = b", "Y = c", "Z = c"], - ["X = c", "Y = a", "Z = a"], - ["X = c", "Y = a", "Z = b"], - ["X = c", "Y = a", "Z = c"], - ["X = c", "Y = b", "Z = a"], - ["X = c", "Y = b", "Z = b"], - ["X = c", "Y = b", "Z = c"], - ["X = c", "Y = c", "Z = a"], - ["X = c", "Y = c", "Z = b"], - ["X = c", "Y = c", "Z = c"]]); - - assert_prolog_success!(&mut wam, "maplist(f, [a,Y,Z]).", - [["Y = a", "Z = a"], - ["Y = a", "Z = b"], - ["Y = a", "Z = c"], - ["Y = b", "Z = a"], - ["Y = b", "Z = b"], - ["Y = b", "Z = c"], - ["Y = c", "Z = a"], - ["Y = c", "Z = b"], - ["Y = c", "Z = c"]]); - - assert_prolog_success!(&mut wam, "maplist(f, [X,a,b]).", - [["X = a"], - ["X = b"], - ["X = c"]]); + assert_prolog_success!( + &mut wam, + "maplist(f, [X,Y,Z]).", + [ + ["X = a", "Y = a", "Z = a"], + ["X = a", "Y = a", "Z = b"], + ["X = a", "Y = a", "Z = c"], + ["X = a", "Y = b", "Z = a"], + ["X = a", "Y = b", "Z = b"], + ["X = a", "Y = b", "Z = c"], + ["X = a", "Y = c", "Z = a"], + ["X = a", "Y = c", "Z = b"], + ["X = a", "Y = c", "Z = c"], + ["X = b", "Y = a", "Z = a"], + ["X = b", "Y = a", "Z = b"], + ["X = b", "Y = a", "Z = c"], + ["X = b", "Y = b", "Z = a"], + ["X = b", "Y = b", "Z = b"], + ["X = b", "Y = b", "Z = c"], + ["X = b", "Y = c", "Z = a"], + ["X = b", "Y = c", "Z = b"], + ["X = b", "Y = c", "Z = c"], + ["X = c", "Y = a", "Z = a"], + ["X = c", "Y = a", "Z = b"], + ["X = c", "Y = a", "Z = c"], + ["X = c", "Y = b", "Z = a"], + ["X = c", "Y = b", "Z = b"], + ["X = c", "Y = b", "Z = c"], + ["X = c", "Y = c", "Z = a"], + ["X = c", "Y = c", "Z = b"], + ["X = c", "Y = c", "Z = c"] + ] + ); + + assert_prolog_success!( + &mut wam, + "maplist(f, [a,Y,Z]).", + [ + ["Y = a", "Z = a"], + ["Y = a", "Z = b"], + ["Y = a", "Z = c"], + ["Y = b", "Z = a"], + ["Y = b", "Z = b"], + ["Y = b", "Z = c"], + ["Y = c", "Z = a"], + ["Y = c", "Z = b"], + ["Y = c", "Z = c"] + ] + ); + + assert_prolog_success!( + &mut wam, + "maplist(f, [X,a,b]).", + [["X = a"], ["X = b"], ["X = c"]] + ); assert_prolog_success!(&mut wam, "maplist(f, [c,a,b])."); assert_prolog_failure!(&mut wam, "maplist(f, [d,e,f])."); assert_prolog_success!(&mut wam, "maplist(f, [])."); @@ -777,8 +969,7 @@ fn test_queries_on_call_n() submit(&mut wam, "p(x). p(y)."); assert_prolog_failure!(&mut wam, "f(p)."); - assert_prolog_success!(&mut wam, "f(p(X)).", [["X = x"], - ["X = y"]]); + assert_prolog_success!(&mut wam, "f(p(X)).", [["X = x"], ["X = y"]]); assert_prolog_success!(&mut wam, "f(p(x))."); assert_prolog_failure!(&mut wam, "f(p(w))."); assert_prolog_failure!(&mut wam, "f(p(X, Y))."); @@ -790,68 +981,82 @@ fn test_queries_on_call_n() submit(&mut wam, "f(P, X, Y) :- call(P, X), call(P, Y)."); - assert_prolog_success!(&mut wam, "f(p, X, Y).", [["Y = x", "X = x"], - ["Y = y", "X = x"], - ["Y = x", "X = y"], - ["Y = y", "X = y"]]); - assert_prolog_success!(&mut wam, "f(p, x, Y).", [["Y = x"], - ["Y = y"]]); - assert_prolog_success!(&mut wam, "f(p, X, y).", [["X = x"], - ["X = y"]]); + assert_prolog_success!( + &mut wam, + "f(p, X, Y).", + [ + ["Y = x", "X = x"], + ["Y = y", "X = x"], + ["Y = x", "X = y"], + ["Y = y", "X = y"] + ] + ); + assert_prolog_success!(&mut wam, "f(p, x, Y).", [["Y = x"], ["Y = y"]]); + assert_prolog_success!(&mut wam, "f(p, X, y).", [["X = x"], ["X = y"]]); assert_prolog_success!(&mut wam, "f(p, x, y)."); assert_prolog_failure!(&mut wam, "f(p, X, z)."); assert_prolog_failure!(&mut wam, "f(p, z, Y)."); - assert_prolog_success!(&mut wam, "call(p, X).", [["X = x"], - ["X = y"]]); + assert_prolog_success!(&mut wam, "call(p, X).", [["X = x"], ["X = y"]]); assert_prolog_success!(&mut wam, "call(p, x)."); assert_prolog_success!(&mut wam, "call(p, y)."); assert_prolog_failure!(&mut wam, "call(p, z)."); submit(&mut wam, "r(f(X)) :- p(X). r(g(Y)) :- p(Y)."); - assert_prolog_success!(&mut wam, "f(r, X, Y).", - [["X = f(x)", "Y = f(x)"], - ["X = f(x)", "Y = f(y)"], - ["X = f(x)", "Y = g(x)"], - ["X = f(x)", "Y = g(y)"], - ["X = f(y)", "Y = f(x)"], - ["X = f(y)", "Y = f(y)"], - ["X = f(y)", "Y = g(x)"], - ["X = f(y)", "Y = g(y)"], - ["X = g(x)", "Y = f(x)"], - ["X = g(x)", "Y = f(y)"], - ["X = g(x)", "Y = g(x)"], - ["X = g(x)", "Y = g(y)"], - ["X = g(y)", "Y = f(x)"], - ["X = g(y)", "Y = f(y)"], - ["X = g(y)", "Y = g(x)"], - ["X = g(y)", "Y = g(y)"]]); - assert_prolog_success!(&mut wam, "f(r, X, X).", - [["X = f(x)"], - ["X = f(y)"], - ["X = g(x)"], - ["X = g(y)"]]); - assert_prolog_success!(&mut wam, "f(r, f(X), g(Y)).", - [["X = x", "Y = x"], - ["X = x", "Y = y"], - ["X = y", "Y = x"], - ["X = y", "Y = y"]]); + assert_prolog_success!( + &mut wam, + "f(r, X, Y).", + [ + ["X = f(x)", "Y = f(x)"], + ["X = f(x)", "Y = f(y)"], + ["X = f(x)", "Y = g(x)"], + ["X = f(x)", "Y = g(y)"], + ["X = f(y)", "Y = f(x)"], + ["X = f(y)", "Y = f(y)"], + ["X = f(y)", "Y = g(x)"], + ["X = f(y)", "Y = g(y)"], + ["X = g(x)", "Y = f(x)"], + ["X = g(x)", "Y = f(y)"], + ["X = g(x)", "Y = g(x)"], + ["X = g(x)", "Y = g(y)"], + ["X = g(y)", "Y = f(x)"], + ["X = g(y)", "Y = f(y)"], + ["X = g(y)", "Y = g(x)"], + ["X = g(y)", "Y = g(y)"] + ] + ); + assert_prolog_success!( + &mut wam, + "f(r, X, X).", + [["X = f(x)"], ["X = f(y)"], ["X = g(x)"], ["X = g(y)"]] + ); + assert_prolog_success!( + &mut wam, + "f(r, f(X), g(Y)).", + [ + ["X = x", "Y = x"], + ["X = x", "Y = y"], + ["X = y", "Y = x"], + ["X = y", "Y = y"] + ] + ); assert_prolog_failure!(&mut wam, "f(r, j(X), h(Y))."); submit(&mut wam, "p(one, one). p(one, two). p(two, two)."); - assert_prolog_success!(&mut wam, "f(p(one), X, Y).", - [["X = one", "Y = one"], - ["X = one", "Y = two"], - ["X = two", "Y = one"], - ["X = two", "Y = two"]]); - assert_prolog_success!(&mut wam, "f(p(one), X, X).", - [["X = one"], - ["X = two"]]); - assert_prolog_success!(&mut wam, "f(p(one), one, Y).", - [["Y = one"], - ["Y = two"]]); + assert_prolog_success!( + &mut wam, + "f(p(one), X, Y).", + [ + ["X = one", "Y = one"], + ["X = one", "Y = two"], + ["X = two", "Y = one"], + ["X = two", "Y = two"] + ] + ); + assert_prolog_success!(&mut wam, "f(p(one), X, X).", [["X = one"], ["X = two"]]); + assert_prolog_success!(&mut wam, "f(p(one), one, Y).", [["Y = one"], ["Y = two"]]); assert_prolog_success!(&mut wam, "f(p(one), one, two)."); assert_prolog_failure!(&mut wam, "f(p(one), one, three)."); @@ -877,86 +1082,133 @@ fn test_queries_on_call_n() submit(&mut wam, "p(f(g(X)), compound, [lists,are,good])."); - assert_prolog_success!(&mut wam, "call(p(f(g(X))),Y,Z).", - [["Y = compound","Z = [lists,are,good]","X = _3"]]); + assert_prolog_success!( + &mut wam, + "call(p(f(g(X))),Y,Z).", + [["Y = compound", "Z = [lists,are,good]", "X = _3"]] + ); - submit(&mut wam, "david_lynch(coffee). + submit( + &mut wam, + "david_lynch(coffee). david_lynch(pie). - david_lynch(kyle(Film)) :- kyle(Film)."); + david_lynch(kyle(Film)) :- kyle(Film).", + ); - submit(&mut wam, "kyle(dune). + submit( + &mut wam, + "kyle(dune). kyle(blue_velvet). kyle(showgirls). - kyle(flintstones)."); - - assert_prolog_success!(&mut wam, "call(david_lynch,X).", - [["X = coffee"], - ["X = pie"], - ["X = kyle(dune)"], - ["X = kyle(blue_velvet)"], - ["X = kyle(showgirls)"], - ["X = kyle(flintstones)"]]); - assert_prolog_success!(&mut wam, "call(david_lynch,kyle(Film)).", - [["Film = dune"], - ["Film = blue_velvet"], - ["Film = showgirls"], - ["Film = flintstones"]]); + kyle(flintstones).", + ); + + assert_prolog_success!( + &mut wam, + "call(david_lynch,X).", + [ + ["X = coffee"], + ["X = pie"], + ["X = kyle(dune)"], + ["X = kyle(blue_velvet)"], + ["X = kyle(showgirls)"], + ["X = kyle(flintstones)"] + ] + ); + assert_prolog_success!( + &mut wam, + "call(david_lynch,kyle(Film)).", + [ + ["Film = dune"], + ["Film = blue_velvet"], + ["Film = showgirls"], + ["Film = flintstones"] + ] + ); assert_prolog_failure!(&mut wam, "call(david_lynch,kyle(Film),_)."); submit(&mut wam, "call_mult(P,X) :- call(call(P),X)."); - assert_prolog_success!(&mut wam, "call_mult(p(X),Y).", - [["Y = one","X = one"], - ["Y = two","X = one"], - ["Y = two","X = two"]]); - assert_prolog_success!(&mut wam, "call_mult(p(X),X).", - [["X = one"], - ["X = two"]]); - assert_prolog_success!(&mut wam, "call_mult(p(one),X).", - [["X = one"], - ["X = two"]]); - assert_prolog_success!(&mut wam, "call_mult(p(X),one).", - [["X = one"]]); + assert_prolog_success!( + &mut wam, + "call_mult(p(X),Y).", + [ + ["Y = one", "X = one"], + ["Y = two", "X = one"], + ["Y = two", "X = two"] + ] + ); + assert_prolog_success!(&mut wam, "call_mult(p(X),X).", [["X = one"], ["X = two"]]); + assert_prolog_success!(&mut wam, "call_mult(p(one),X).", [["X = one"], ["X = two"]]); + assert_prolog_success!(&mut wam, "call_mult(p(X),one).", [["X = one"]]); assert_prolog_failure!(&mut wam, "call_mult(p(two),one)."); assert_prolog_success!(&mut wam, "call_mult(p(two),two)."); - assert_prolog_success!(&mut wam, "call(call(p(one)),X),call(call(p(two)),two).", - [["X = one"], - ["X = two"]]); - assert_prolog_success!(&mut wam, "call(call(p(one,X))),call(call(p(two,two))).", - [["X = one"], - ["X = two"]]); + assert_prolog_success!( + &mut wam, + "call(call(p(one)),X),call(call(p(two)),two).", + [["X = one"], ["X = two"]] + ); + assert_prolog_success!( + &mut wam, + "call(call(p(one,X))),call(call(p(two,two))).", + [["X = one"], ["X = two"]] + ); assert_prolog_failure!(&mut wam, "call(call(p(one)),X),call(call(p(two)),one)."); - assert_prolog_success!(&mut wam, "call(call(p(X)),X),call(call(p(Y)),Y).", - [["X = one","Y = one"], - ["X = one","Y = two"], - ["X = two","Y = one"], - ["X = two","Y = two"]]); - assert_prolog_success!(&mut wam, "call(call(p(X)),Y),call(call(p(Y)),X).", - [["X = one","Y = one"], - ["X = two","Y = two"]]); - assert_prolog_success!(&mut wam, "call(call(p),X,Y),call(call(call(p)),X,Y).", - [["X = one","Y = one"], - ["Y = two","X = one"], - ["Y = two","X = two"]]); - assert_prolog_success!(&mut wam, "call(call(p),X,Y),call(call(call(p(X))),Y).", - [["X = one","Y = one"], - ["Y = two","X = one"], - ["Y = two","X = two"]]); + assert_prolog_success!( + &mut wam, + "call(call(p(X)),X),call(call(p(Y)),Y).", + [ + ["X = one", "Y = one"], + ["X = one", "Y = two"], + ["X = two", "Y = one"], + ["X = two", "Y = two"] + ] + ); + assert_prolog_success!( + &mut wam, + "call(call(p(X)),Y),call(call(p(Y)),X).", + [["X = one", "Y = one"], ["X = two", "Y = two"]] + ); + assert_prolog_success!( + &mut wam, + "call(call(p),X,Y),call(call(call(p)),X,Y).", + [ + ["X = one", "Y = one"], + ["Y = two", "X = one"], + ["Y = two", "X = two"] + ] + ); + assert_prolog_success!( + &mut wam, + "call(call(p),X,Y),call(call(call(p(X))),Y).", + [ + ["X = one", "Y = one"], + ["Y = two", "X = one"], + ["Y = two", "X = two"] + ] + ); assert_prolog_failure!(&mut wam, "call(call(p),X,Y),call(call(call(p(X))),X,Y)."); - assert_prolog_success!(&mut wam, "call(call(p),X,Y),call(call(call(p(X))),X).", - [["X = one","Y = one"], - ["Y = two","X = one"], - ["Y = two","X = two"]]); + assert_prolog_success!( + &mut wam, + "call(call(p),X,Y),call(call(call(p(X))),X).", + [ + ["X = one", "Y = one"], + ["Y = two", "X = one"], + ["Y = two", "X = two"] + ] + ); submit(&mut wam, "f(call(f,undefined)). f(undefined)."); submit(&mut wam, "call_var(P) :- P."); - assert_prolog_success!(&mut wam, "f(X),call_var(X).", - [["X = call(f,undefined)"]]); - assert_prolog_success!(&mut wam, "f(call(f,Q)),call_var(call(f,Q)).", - [["Q = undefined"]]); + assert_prolog_success!(&mut wam, "f(X),call_var(X).", [["X = call(f,undefined)"]]); + assert_prolog_success!( + &mut wam, + "f(call(f,Q)),call_var(call(f,Q)).", + [["Q = undefined"]] + ); assert_prolog_failure!(&mut wam, "call_var(call(undefined,Q))."); assert_prolog_failure!(&mut wam, "call(call)."); @@ -964,14 +1216,15 @@ fn test_queries_on_call_n() assert_prolog_failure!(&mut wam, "call(call(call(call)))."); assert_prolog_failure!(&mut wam, "call(call(call(call(call))))."); assert_prolog_failure!(&mut wam, "call(call(call(call(call(call)))))."); - assert_prolog_success!(&mut wam, "call(call(call(call(call(call(p(X))))))).", - [["X = x"], - ["X = y"]]); + assert_prolog_success!( + &mut wam, + "call(call(call(call(call(call(p(X))))))).", + [["X = x"], ["X = y"]] + ); } #[test] -fn test_queries_on_arithmetic() -{ +fn test_queries_on_arithmetic() { let mut wam = Machine::new(readline::input_stream()); assert_prolog_success!(&mut wam, "X is 1, X is X.", [["X = 1"]]); @@ -982,8 +1235,11 @@ fn test_queries_on_arithmetic() // assert_prolog_failure!(&mut wam, "X is 1 + a."); // assert_prolog_failure!(&mut wam, "X is 1 + Y."); - assert_prolog_success!(&mut wam, "Y is 2 + 2 - 2, X is 1 + Y, X = 3.", - [["X = 3", "Y = 2"]]); + assert_prolog_success!( + &mut wam, + "Y is 2 + 2 - 2, X is 1 + Y, X = 3.", + [["X = 3", "Y = 2"]] + ); assert_prolog_failure!(&mut wam, "Y is 2 + 2 - 2, X is 1 + Y, X = 2."); assert_prolog_success!(&mut wam, "6 is 6."); @@ -998,40 +1254,66 @@ fn test_queries_on_arithmetic() submit(&mut wam, "f(X) :- X is 5 // 0."); - assert_prolog_success!(&mut wam, "catch(f(X), error(evaluation_error(E), _), true), E = zero_divisor.", - [["E = zero_divisor", "X = _1"]]); + assert_prolog_success!( + &mut wam, + "catch(f(X), error(evaluation_error(E), _), true), E = zero_divisor.", + [["E = zero_divisor", "X = _1"]] + ); submit(&mut wam, "f(X) :- X is (5 rdiv 1) / 0."); - assert_prolog_success!(&mut wam, "catch(f(X), error(evaluation_error(E), _), true), E = zero_divisor.", - [["E = zero_divisor", "X = _1"]]); + assert_prolog_success!( + &mut wam, + "catch(f(X), error(evaluation_error(E), _), true), E = zero_divisor.", + [["E = zero_divisor", "X = _1"]] + ); submit(&mut wam, "f(X) :- X is 5.0 / 0."); - assert_prolog_success!(&mut wam, "catch(f(X), error(evaluation_error(E), _), true), E = zero_divisor.", - [["E = zero_divisor", "X = _1"]]); + assert_prolog_success!( + &mut wam, + "catch(f(X), error(evaluation_error(E), _), true), E = zero_divisor.", + [["E = zero_divisor", "X = _1"]] + ); - assert_prolog_success!(&mut wam, "X is ((3 + 4) // 2) + 2 - 1 // 1, Y is 2+2, Z is X+Y.", - [["Y = 4", "X = 4", "Z = 8"]]); + assert_prolog_success!( + &mut wam, + "X is ((3 + 4) // 2) + 2 - 1 // 1, Y is 2+2, Z is X+Y.", + [["Y = 4", "X = 4", "Z = 8"]] + ); - assert_prolog_success!(&mut wam, "X is ((3 + 4) // 2) + 2 - 1 // 1, Y is 2+2, Z = 8, Y is 4.", - [["Y = 4", "X = 4", "Z = 8"]]); + assert_prolog_success!( + &mut wam, + "X is ((3 + 4) // 2) + 2 - 1 // 1, Y is 2+2, Z = 8, Y is 4.", + [["Y = 4", "X = 4", "Z = 8"]] + ); - assert_prolog_success!(&mut wam, "X is (3 rdiv 4) / 2, Y is 3 rdiv 8.", - [["X = 0.375", "Y = 3/8"]]); + assert_prolog_success!( + &mut wam, + "X is (3 rdiv 4) / 2, Y is 3 rdiv 8.", + [["X = 0.375", "Y = 3/8"]] + ); assert_prolog_success!(&mut wam, "X is 10 xor -4, X is -10.", [["X = -10"]]); assert_prolog_success!(&mut wam, "X is 4 xor -7, X is -3.", [["X = -3"]]); assert_prolog_success!(&mut wam, "X is 10 xor 5 + 55, X = 70.", [["X = 70"]]); - assert_prolog_success!(&mut wam, "X is 10 rem -3, X = 1.", [["X = 1"]]); + assert_prolog_success!(&mut wam, "X is 10 rem -3, X = 1.", [["X = 1"]]); assert_prolog_success!(&mut wam, "X is 10 mod -3, X is -2.", [["X = -2"]]); assert_prolog_success!(&mut wam, "call(is, X, 3 + 4).", [["X = 7"]]); - assert_prolog_success!(&mut wam, "Y is 3 + 3, call(is, X, Y + 4).", [["Y = 6", "X = 10"]]); + assert_prolog_success!( + &mut wam, + "Y is 3 + 3, call(is, X, Y + 4).", + [["Y = 6", "X = 10"]] + ); assert_prolog_success!(&mut wam, "call(is, X, 3 + 4.5).", [["X = 7.5"]]); - assert_prolog_success!(&mut wam, "X is 2 rdiv 3, call(is, Y, X*X).", [["X = 2/3", "Y = 4/9"]]); + assert_prolog_success!( + &mut wam, + "X is 2 rdiv 3, call(is, Y, X*X).", + [["X = 2/3", "Y = 4/9"]] + ); assert_prolog_failure!(&mut wam, "call(>, 3, 3 + 3)."); assert_prolog_failure!(&mut wam, "X is 3 + 3, call(>, 3, X)."); @@ -1039,13 +1321,23 @@ fn test_queries_on_arithmetic() assert_prolog_success!(&mut wam, "X is 3 + 3, call(<, 3, X).", [["X = 6"]]); assert_prolog_success!(&mut wam, "X is 3 + 3, X =:= 3 + 3.", [["X = 6"]]); - assert_prolog_success!(&mut wam, "catch(call(is, X, 3 // 0), error(E, _), true).", - [["X = _5", "E = evaluation_error(zero_divisor)"]]); + assert_prolog_success!( + &mut wam, + "catch(call(is, X, 3 // 0), error(E, _), true).", + [["X = _5", "E = evaluation_error(zero_divisor)"]] + ); - assert_prolog_success!(&mut wam, "catch(call(is, X, 3 // 3), _, true).", [["X = 1"]]); + assert_prolog_success!( + &mut wam, + "catch(call(is, X, 3 // 3), _, true).", + [["X = 1"]] + ); - submit(&mut wam, "f(X, Sum) :- ( integer(X) -> Sum is X + X * X + 3 ; - var(X) -> Sum = 1, X = 1 )."); + submit( + &mut wam, + "f(X, Sum) :- ( integer(X) -> Sum is X + X * X + 3 ; + var(X) -> Sum = 1, X = 1 ).", + ); assert_prolog_success!(&mut wam, "f(X, Sum).", [["X = 1", "Sum = 1"]]); assert_prolog_success!(&mut wam, "f(5, Sum).", [["Sum = 33"]]); @@ -1059,99 +1351,111 @@ fn test_queries_on_arithmetic() submit(&mut wam, ":- op(900, xfx, ~)."); submit(&mut wam, "X ~ Y :- abs(X - Y) =< 1 rdiv 10000."); - assert_prolog_success!(&mut wam, "X is 3 ** 3.", - [["X = 27"]]); - assert_prolog_success!(&mut wam, "X is 3 ** 0.", - [["X = 1"]]); - assert_prolog_success!(&mut wam, "X is 3 ** -0.", - [["X = 1"]]); - assert_prolog_success!(&mut wam, "X is 3 ** 1.", - [["X = 3"]]); - assert_prolog_success!(&mut wam, "X is (-3) ** 3.", - [["X = -27"]]); - assert_prolog_success!(&mut wam, "X is (-3) ** 3.", - [["X = -27"]]); - assert_prolog_success!(&mut wam, "X is (-3) ** 0.", - [["X = 1"]]); - assert_prolog_success!(&mut wam, "X is (-3) ** -0.", - [["X = 1"]]); - assert_prolog_success!(&mut wam, "X is (-3) ** 1.", - [["X = -3"]]); -// assert_prolog_success!(&mut wam, "X is (1 rdiv 27) ** -3, X ~ 19683."); -// assert_prolog_success!(&mut wam, "X is (-1 rdiv 27) ** -3, X ~ -19683."); - - assert_prolog_success!(&mut wam, "X is 0.0 ** 0.", - [["X = 1.0"]]); - assert_prolog_success!(&mut wam, "catch(_ is 0.0 ** -2342, error(E, _), true).", - [["E = evaluation_error(undefined)"]]); - assert_prolog_success!(&mut wam, "X is 0.0 ** 2342.", - [["X = 0"]]); - - assert_prolog_success!(&mut wam, "catch(_ is (-3) ** (1 rdiv 2), error(E, _), true).", - [["E = evaluation_error(undefined)"]]); - assert_prolog_success!(&mut wam, "catch(_ is (-3/2) ** (1 rdiv 2), error(E, _), true).", - [["E = evaluation_error(undefined)"]]); - assert_prolog_success!(&mut wam, "catch(_ is (-3 rdiv 2) ** (1 rdiv 4), error(E, _), true).", - [["E = evaluation_error(undefined)"]]); - assert_prolog_success!(&mut wam, "catch(_ is (-3 rdiv 2) ** (-1 rdiv 4), error(E, _), true).", - [["E = evaluation_error(undefined)"]]); - assert_prolog_success!(&mut wam, "catch(_ is 0 ** (-5 rdiv 4), error(E, _), true).", - [["E = evaluation_error(undefined)"]]); + assert_prolog_success!(&mut wam, "X is 3 ** 3.", [["X = 27"]]); + assert_prolog_success!(&mut wam, "X is 3 ** 0.", [["X = 1"]]); + assert_prolog_success!(&mut wam, "X is 3 ** -0.", [["X = 1"]]); + assert_prolog_success!(&mut wam, "X is 3 ** 1.", [["X = 3"]]); + assert_prolog_success!(&mut wam, "X is (-3) ** 3.", [["X = -27"]]); + assert_prolog_success!(&mut wam, "X is (-3) ** 3.", [["X = -27"]]); + assert_prolog_success!(&mut wam, "X is (-3) ** 0.", [["X = 1"]]); + assert_prolog_success!(&mut wam, "X is (-3) ** -0.", [["X = 1"]]); + assert_prolog_success!(&mut wam, "X is (-3) ** 1.", [["X = -3"]]); + // assert_prolog_success!(&mut wam, "X is (1 rdiv 27) ** -3, X ~ 19683."); + // assert_prolog_success!(&mut wam, "X is (-1 rdiv 27) ** -3, X ~ -19683."); + + assert_prolog_success!(&mut wam, "X is 0.0 ** 0.", [["X = 1.0"]]); + assert_prolog_success!( + &mut wam, + "catch(_ is 0.0 ** -2342, error(E, _), true).", + [["E = evaluation_error(undefined)"]] + ); + assert_prolog_success!(&mut wam, "X is 0.0 ** 2342.", [["X = 0"]]); + + assert_prolog_success!( + &mut wam, + "catch(_ is (-3) ** (1 rdiv 2), error(E, _), true).", + [["E = evaluation_error(undefined)"]] + ); + assert_prolog_success!( + &mut wam, + "catch(_ is (-3/2) ** (1 rdiv 2), error(E, _), true).", + [["E = evaluation_error(undefined)"]] + ); + assert_prolog_success!( + &mut wam, + "catch(_ is (-3 rdiv 2) ** (1 rdiv 4), error(E, _), true).", + [["E = evaluation_error(undefined)"]] + ); + assert_prolog_success!( + &mut wam, + "catch(_ is (-3 rdiv 2) ** (-1 rdiv 4), error(E, _), true).", + [["E = evaluation_error(undefined)"]] + ); + assert_prolog_success!( + &mut wam, + "catch(_ is 0 ** (-5 rdiv 4), error(E, _), true).", + [["E = evaluation_error(undefined)"]] + ); assert_prolog_success!(&mut wam, "X is 3 ** (1 rdiv 3), Y is X ** 3, Y ~ 3."); -// assert_prolog_success!(&mut wam, "X is (-3) ** (1 rdiv 3), Y is X ** 3, Y ~ -3."); -// assert_prolog_failure!(&mut wam, "X is (-5) ** (1 rdiv 3), Y is X ** 3, Y ~ -3."); + // assert_prolog_success!(&mut wam, "X is (-3) ** (1 rdiv 3), Y is X ** 3, Y ~ -3."); + // assert_prolog_failure!(&mut wam, "X is (-5) ** (1 rdiv 3), Y is X ** 3, Y ~ -3."); assert_prolog_success!(&mut wam, "X is 5 ** (1 rdiv 3), Y is X ** 3, Y ~ 5."); - assert_prolog_success!(&mut wam, "X is (1 rdiv 3) ** 0.5, Y is X ** 2, 1 rdiv 3 ~ Y."); - -// assert_prolog_success!(&mut wam, "X is (-5) ** (-1 rdiv 3), Y is X ** 3, Y ~ -1 rdiv 5."); -// assert_prolog_failure!(&mut wam, "X is (-5) ** (-1 rdiv 3), Y is X ** 3, Y ~ 1 rdiv 5."); - - assert_prolog_success!(&mut wam, "X is (0 rdiv 5) ** 5.", - [["X = 0"]]); - assert_prolog_success!(&mut wam, "X is (-0 rdiv 5) ** 5.", - [["X = 0"]]); - assert_prolog_success!(&mut wam, "X is (0 rdiv 5) ** 0.", - [["X = 1.0"]]); - assert_prolog_success!(&mut wam, "catch(_ is (0 rdiv 0) ** 5, error(E, _), true).", - [["E = evaluation_error(zero_divisor)"]]); + assert_prolog_success!( + &mut wam, + "X is (1 rdiv 3) ** 0.5, Y is X ** 2, 1 rdiv 3 ~ Y." + ); + + // assert_prolog_success!(&mut wam, "X is (-5) ** (-1 rdiv 3), Y is X ** 3, Y ~ -1 rdiv 5."); + // assert_prolog_failure!(&mut wam, "X is (-5) ** (-1 rdiv 3), Y is X ** 3, Y ~ 1 rdiv 5."); + + assert_prolog_success!(&mut wam, "X is (0 rdiv 5) ** 5.", [["X = 0"]]); + assert_prolog_success!(&mut wam, "X is (-0 rdiv 5) ** 5.", [["X = 0"]]); + assert_prolog_success!(&mut wam, "X is (0 rdiv 5) ** 0.", [["X = 1.0"]]); + assert_prolog_success!( + &mut wam, + "catch(_ is (0 rdiv 0) ** 5, error(E, _), true).", + [["E = evaluation_error(zero_divisor)"]] + ); } #[test] -fn test_queries_on_exceptions() -{ +fn test_queries_on_exceptions() { let mut wam = Machine::new(readline::input_stream()); submit(&mut wam, "f(a). f(_) :- throw(stuff)."); submit(&mut wam, "handle(stuff)."); - assert_prolog_success!(&mut wam, "catch(f(X), E, handle(E)).", - [["E = _2", "X = a"], - ["E = stuff", "X = _1"]]); + assert_prolog_success!( + &mut wam, + "catch(f(X), E, handle(E)).", + [["E = _2", "X = a"], ["E = stuff", "X = _1"]] + ); submit(&mut wam, "f(a). f(X) :- g(X)."); submit(&mut wam, "g(x). g(y). g(z)."); submit(&mut wam, "handle(x). handle(y)."); - assert_prolog_success!(&mut wam, "catch(f(X), X, handle(X)).", - [["X = a"], - ["X = x"], - ["X = y"], - ["X = z"]]); - assert_prolog_success!(&mut wam, "catch(f(a), _, handle(X)).", - [["X = _4"]]); + assert_prolog_success!( + &mut wam, + "catch(f(X), X, handle(X)).", + [["X = a"], ["X = x"], ["X = y"], ["X = z"]] + ); + assert_prolog_success!(&mut wam, "catch(f(a), _, handle(X)).", [["X = _4"]]); assert_prolog_failure!(&mut wam, "catch(f(b), _, handle(X))."); submit(&mut wam, "g(x). g(X) :- throw(x)."); - assert_prolog_success!(&mut wam, "catch(f(X), x, handle(X)).", - [["X = a"], - ["X = x"], - ["X = x"], - ["X = y"]]); - assert_prolog_success!(&mut wam, "catch(f(X), x, handle(z)).", - [["X = a"], - ["X = x"]]); + assert_prolog_success!( + &mut wam, + "catch(f(X), x, handle(X)).", + [["X = a"], ["X = x"], ["X = x"], ["X = y"]] + ); + assert_prolog_success!( + &mut wam, + "catch(f(X), x, handle(z)).", + [["X = a"], ["X = x"]] + ); assert_prolog_success!(&mut wam, "catch(f(z), x, handle(x))."); assert_prolog_success!(&mut wam, "catch(f(z), x, handle(y))."); assert_prolog_failure!(&mut wam, "catch(f(z), x, handle(z))."); @@ -1160,25 +1464,39 @@ fn test_queries_on_exceptions() submit(&mut wam, "handle(stuff). handle(other_stuff)."); // the first 3 cases should deterministically succeed. - assert_prolog_success!(&mut wam, "catch(f(X), E, handle(E)).", - [["X = _1", "E = stuff"]]); - assert_prolog_success!(&mut wam, "catch(f(X), E, handle(stuff)).", - [["X = _1", "E = stuff"]]); - assert_prolog_success!(&mut wam, "catch(f(X), E, handle(other_stuff)).", - [["X = _1", "E = stuff"]]); + assert_prolog_success!( + &mut wam, + "catch(f(X), E, handle(E)).", + [["X = _1", "E = stuff"]] + ); + assert_prolog_success!( + &mut wam, + "catch(f(X), E, handle(stuff)).", + [["X = _1", "E = stuff"]] + ); + assert_prolog_success!( + &mut wam, + "catch(f(X), E, handle(other_stuff)).", + [["X = _1", "E = stuff"]] + ); assert_prolog_failure!(&mut wam, "catch(f(X), E, handle(not_stuff))."); submit(&mut wam, "f(success). f(X) :- catch(g(X), E, handle(E))."); submit(&mut wam, "g(g_success). g(g_success_2). g(X) :- throw(X)."); submit(&mut wam, "handle(x). handle(y). handle(z)."); - assert_prolog_success!(&mut wam, "catch(f(X), E, E).", - [["X = success", "E = _2"], - ["X = g_success", "E = _2"], - ["X = g_success_2", "E = _2"], - ["X = _1", "E = _2"], - ["X = _1", "E = _2"], - ["X = _1", "E = _2"]]); + assert_prolog_success!( + &mut wam, + "catch(f(X), E, E).", + [ + ["X = success", "E = _2"], + ["X = g_success", "E = _2"], + ["X = g_success_2", "E = _2"], + ["X = _1", "E = _2"], + ["X = _1", "E = _2"], + ["X = _1", "E = _2"] + ] + ); assert_prolog_failure!(&mut wam, "catch(f(fail), _, _)."); assert_prolog_success!(&mut wam, "catch(f(x), _, _)."); assert_prolog_success!(&mut wam, "catch(f(y), _, _)."); @@ -1186,40 +1504,64 @@ fn test_queries_on_exceptions() submit(&mut wam, "f(success). f(E) :- catch(g(E), E, handle(E))."); submit(&mut wam, "g(g_success). g(g_success_2). g(X) :- throw(X)."); - submit(&mut wam, "handle(x). handle(y). handle(z). handle(v) :- throw(X)."); + submit( + &mut wam, + "handle(x). handle(y). handle(z). handle(v) :- throw(X).", + ); - assert_prolog_success!(&mut wam, "catch(f(X), E, E).", - [["X = success", "E = _2"], - ["X = g_success", "E = _2"], - ["X = g_success_2", "E = _2"], - ["X = x", "E = _2"], - ["X = y", "E = _2"], - ["X = z", "E = _2"]]); + assert_prolog_success!( + &mut wam, + "catch(f(X), E, E).", + [ + ["X = success", "E = _2"], + ["X = g_success", "E = _2"], + ["X = g_success_2", "E = _2"], + ["X = x", "E = _2"], + ["X = y", "E = _2"], + ["X = z", "E = _2"] + ] + ); - submit(&mut wam, "handle(x). handle(y). handle(z). handle(v) :- throw(handle_top(X))."); + submit( + &mut wam, + "handle(x). handle(y). handle(z). handle(v) :- throw(handle_top(X)).", + ); submit(&mut wam, "handle_top(an_error_1). handle_top(an_error_2)."); - assert_prolog_success!(&mut wam, "catch(f(X), E, E).", - [["X = success", "E = _2"], - ["X = g_success", "E = _2"], - ["X = g_success_2", "E = _2"], - ["X = x", "E = _2"], - ["X = y", "E = _2"], - ["X = z", "E = _2"], - ["X = _1", "E = handle_top(an_error_1)"], - ["X = _1", "E = handle_top(an_error_2)"]]); - - submit(&mut wam, "handle(x). handle(y). handle(z). handle(v) :- throw(X)."); - - assert_prolog_success!(&mut wam, "catch(f(X), E, handle_top(E)).", - [["X = success", "E = _2"], - ["X = g_success", "E = _2"], - ["X = g_success_2", "E = _2"], - ["X = x", "E = _2"], - ["X = y", "E = _2"], - ["X = z", "E = _2"], - ["E = an_error_1", "X = _1"], - ["E = an_error_2", "X = _1"]]); + assert_prolog_success!( + &mut wam, + "catch(f(X), E, E).", + [ + ["X = success", "E = _2"], + ["X = g_success", "E = _2"], + ["X = g_success_2", "E = _2"], + ["X = x", "E = _2"], + ["X = y", "E = _2"], + ["X = z", "E = _2"], + ["X = _1", "E = handle_top(an_error_1)"], + ["X = _1", "E = handle_top(an_error_2)"] + ] + ); + + submit( + &mut wam, + "handle(x). handle(y). handle(z). handle(v) :- throw(X).", + ); + + assert_prolog_success!( + &mut wam, + "catch(f(X), E, handle_top(E)).", + [ + ["X = success", "E = _2"], + ["X = g_success", "E = _2"], + ["X = g_success_2", "E = _2"], + ["X = x", "E = _2"], + ["X = y", "E = _2"], + ["X = z", "E = _2"], + ["E = an_error_1", "X = _1"], + ["E = an_error_2", "X = _1"] + ] + ); } #[test] @@ -1227,97 +1569,162 @@ fn test_queries_on_skip_max_list() { let mut wam = Machine::new(readline::input_stream()); // test on proper and empty lists. - assert_prolog_success!(&mut wam, "'$skip_max_list'(N,5,[],Xs).", - [["Xs = []","N = 0"]]); - assert_prolog_success!(&mut wam, "'$skip_max_list'(N,5,[a,b,c],Xs).", - [["Xs = []","N = 3"]]); - assert_prolog_success!(&mut wam, "'$skip_max_list'(N,2,[a,b,c],Xs).", - [["Xs = [c]","N = 2"]]); - assert_prolog_success!(&mut wam, "'$skip_max_list'(N,3,[a,b,c],Xs).", - [["Xs = []","N = 3"]]); - - assert_prolog_success!(&mut wam, "'$skip_max_list'(N,0,[],Xs).", - [["Xs = []","N = 0"]]); - assert_prolog_success!(&mut wam, "'$skip_max_list'(N,0,[a,b,c],Xs).", - [["Xs = [a,b,c]","N = 0"]]); - assert_prolog_success!(&mut wam, "'$skip_max_list'(N,0,[a,b,c],Xs).", - [["Xs = [a,b,c]","N = 0"]]); - assert_prolog_success!(&mut wam, "'$skip_max_list'(N,0,[a,b,c],Xs).", - [["Xs = [a,b,c]","N = 0"]]); + assert_prolog_success!( + &mut wam, + "'$skip_max_list'(N,5,[],Xs).", + [["Xs = []", "N = 0"]] + ); + assert_prolog_success!( + &mut wam, + "'$skip_max_list'(N,5,[a,b,c],Xs).", + [["Xs = []", "N = 3"]] + ); + assert_prolog_success!( + &mut wam, + "'$skip_max_list'(N,2,[a,b,c],Xs).", + [["Xs = [c]", "N = 2"]] + ); + assert_prolog_success!( + &mut wam, + "'$skip_max_list'(N,3,[a,b,c],Xs).", + [["Xs = []", "N = 3"]] + ); + + assert_prolog_success!( + &mut wam, + "'$skip_max_list'(N,0,[],Xs).", + [["Xs = []", "N = 0"]] + ); + assert_prolog_success!( + &mut wam, + "'$skip_max_list'(N,0,[a,b,c],Xs).", + [["Xs = [a,b,c]", "N = 0"]] + ); + assert_prolog_success!( + &mut wam, + "'$skip_max_list'(N,0,[a,b,c],Xs).", + [["Xs = [a,b,c]", "N = 0"]] + ); + assert_prolog_success!( + &mut wam, + "'$skip_max_list'(N,0,[a,b,c],Xs).", + [["Xs = [a,b,c]", "N = 0"]] + ); assert_prolog_failure!(&mut wam, "'$skip_max_list'(4,0,[],Xs)."); assert_prolog_failure!(&mut wam, "'$skip_max_list'(3,0,[a,b,c],Xs)."); assert_prolog_failure!(&mut wam, "'$skip_max_list'(2,0,[a,b,c],Xs)."); assert_prolog_failure!(&mut wam, "'$skip_max_list'(1,0,[a,b,c],Xs)."); - assert_prolog_success!(&mut wam, "'$skip_max_list'(0,5,[],Xs).", - [["Xs = []"]]); - assert_prolog_success!(&mut wam, "'$skip_max_list'(3,5,[a,b,c],Xs).", - [["Xs = []"]]); - assert_prolog_success!(&mut wam, "'$skip_max_list'(2,2,[a,b,c],Xs).", - [["Xs = [c]"]]); - assert_prolog_success!(&mut wam, "'$skip_max_list'(3,3,[a,b,c],Xs).", - [["Xs = []"]]); + assert_prolog_success!(&mut wam, "'$skip_max_list'(0,5,[],Xs).", [["Xs = []"]]); + assert_prolog_success!(&mut wam, "'$skip_max_list'(3,5,[a,b,c],Xs).", [["Xs = []"]]); + assert_prolog_success!( + &mut wam, + "'$skip_max_list'(2,2,[a,b,c],Xs).", + [["Xs = [c]"]] + ); + assert_prolog_success!(&mut wam, "'$skip_max_list'(3,3,[a,b,c],Xs).", [["Xs = []"]]); // tests on proper and empty lists with no max. // test on proper and empty lists. - assert_prolog_success!(&mut wam, "'$skip_max_list'(N,-1,[],Xs).", - [["Xs = []","N = 0"]]); - assert_prolog_success!(&mut wam, "'$skip_max_list'(N,-1,[a,b,c],Xs).", - [["Xs = []","N = 3"]]); + assert_prolog_success!( + &mut wam, + "'$skip_max_list'(N,-1,[],Xs).", + [["Xs = []", "N = 0"]] + ); + assert_prolog_success!( + &mut wam, + "'$skip_max_list'(N,-1,[a,b,c],Xs).", + [["Xs = []", "N = 3"]] + ); - assert_prolog_success!(&mut wam, "'$skip_max_list'(N,-1,[],Xs).", - [["Xs = []","N = 0"]]); + assert_prolog_success!( + &mut wam, + "'$skip_max_list'(N,-1,[],Xs).", + [["Xs = []", "N = 0"]] + ); assert_prolog_failure!(&mut wam, "'$skip_max_list'(4,-1,[],Xs)."); - assert_prolog_success!(&mut wam, "'$skip_max_list'(3,-1,[a,b,c],Xs).", - [["Xs = []"]]); + assert_prolog_success!( + &mut wam, + "'$skip_max_list'(3,-1,[a,b,c],Xs).", + [["Xs = []"]] + ); - assert_prolog_success!(&mut wam, "'$skip_max_list'(0,-1,[],Xs).", - [["Xs = []"]]); - assert_prolog_success!(&mut wam, "'$skip_max_list'(3,-1,[a,b,c],Xs).", - [["Xs = []"]]); + assert_prolog_success!(&mut wam, "'$skip_max_list'(0,-1,[],Xs).", [["Xs = []"]]); + assert_prolog_success!( + &mut wam, + "'$skip_max_list'(3,-1,[a,b,c],Xs).", + [["Xs = []"]] + ); // tests on partial lists. - assert_prolog_success!(&mut wam, "'$skip_max_list'(3,4,[a,b,c|X],Xs0).", - [["X = _1","Xs0 = _1"]]); - assert_prolog_success!(&mut wam, "'$skip_max_list'(3,3,[a,b,c|X],Xs0).", - [["X = _1","Xs0 = _1"]]); + assert_prolog_success!( + &mut wam, + "'$skip_max_list'(3,4,[a,b,c|X],Xs0).", + [["X = _1", "Xs0 = _1"]] + ); + assert_prolog_success!( + &mut wam, + "'$skip_max_list'(3,3,[a,b,c|X],Xs0).", + [["X = _1", "Xs0 = _1"]] + ); assert_prolog_failure!(&mut wam, "'$skip_max_list'(3,2,[a,b,c|X],Xs0)."); assert_prolog_failure!(&mut wam, "'$skip_max_list'(3,1,[a,b,c|X],Xs0)."); assert_prolog_failure!(&mut wam, "'$skip_max_list'(3,0,[a,b,c|X],Xs0)."); // tests on cyclic lists. assert_prolog_failure!(&mut wam, "Xs = [a,b|Xs],'$skip_max_list'(3,5,X,Xs0)."); - assert_prolog_failure!(&mut wam, "X = [a,b|Y],Y = [c,d|X],'$skip_max_list'(4,5,X,Xs0)."); - assert_prolog_failure!(&mut wam, "X = [a,b|Y],Y = [c,d|X],'$skip_max_list'(4,3,X,Xs0)."); + assert_prolog_failure!( + &mut wam, + "X = [a,b|Y],Y = [c,d|X],'$skip_max_list'(4,5,X,Xs0)." + ); + assert_prolog_failure!( + &mut wam, + "X = [a,b|Y],Y = [c,d|X],'$skip_max_list'(4,3,X,Xs0)." + ); // tests on non lists. - assert_prolog_success!(&mut wam, "'$skip_max_list'(N,9,non_list,Xs).", - [["Xs = non_list","N = 0"]]); + assert_prolog_success!( + &mut wam, + "'$skip_max_list'(N,9,non_list,Xs).", + [["Xs = non_list", "N = 0"]] + ); } #[test] -fn test_queries_on_conditionals() -{ +fn test_queries_on_conditionals() { let mut wam = Machine::new(readline::input_stream()); - submit(&mut wam, "test(A) :- ( A =:= 2 -> writeq(\"A is 2\") + submit( + &mut wam, + "test(A) :- ( A =:= 2 -> writeq(\"A is 2\") ; A =:= 3 -> writeq(\"A is 3\") ; A = \"not 2 or 3\" - )."); + ).", + ); - assert_prolog_success!(&mut wam, "catch(test(A), error(instantiation_error, _), true)."); + assert_prolog_success!( + &mut wam, + "catch(test(A), error(instantiation_error, _), true)." + ); assert_prolog_success!(&mut wam, "A = 2, test(A).", [["A = 2"]]); - assert_prolog_success!(&mut wam, "A = 3, test(A), B = 3, test(B).", [["A = 3", "B = 3"]]); + assert_prolog_success!( + &mut wam, + "A = 3, test(A), B = 3, test(B).", + [["A = 3", "B = 3"]] + ); submit(&mut wam, "f(a). f(b)."); submit(&mut wam, "g(1). g(2). g(3)."); - submit(&mut wam, "typed_dispatch(X) :- ( var(X) -> f(X) + submit( + &mut wam, + "typed_dispatch(X) :- ( var(X) -> f(X) ; integer(X) -> g(X) - ; atomic(X))."); + ; atomic(X)).", + ); assert_prolog_success!(&mut wam, "typed_dispatch(X).", [["X = a"], ["X = b"]]); assert_prolog_success!(&mut wam, "typed_dispatch(a)."); @@ -1331,11 +1738,16 @@ fn test_queries_on_conditionals() assert_prolog_failure!(&mut wam, "typed_dispatch(compound(term))."); submit(&mut wam, "f(a). f(b). f(compound(term))."); - submit(&mut wam, "g(X, Y) :- f(X), (atomic(X) -> X = a ; X = a ; X = compound(Y))."); + submit( + &mut wam, + "g(X, Y) :- f(X), (atomic(X) -> X = a ; X = a ; X = compound(Y)).", + ); - assert_prolog_success!(&mut wam, "g(X, Y).", - [["Y = _1", "X = a"], - ["Y = term", "X = compound(term)"]]); + assert_prolog_success!( + &mut wam, + "g(X, Y).", + [["Y = _1", "X = a"], ["Y = term", "X = compound(term)"]] + ); assert_prolog_success!(&mut wam, "g(X, X).", [["X = a"]]); assert_prolog_success!(&mut wam, "g(compound(X), X).", [["X = term"]]); @@ -1343,7 +1755,10 @@ fn test_queries_on_conditionals() assert_prolog_success!(&mut wam, "g(a, _)."); assert_prolog_success!(&mut wam, "g(X, _), X = a.", [["X = a"]]); - submit(&mut wam, "g(X) :- var(X) -> (var(X) -> X is 3 + 3 ; X = not_6)."); + submit( + &mut wam, + "g(X) :- var(X) -> (var(X) -> X is 3 + 3 ; X = not_6).", + ); assert_prolog_success!(&mut wam, "g(X).", [["X = 6"]]); assert_prolog_failure!(&mut wam, "g(1)."); @@ -1352,57 +1767,86 @@ fn test_queries_on_conditionals() assert_prolog_success!(&mut wam, "f(X), (g(Y), !).", [["X = a", "Y = 6"]]); - submit(&mut wam, "test(X, [X]) :- (atomic(X) -> true ; throw(type_error(atomic_expected, X))). - test(_, _)."); + submit( + &mut wam, + "test(X, [X]) :- (atomic(X) -> true ; throw(type_error(atomic_expected, X))). + test(_, _).", + ); - assert_prolog_success!(&mut wam, "catch(test(a, [a]), type_error(E), true).", - [["E = _6"], ["E = _6"]]); + assert_prolog_success!( + &mut wam, + "catch(test(a, [a]), type_error(E), true).", + [["E = _6"], ["E = _6"]] + ); - assert_prolog_success!(&mut wam, "f(X), call(->, atomic(X), true).", - [["X = a"], ["X = b"]]); + assert_prolog_success!( + &mut wam, + "f(X), call(->, atomic(X), true).", + [["X = a"], ["X = b"]] + ); } #[test] -fn test_queries_on_modules() -{ +fn test_queries_on_modules() { let mut wam = Machine::new(readline::input_stream()); submit(&mut wam, ":- use_module('src/prolog/lib/lists.pl')."); - submit_code(&mut wam, " + submit_code( + &mut wam, + " :- module(my_lists, [local_member/2, reverse/2]). :- use_module('src/prolog/lib/lists.pl', [member/2]). local_member(X, Xs) :- member(X, Xs). -reverse(Xs, Ys) :- lists:reverse(Xs, Ys)."); +reverse(Xs, Ys) :- lists:reverse(Xs, Ys).", + ); assert_prolog_success!(&mut wam, "my_lists:local_member(1, [1,2,3])."); assert_prolog_success!(&mut wam, "my_lists:reverse([a,b,c], [c,b,a])."); - submit_code(&mut wam, " + submit_code( + &mut wam, + " :- module(my_lists_2, [local_member/2]). -:- use_module(library(my_lists), [local_member/2])."); +:- use_module(library(my_lists), [local_member/2]).", + ); assert_prolog_success!(&mut wam, "my_lists_2:local_member(1, [1,2,3])."); - assert_prolog_success!(&mut wam, "catch(local_member(X, Xs), error(E, _), true).", - [["X = _1", "E = existence_error(procedure,local_member/2)", "Xs = _2"]]); + assert_prolog_success!( + &mut wam, + "catch(local_member(X, Xs), error(E, _), true).", + [[ + "X = _1", + "E = existence_error(procedure,local_member/2)", + "Xs = _2" + ]] + ); - submit(&mut wam, ":- use_module('src/prolog/lib/lists.pl', [reverse/2])."); + submit( + &mut wam, + ":- use_module('src/prolog/lib/lists.pl', [reverse/2]).", + ); - assert_prolog_success!(&mut wam, "catch(member(_, _), error(existence_error(procedure, P), _), true).", - [["P = member/2"]]); + assert_prolog_success!( + &mut wam, + "catch(member(_, _), error(existence_error(procedure, P), _), true).", + [["P = member/2"]] + ); assert_prolog_success!(&mut wam, "reverse(_, _)."); submit(&mut wam, ":- use_module('src/prolog/lib/lists.pl', [])."); - assert_prolog_success!(&mut wam, "catch(reverse(_, _), error(existence_error(procedure, P), _), true).", - [["P = reverse/2"]]); + assert_prolog_success!( + &mut wam, + "catch(reverse(_, _), error(existence_error(procedure, P), _), true).", + [["P = reverse/2"]] + ); } #[test] -fn test_queries_on_builtins() -{ +fn test_queries_on_builtins() { let mut wam = Machine::new(readline::input_stream()); submit(&mut wam, ":- use_module('src/prolog/lib/lists.pl')."); @@ -1435,19 +1879,24 @@ fn test_queries_on_builtins() assert_prolog_success!(&mut wam, "arg(3, f(a,b,c,d), Arg).", [["Arg = c"]]); assert_prolog_success!(&mut wam, "arg(4, f(a,b,c,d), Arg).", [["Arg = d"]]); - assert_prolog_success!(&mut wam, "catch(arg(N, f, Arg), error(E, _), true).", - [["E = instantiation_error", "Arg = _3", "N = _1"]]); + assert_prolog_success!( + &mut wam, + "catch(arg(N, f, Arg), error(E, _), true).", + [["E = instantiation_error", "Arg = _3", "N = _1"]] + ); assert_prolog_failure!(&mut wam, "arg(N, f(arg, arg, arg), not_arg)."); assert_prolog_failure!(&mut wam, "arg(1, f(arg, not_arg, not_arg), not_arg)."); assert_prolog_success!(&mut wam, "arg(2, f(arg, not_arg, not_arg), not_arg)."); assert_prolog_success!(&mut wam, "arg(3, f(arg, not_arg, not_arg), not_arg)."); - assert_prolog_success!(&mut wam, "functor(f(a,b,c), F, Arity).", - [["F = f", "Arity = 3"]]); + assert_prolog_success!( + &mut wam, + "functor(f(a,b,c), F, Arity).", + [["F = f", "Arity = 3"]] + ); - assert_prolog_success!(&mut wam, "functor(f(a,b,c), F, N).", - [["F = f", "N = 3"]]); + assert_prolog_success!(&mut wam, "functor(f(a,b,c), F, N).", [["F = f", "N = 3"]]); assert_prolog_failure!(&mut wam, "functor(f(a,b,c), g, N)."); assert_prolog_success!(&mut wam, "functor(f(a,b,c), F, 3).", [["F = f"]]); assert_prolog_failure!(&mut wam, "functor(f(a,b,c), F, 4)."); @@ -1455,15 +1904,24 @@ fn test_queries_on_builtins() assert_prolog_success!(&mut wam, "functor(F, f, 0).", [["F = f"]]); - assert_prolog_success!(&mut wam, "functor(Func,f,3).",[["Func = f(_2,_3,_4)"]]); - assert_prolog_success!(&mut wam, "functor(Func,f,4).",[["Func = f(_2,_3,_4,_5)"]]); + assert_prolog_success!(&mut wam, "functor(Func,f,3).", [["Func = f(_2,_3,_4)"]]); + assert_prolog_success!(&mut wam, "functor(Func,f,4).", [["Func = f(_2,_3,_4,_5)"]]); - assert_prolog_success!(&mut wam, "catch(functor(F,\"sdf\",3),error(E,_),true).", - [["E = type_error(atom,[s,d,f])","F = _1"]]); - assert_prolog_success!(&mut wam, "catch(functor(Func,F,3),error(E,_),true).", - [["E = instantiation_error","Func = _1","F = _2"]]); - assert_prolog_success!(&mut wam, "catch(functor(Func,f,N),error(E,_),true).", - [["E = instantiation_error","Func = _1","N = _3"]]); + assert_prolog_success!( + &mut wam, + "catch(functor(F,\"sdf\",3),error(E,_),true).", + [["E = type_error(atom,[s,d,f])", "F = _1"]] + ); + assert_prolog_success!( + &mut wam, + "catch(functor(Func,F,3),error(E,_),true).", + [["E = instantiation_error", "Func = _1", "F = _2"]] + ); + assert_prolog_success!( + &mut wam, + "catch(functor(Func,f,N),error(E,_),true).", + [["E = instantiation_error", "Func = _1", "N = _3"]] + ); assert_prolog_failure!(&mut wam, "catch(functor(Func,f,N),error(E,_),false)."); assert_prolog_success!(&mut wam, "X is 3,call(integer,X)."); @@ -1471,57 +1929,98 @@ fn test_queries_on_builtins() assert_prolog_success!(&mut wam, "X is 3 + 3.5,\\+ call(integer,X)."); assert_prolog_success!(&mut wam, "X is 3 + 3.5,\\+ integer(X)."); - assert_prolog_success!(&mut wam, "Func =.. [atom].",[["Func = atom"]]); - assert_prolog_success!(&mut wam, "Func =.. [\"sdf\"].",[["Func = [s,d,f]"]]); - assert_prolog_success!(&mut wam, "Func =.. [1].",[["Func = 1"]]); - assert_prolog_success!(&mut wam, "catch(Func =.. [1,2],error(type_error(atom,1),_),true)."); - assert_prolog_success!(&mut wam, "f(1,2,3) =.. List.",[["List = [f,1,2,3]"]]); + assert_prolog_success!(&mut wam, "Func =.. [atom].", [["Func = atom"]]); + assert_prolog_success!(&mut wam, "Func =.. [\"sdf\"].", [["Func = [s,d,f]"]]); + assert_prolog_success!(&mut wam, "Func =.. [1].", [["Func = 1"]]); + assert_prolog_success!( + &mut wam, + "catch(Func =.. [1,2],error(type_error(atom,1),_),true)." + ); + assert_prolog_success!(&mut wam, "f(1,2,3) =.. List.", [["List = [f,1,2,3]"]]); assert_prolog_success!(&mut wam, "f(1,2,3) =.. [f,1,2,3]."); assert_prolog_failure!(&mut wam, "f(1,2,3) =.. [f,1]."); assert_prolog_failure!(&mut wam, "f(1,2,3) =.. [g,1,2,3]."); - assert_prolog_success!(&mut wam, "f(1,2,3) =.. [f,X,Y,Z].", - [["X = 1","Y = 2","Z = 3"]]); - - assert_prolog_success!(&mut wam, "length([a,b,c],N).",[["N = 3"]]); - assert_prolog_success_with_limit!(&mut wam, "length(Xs,N).", - [["N = 0","Xs = []"], - ["N = 1","Xs = [_4]"], - ["N = 2","Xs = [_4,_8]"], - ["N = 3","Xs = [_4,_8,_12]"], - ["N = 4","Xs = [_4,_8,_12,_16]"], - ["N = 5","Xs = [_4,_8,_12,_16,_20]"]], - 6); - - assert_prolog_success!(&mut wam, "length(Xs,3).",[["Xs = [_5,_9,_13]"]]); - assert_prolog_success!(&mut wam, "length([],N).",[["N = 0"]]); - assert_prolog_success!(&mut wam, "length(Xs,0).",[["Xs = []"]]); + assert_prolog_success!( + &mut wam, + "f(1,2,3) =.. [f,X,Y,Z].", + [["X = 1", "Y = 2", "Z = 3"]] + ); + + assert_prolog_success!(&mut wam, "length([a,b,c],N).", [["N = 3"]]); + assert_prolog_success_with_limit!( + &mut wam, + "length(Xs,N).", + [ + ["N = 0", "Xs = []"], + ["N = 1", "Xs = [_4]"], + ["N = 2", "Xs = [_4,_8]"], + ["N = 3", "Xs = [_4,_8,_12]"], + ["N = 4", "Xs = [_4,_8,_12,_16]"], + ["N = 5", "Xs = [_4,_8,_12,_16,_20]"] + ], + 6 + ); + + assert_prolog_success!(&mut wam, "length(Xs,3).", [["Xs = [_5,_9,_13]"]]); + assert_prolog_success!(&mut wam, "length([],N).", [["N = 0"]]); + assert_prolog_success!(&mut wam, "length(Xs,0).", [["Xs = []"]]); assert_prolog_success!(&mut wam, "length([a,b,[a,b,c]],3)."); assert_prolog_failure!(&mut wam, "length([a,b,[a,b,c]],2)."); - assert_prolog_success!(&mut wam, "catch(length(a,[]),error(E,_),true).", - [["E = type_error(integer,[])"]]); + assert_prolog_success!( + &mut wam, + "catch(length(a,[]),error(E,_),true).", + [["E = type_error(integer,[])"]] + ); - assert_prolog_success!(&mut wam, "copy_term([1,2,3],[X,Y,Z]).", - [["Z = 3","Y = 2","X = 1"]]); - assert_prolog_success!(&mut wam, "copy_term(f(X,[a],Z),f(X,Y,Z)).", - [["X = _3","Y = [a]","Z = _5"]]); + assert_prolog_success!( + &mut wam, + "copy_term([1,2,3],[X,Y,Z]).", + [["Z = 3", "Y = 2", "X = 1"]] + ); + assert_prolog_success!( + &mut wam, + "copy_term(f(X,[a],Z),f(X,Y,Z)).", + [["X = _3", "Y = [a]", "Z = _5"]] + ); assert_prolog_failure!(&mut wam, "copy_term(g(X),f(X))."); - assert_prolog_success!(&mut wam, "copy_term(f(X),f(X)).", - [["X = _1"]]); - assert_prolog_success!(&mut wam, "copy_term([[[[X,Y],Y],X]],Term).", - [["Term = [[[[_22,_26],_26],_22]]","X = _2","Y = _0"]]); - assert_prolog_success!(&mut wam, "copy_term([X,[Y,[X]]],Term).", - [["Term = [_12,[_16,[_12]]]","X = _0","Y = _4"]]); + assert_prolog_success!(&mut wam, "copy_term(f(X),f(X)).", [["X = _1"]]); + assert_prolog_success!( + &mut wam, + "copy_term([[[[X,Y],Y],X]],Term).", + [["Term = [[[[_22,_26],_26],_22]]", "X = _2", "Y = _0"]] + ); + assert_prolog_success!( + &mut wam, + "copy_term([X,[Y,[X]]],Term).", + [["Term = [_12,[_16,[_12]]]", "X = _0", "Y = _4"]] + ); // test copy_term on cyclic terms. assert_prolog_failure!(&mut wam, "X = g(X,Y),Y = f(X),copy_term(Y,g(Z))."); - assert_prolog_success!(&mut wam, "X = g(X,Y),Y = f(X),copy_term(Y,f(Z)).", - [["Y = f(g(X,Y))","X = g(X,f(X))","Z = g(Z,f(Z))"]]); - assert_prolog_success!(&mut wam, "X = g(X,Y),Y = f(X),copy_term(Y,V).", - [["V = f(g(g(g(...,V),V),V))","X = g(X,f(X))","Y = f(g(X,Y))"]]); - assert_prolog_success!(&mut wam, "f(Y,Y,[X,a,[],Y]) = Term,copy_term(Term,NewTerm).", - [["NewTerm = f(_16,_16,[_19,a,[],_16])", - "Term = f(_0,Y,[_6,a,[],Y])", - "X = _6","Y = _0"]]); + assert_prolog_success!( + &mut wam, + "X = g(X,Y),Y = f(X),copy_term(Y,f(Z)).", + [["Y = f(g(X,Y))", "X = g(X,f(X))", "Z = g(Z,f(Z))"]] + ); + assert_prolog_success!( + &mut wam, + "X = g(X,Y),Y = f(X),copy_term(Y,V).", + [[ + "V = f(g(g(g(...,V),V),V))", + "X = g(X,f(X))", + "Y = f(g(X,Y))" + ]] + ); + assert_prolog_success!( + &mut wam, + "f(Y,Y,[X,a,[],Y]) = Term,copy_term(Term,NewTerm).", + [[ + "NewTerm = f(_16,_16,[_19,a,[],_16])", + "Term = f(_0,Y,[_6,a,[],Y])", + "X = _6", + "Y = _0" + ]] + ); assert_prolog_success!(&mut wam, "float(3.14159269)."); assert_prolog_failure!(&mut wam, "float(3)."); @@ -1574,7 +2073,10 @@ fn test_queries_on_builtins() assert_prolog_failure!(&mut wam, "B = f(A),ground(B)."); assert_prolog_failure!(&mut wam, "B = f(A),ground(A)."); - assert_prolog_success!(&mut wam, "ground(x),ground(f(x)),X = f(x),ground(g(f(X),[a,b]))."); + assert_prolog_success!( + &mut wam, + "ground(x),ground(f(x)),X = f(x),ground(g(f(X),[a,b]))." + ); assert_prolog_success!(&mut wam, "A = f(A),g(A,B) == g(f(A),B)."); assert_prolog_failure!(&mut wam, "A = f(A),g(A,B) == g(f(A),b)."); @@ -1612,7 +2114,7 @@ fn test_queries_on_builtins() assert_prolog_success!(&mut wam, "1 @=< 1.0."); submit(&mut wam, ":- use_module('src/prolog/lib/non_iso.pl')."); - + assert_prolog_success!(&mut wam, "variant(X, Y)."); assert_prolog_failure!(&mut wam, "variant(f(X), f(x))."); assert_prolog_success!(&mut wam, "variant(X, X)."); @@ -1622,192 +2124,327 @@ fn test_queries_on_builtins() assert_prolog_success!(&mut wam, "variant([X,Y,X], [V,W,V])."); assert_prolog_success!(&mut wam, "g(B) = B, g(A) = A, variant(A, B)."); - assert_prolog_success!(&mut wam, "keysort([1-1,1-1],Sorted).", - [["Sorted = [1-1,1-1]"]]); - assert_prolog_success!(&mut wam, "keysort([2-99,1-a,3-f(_),1-z,1-a,2-44],Sorted).", - [["Sorted = [1-a,1-z,1-a,2-99,2-44,3-f(_7)]"]]); - assert_prolog_success!(&mut wam, "keysort([X-1,1-1],[2-1,1-1]).", - [["X = 2"]]); + assert_prolog_success!( + &mut wam, + "keysort([1-1,1-1],Sorted).", + [["Sorted = [1-1,1-1]"]] + ); + assert_prolog_success!( + &mut wam, + "keysort([2-99,1-a,3-f(_),1-z,1-a,2-44],Sorted).", + [["Sorted = [1-a,1-z,1-a,2-99,2-44,3-f(_7)]"]] + ); + assert_prolog_success!(&mut wam, "keysort([X-1,1-1],[2-1,1-1]).", [["X = 2"]]); assert_prolog_failure!(&mut wam, "Pairs = [a-a|Pairs],keysort(Pairs,_)."); - assert_prolog_success!(&mut wam, "Pairs = [a-a|Pairs],catch(keysort(Pairs,_),error(E,_),true).", - [["E = type_error(list,[a-a,a-a,a-a|...])","Pairs = [a-a|Pairs]"]]); - - assert_prolog_success!(&mut wam, "keysort([],L).", - [["L = []"]]); - assert_prolog_success!(&mut wam, "catch(keysort([a|_],_),error(E,_),true).", - [["E = instantiation_error"]]); - assert_prolog_success!(&mut wam, "catch(keysort([],[a|a]),error(Pat,_),true).", - [["Pat = type_error(list,[a|a])"]]); - assert_prolog_success!(&mut wam, "catch(keysort(_,_),error(E,_),true).", - [["E = type_error(list,_16)"]]); - assert_prolog_success!(&mut wam, "catch(keysort([a-1],[_|b]),error(E,_),true).", - [["E = type_error(list,[_27|b])"]]); - assert_prolog_success!(&mut wam, "catch(keysort([a-1],[a-b,c-d,a]),error(E,_),true).", - [["E = type_error(pair,a)"]]); - assert_prolog_success!(&mut wam, "catch(keysort([a],[a-b]),error(E,_),true).", - [["E = type_error(pair,a)"]]); - - assert_prolog_success!(&mut wam, "catch(sort([a|_],_),error(E,_),true).", - [["E = instantiation_error"]]); - assert_prolog_success!(&mut wam, "catch(sort([],[a|a]),error(Pat,_),true).", - [["Pat = type_error(list,[a|a])"]]); - assert_prolog_success!(&mut wam, "sort([],L).", - [["L = []"]]); - assert_prolog_success!(&mut wam, "catch(sort(_,[]),error(E,_),true).", - [["E = type_error(list,_16)"]]); - assert_prolog_success!(&mut wam, "catch(sort([a,b,c],not_a_list),error(E,_),true).", - [["E = type_error(list,not_a_list)"]]); - - assert_prolog_success!(&mut wam, "call(((G = 2 ; fail),B=3,!)).", - [["G = 2","B = 3"]]); + assert_prolog_success!( + &mut wam, + "Pairs = [a-a|Pairs],catch(keysort(Pairs,_),error(E,_),true).", + [[ + "E = type_error(list,[a-a,a-a,a-a|...])", + "Pairs = [a-a|Pairs]" + ]] + ); + + assert_prolog_success!(&mut wam, "keysort([],L).", [["L = []"]]); + assert_prolog_success!( + &mut wam, + "catch(keysort([a|_],_),error(E,_),true).", + [["E = instantiation_error"]] + ); + assert_prolog_success!( + &mut wam, + "catch(keysort([],[a|a]),error(Pat,_),true).", + [["Pat = type_error(list,[a|a])"]] + ); + assert_prolog_success!( + &mut wam, + "catch(keysort(_,_),error(E,_),true).", + [["E = type_error(list,_16)"]] + ); + assert_prolog_success!( + &mut wam, + "catch(keysort([a-1],[_|b]),error(E,_),true).", + [["E = type_error(list,[_27|b])"]] + ); + assert_prolog_success!( + &mut wam, + "catch(keysort([a-1],[a-b,c-d,a]),error(E,_),true).", + [["E = type_error(pair,a)"]] + ); + assert_prolog_success!( + &mut wam, + "catch(keysort([a],[a-b]),error(E,_),true).", + [["E = type_error(pair,a)"]] + ); + + assert_prolog_success!( + &mut wam, + "catch(sort([a|_],_),error(E,_),true).", + [["E = instantiation_error"]] + ); + assert_prolog_success!( + &mut wam, + "catch(sort([],[a|a]),error(Pat,_),true).", + [["Pat = type_error(list,[a|a])"]] + ); + assert_prolog_success!(&mut wam, "sort([],L).", [["L = []"]]); + assert_prolog_success!( + &mut wam, + "catch(sort(_,[]),error(E,_),true).", + [["E = type_error(list,_16)"]] + ); + assert_prolog_success!( + &mut wam, + "catch(sort([a,b,c],not_a_list),error(E,_),true).", + [["E = type_error(list,not_a_list)"]] + ); + + assert_prolog_success!( + &mut wam, + "call(((G = 2 ; fail),B=3,!)).", + [["G = 2", "B = 3"]] + ); assert_prolog_success!(&mut wam, "call_with_inference_limit((setup_call_cleanup(S=1,(G=2;fail),writeq(S+G>B)),B=3,!),135,R).", [["G = 2","B = 3","R = !","S = 1"]]); - assert_prolog_success!(&mut wam, "call_with_inference_limit((setup_call_cleanup(S=1,(G=2;fail),writeq(S+G>B)),B=3,!),10,R).", - [["S = _1","G = _4","B = _14","R = inference_limit_exceeded"]]); - - assert_prolog_success!(&mut wam, "X = '\\033\\'.", - [["X = '\\x1b\\'"]]); - - assert_prolog_success!(&mut wam, "X = '\\n'.", - [["X = '\\n'"]]); - assert_prolog_success!(&mut wam, "X = '\\b'.", - [["X = '\\b'"]]); - assert_prolog_success!(&mut wam, "X = '\\v'.", - [["X = '\\v'"]]); - assert_prolog_success!(&mut wam, "X = '\\a'.", - [["X = '\\a'"]]); - assert_prolog_success!(&mut wam, "X = '\\f'.", - [["X = '\\f'"]]); - assert_prolog_success!(&mut wam, "X = '\\b\\r\\f\\t\\n'.", - [["X = '\\b\\r\\f\\t\\n'"]]); + assert_prolog_success!( + &mut wam, + "call_with_inference_limit((setup_call_cleanup(S=1,(G=2;fail),writeq(S+G>B)),B=3,!),10,R).", + [[ + "S = _1", + "G = _4", + "B = _14", + "R = inference_limit_exceeded" + ]] + ); + + assert_prolog_success!(&mut wam, "X = '\\033\\'.", [["X = '\\x1b\\'"]]); + + assert_prolog_success!(&mut wam, "X = '\\n'.", [["X = '\\n'"]]); + assert_prolog_success!(&mut wam, "X = '\\b'.", [["X = '\\b'"]]); + assert_prolog_success!(&mut wam, "X = '\\v'.", [["X = '\\v'"]]); + assert_prolog_success!(&mut wam, "X = '\\a'.", [["X = '\\a'"]]); + assert_prolog_success!(&mut wam, "X = '\\f'.", [["X = '\\f'"]]); + assert_prolog_success!( + &mut wam, + "X = '\\b\\r\\f\\t\\n'.", + [["X = '\\b\\r\\f\\t\\n'"]] + ); assert_prolog_success!(&mut wam, "(- (1)) = -(1)."); assert_prolog_success!(&mut wam, "(- -1) = -(-1)."); - assert_prolog_success!(&mut wam, "X = ((*)=(*)).", - [["X = ((*)=(*))"]]); - assert_prolog_success!(&mut wam, "X = [.,.(.,.,.)].", - [["X = ['.','.'('.','.','.')]"]]); - assert_prolog_success!(&mut wam, "X = a+(b*c).", - [["X = a+b*c"]]); - assert_prolog_success!(&mut wam, "X = a*(b+c).", - [["X = a*(b+c)"]]); - assert_prolog_success!(&mut wam, "X = [:-,-].", - [["X = [:-,-]"]]); - assert_prolog_success!(&mut wam, "X = a*(b+c).", - [["X = a*(b+c)"]]); - assert_prolog_success!(&mut wam, "X = (-)-(-).", - [["X = (-)-(-)"]]); - assert_prolog_success!(&mut wam, "X = ((:-):-(:-)).", - [["X = ((:-):-(:-))"]]); - assert_prolog_success!(&mut wam, "X = (a:-b,c).", - [["X = (a:-b,c)"]]); - assert_prolog_success!(&mut wam, "X = f((f:-a,b,c)).", - [["X = f((f:-a,b,c))"]]); - assert_prolog_success!(&mut wam, "X = f((f:-a,(b,c))).", - [["X = f((f:-a,b,c))"]]); - assert_prolog_success!(&mut wam, "X = f((a,b,c)).", - [["X = f((a,b,c))"]]); - assert_prolog_success!(&mut wam, "X = f((a,(b,c))).", - [["X = f((a,b,c))"]]); - assert_prolog_success!(&mut wam, "X = f(((a,b),c)).", - [["X = f(((a,b),c))"]]); - assert_prolog_success!(&mut wam, "X = f(((a,b),(c,d))).", - [["X = f(((a,b),c,d))"]]); - - assert_prolog_success!(&mut wam, "findall(X,(X = 1 ; X = 2),S).", - [["S = [1,2]","X = _0"]]); - assert_prolog_success!(&mut wam, "findall(X+Y,(X = 1),S).", - [["S = [1+_36]","X = _1","Y = _2"]]); - assert_prolog_success!(&mut wam, "findall(X,false,S).", - [["S = []","X = _0"]]); - assert_prolog_success!(&mut wam, "findall(X,(X = 1 ; X = 1),S).", - [["S = [1,1]","X = _0"]]); + assert_prolog_success!(&mut wam, "X = ((*)=(*)).", [["X = ((*)=(*))"]]); + assert_prolog_success!( + &mut wam, + "X = [.,.(.,.,.)].", + [["X = ['.','.'('.','.','.')]"]] + ); + assert_prolog_success!(&mut wam, "X = a+(b*c).", [["X = a+b*c"]]); + assert_prolog_success!(&mut wam, "X = a*(b+c).", [["X = a*(b+c)"]]); + assert_prolog_success!(&mut wam, "X = [:-,-].", [["X = [:-,-]"]]); + assert_prolog_success!(&mut wam, "X = a*(b+c).", [["X = a*(b+c)"]]); + assert_prolog_success!(&mut wam, "X = (-)-(-).", [["X = (-)-(-)"]]); + assert_prolog_success!(&mut wam, "X = ((:-):-(:-)).", [["X = ((:-):-(:-))"]]); + assert_prolog_success!(&mut wam, "X = (a:-b,c).", [["X = (a:-b,c)"]]); + assert_prolog_success!(&mut wam, "X = f((f:-a,b,c)).", [["X = f((f:-a,b,c))"]]); + assert_prolog_success!(&mut wam, "X = f((f:-a,(b,c))).", [["X = f((f:-a,b,c))"]]); + assert_prolog_success!(&mut wam, "X = f((a,b,c)).", [["X = f((a,b,c))"]]); + assert_prolog_success!(&mut wam, "X = f((a,(b,c))).", [["X = f((a,b,c))"]]); + assert_prolog_success!(&mut wam, "X = f(((a,b),c)).", [["X = f(((a,b),c))"]]); + assert_prolog_success!(&mut wam, "X = f(((a,b),(c,d))).", [["X = f(((a,b),c,d))"]]); + + assert_prolog_success!( + &mut wam, + "findall(X,(X = 1 ; X = 2),S).", + [["S = [1,2]", "X = _0"]] + ); + assert_prolog_success!( + &mut wam, + "findall(X+Y,(X = 1),S).", + [["S = [1+_36]", "X = _1", "Y = _2"]] + ); + assert_prolog_success!(&mut wam, "findall(X,false,S).", [["S = []", "X = _0"]]); + assert_prolog_success!( + &mut wam, + "findall(X,(X = 1 ; X = 1),S).", + [["S = [1,1]", "X = _0"]] + ); assert_prolog_failure!(&mut wam, "findall(X,(X = 2 ; X = 1),[1,2])."); - assert_prolog_success!(&mut wam, "findall(X,(X = 1 ; X = 2),[X,Y]).", - [["X = 1","Y = 2"]]); - assert_prolog_success!(&mut wam, "catch(findall(X,4,S),error(type_error(callable,4),_),true).", - [["S = _3","X = _1"]]); - - assert_prolog_success!(&mut wam, "bagof(X,(X=Y; X=Z),S).", - [["S = [_3,_6]","X = _0","Y = _3","Z = _6"]]); - assert_prolog_success!(&mut wam, "bagof(X,(X=1 ; X = 2),X).", - [["X = [1,2]"]]); - assert_prolog_success!(&mut wam, "bagof(X,(X=1 ; X = 2),S).", - [["S = [1,2]","X = _0"]]); - assert_prolog_success!(&mut wam, "bagof(1,(Y=1 ; Y=2),L).", - [["L = [1]","Y = 1"], - ["L = [1]","Y = 2"]]); + assert_prolog_success!( + &mut wam, + "findall(X,(X = 1 ; X = 2),[X,Y]).", + [["X = 1", "Y = 2"]] + ); + assert_prolog_success!( + &mut wam, + "catch(findall(X,4,S),error(type_error(callable,4),_),true).", + [["S = _3", "X = _1"]] + ); + + assert_prolog_success!( + &mut wam, + "bagof(X,(X=Y; X=Z),S).", + [["S = [_3,_6]", "X = _0", "Y = _3", "Z = _6"]] + ); + assert_prolog_success!(&mut wam, "bagof(X,(X=1 ; X = 2),X).", [["X = [1,2]"]]); + assert_prolog_success!( + &mut wam, + "bagof(X,(X=1 ; X = 2),S).", + [["S = [1,2]", "X = _0"]] + ); + assert_prolog_success!( + &mut wam, + "bagof(1,(Y=1 ; Y=2),L).", + [["L = [1]", "Y = 1"], ["L = [1]", "Y = 2"]] + ); submit(&mut wam, "b(1,1). b(1,1). b(1,2). b(2,1). b(2,2). b(2,2)."); - assert_prolog_success!(&mut wam, "bagof(X,b(X,Y),L).", - [["L = [1,Y,2]","X = _0","Y = 1"], - ["L = [1,2,Y]","X = _0","Y = 2"]]); + assert_prolog_success!( + &mut wam, + "bagof(X,b(X,Y),L).", + [ + ["L = [1,Y,2]", "X = _0", "Y = 1"], + ["L = [1,2,Y]", "X = _0", "Y = 2"] + ] + ); - assert_prolog_success!(&mut wam, "bagof(X,(X=Y; X=Z; Y=1),L).", - [["L = [_3,_6]","X = _0","Y = _3","Z = _6"], - ["L = [_112]","X = _0","Y = 1","Z = _6"]]); + assert_prolog_success!( + &mut wam, + "bagof(X,(X=Y; X=Z; Y=1),L).", + [ + ["L = [_3,_6]", "X = _0", "Y = _3", "Z = _6"], + ["L = [_112]", "X = _0", "Y = 1", "Z = _6"] + ] + ); submit(&mut wam, "a(1,f(_)). a(2,f(_))."); - assert_prolog_success!(&mut wam, "bagof(X,a(X,Y),L).", - [["L = [1,2]","X = _0","Y = f(_78)"]]); + assert_prolog_success!( + &mut wam, + "bagof(X,a(X,Y),L).", + [["L = [1,2]", "X = _0", "Y = f(_78)"]] + ); - assert_prolog_success!(&mut wam, "setof(X,(X = 1 ; X = 2),S).", - [["S = [1,2]","X = _0"]]); - assert_prolog_success!(&mut wam, "setof(X,(X=Y ; X=Z),S).", - [["S = [_3,_6]","X = _0","Y = _3","Z = _6"]]); + assert_prolog_success!( + &mut wam, + "setof(X,(X = 1 ; X = 2),S).", + [["S = [1,2]", "X = _0"]] + ); + assert_prolog_success!( + &mut wam, + "setof(X,(X=Y ; X=Z),S).", + [["S = [_3,_6]", "X = _0", "Y = _3", "Z = _6"]] + ); assert_prolog_failure!(&mut wam, "setof(X,false,S)."); - assert_prolog_success!(&mut wam, "setof(1,(Y=1 ; Y=2),L).", - [["L = [1]","Y = 1"], - ["L = [1]","Y = 2"]]); - assert_prolog_success!(&mut wam, "setof(X,(X=Y; X=Z; Y=1),L).", - [["L = [_3,_6]","X = _0","Y = _3","Z = _6"], - ["L = [_112]","Y = 1","X = _0","Y = 1","Z = _6"]]); - assert_prolog_failure!(&mut wam, "setof(X,member(X,[f(U,b),f(V,c)]),[f(a,c),f(a,b)])."); - assert_prolog_success!(&mut wam, "setof(X,member(X,[f(U,b),f(V,c)]),[f(a,b),f(a,c)]).", - [["U = a","V = a","X = _0"]]); - assert_prolog_success!(&mut wam, "setof(X,member(X,[V,U,f(U),f(V)]),L).", - [["L = [_2,_4,f(U),f(V)]","U = _2","V = _4","X = _0"]]); - assert_prolog_success!(&mut wam, "setof(X,member(X,[V,U,f(U),f(V)]),[a,b,f(a),f(b)]).", - [["U = a","V = b","X = _0"]]); - - assert_prolog_success!(&mut wam, "findall(X,(X = 1 ; X = 2),S0,S1).", - [["S0 = [1,2|_11]","S1 = _11","X = _0"]]); - assert_prolog_success!(&mut wam, "findall(X+Y,(X = 1),S0,S1).", - [["S0 = [1+_44|_7]","S1 = _7","X = _1","Y = _2"]]); - assert_prolog_success!(&mut wam, "findall(X,false,S,_).", - [["S = []","X = _0"]]); - assert_prolog_success!(&mut wam, "findall(X,(X = 1 ; X = 1),S0,S1).", - [["S0 = [1,1|_11]","S1 = _11","X = _0"]]); + assert_prolog_success!( + &mut wam, + "setof(1,(Y=1 ; Y=2),L).", + [["L = [1]", "Y = 1"], ["L = [1]", "Y = 2"]] + ); + assert_prolog_success!( + &mut wam, + "setof(X,(X=Y; X=Z; Y=1),L).", + [ + ["L = [_3,_6]", "X = _0", "Y = _3", "Z = _6"], + ["L = [_112]", "Y = 1", "X = _0", "Y = 1", "Z = _6"] + ] + ); + assert_prolog_failure!( + &mut wam, + "setof(X,member(X,[f(U,b),f(V,c)]),[f(a,c),f(a,b)])." + ); + assert_prolog_success!( + &mut wam, + "setof(X,member(X,[f(U,b),f(V,c)]),[f(a,b),f(a,c)]).", + [["U = a", "V = a", "X = _0"]] + ); + assert_prolog_success!( + &mut wam, + "setof(X,member(X,[V,U,f(U),f(V)]),L).", + [["L = [_2,_4,f(U),f(V)]", "U = _2", "V = _4", "X = _0"]] + ); + assert_prolog_success!( + &mut wam, + "setof(X,member(X,[V,U,f(U),f(V)]),[a,b,f(a),f(b)]).", + [["U = a", "V = b", "X = _0"]] + ); + + assert_prolog_success!( + &mut wam, + "findall(X,(X = 1 ; X = 2),S0,S1).", + [["S0 = [1,2|_11]", "S1 = _11", "X = _0"]] + ); + assert_prolog_success!( + &mut wam, + "findall(X+Y,(X = 1),S0,S1).", + [["S0 = [1+_44|_7]", "S1 = _7", "X = _1", "Y = _2"]] + ); + assert_prolog_success!(&mut wam, "findall(X,false,S,_).", [["S = []", "X = _0"]]); + assert_prolog_success!( + &mut wam, + "findall(X,(X = 1 ; X = 1),S0,S1).", + [["S0 = [1,1|_11]", "S1 = _11", "X = _0"]] + ); assert_prolog_failure!(&mut wam, "findall(X,(X = 2 ; X = 1),[1,2|S],S)."); - assert_prolog_success!(&mut wam, "findall(X,(X = 1 ; X = 2),[X,Y|S],S).", - [["S = _11","X = 1","Y = 2"]]); - assert_prolog_success!(&mut wam, "catch(findall(X,4,S0,S1),error(type_error(callable,4),_),true).", - [["S0 = _3","S1 = _4","X = _1"]]); + assert_prolog_success!( + &mut wam, + "findall(X,(X = 1 ; X = 2),[X,Y|S],S).", + [["S = _11", "X = 1", "Y = 2"]] + ); + assert_prolog_success!( + &mut wam, + "catch(findall(X,4,S0,S1),error(type_error(callable,4),_),true).", + [["S0 = _3", "S1 = _4", "X = _1"]] + ); // bagof & setof with existential variables. - assert_prolog_success!(&mut wam, "bagof(X,Y^((X = 1,Y = 1; (X = 2,Y = 2))),S).", - [["S = [1,2]","X = _0","Y = _5"]]); - assert_prolog_success!(&mut wam, "bagof(X,Y^((X = 1 ; Y = 1) ; (X = 2,Y = 2)),S).", - [["S = [1,_126,2]","X = _0","Y = _5"]]); + assert_prolog_success!( + &mut wam, + "bagof(X,Y^((X = 1,Y = 1; (X = 2,Y = 2))),S).", + [["S = [1,2]", "X = _0", "Y = _5"]] + ); + assert_prolog_success!( + &mut wam, + "bagof(X,Y^((X = 1 ; Y = 1) ; (X = 2,Y = 2)),S).", + [["S = [1,_126,2]", "X = _0", "Y = _5"]] + ); - assert_prolog_success!(&mut wam, "setof(X,Y^((X = 1,Y = 1; (X = 2,Y = 2))),S).", - [["S = [1,2]","X = _0","Y = _5"]]); - assert_prolog_success!(&mut wam, "setof(X,Y^((X = 1 ; Y = 1) ; (X = 2,Y = 2)),S).", - [["S = [_126,1,2]","X = _0","Y = _5"]]); + assert_prolog_success!( + &mut wam, + "setof(X,Y^((X = 1,Y = 1; (X = 2,Y = 2))),S).", + [["S = [1,2]", "X = _0", "Y = _5"]] + ); + assert_prolog_success!( + &mut wam, + "setof(X,Y^((X = 1 ; Y = 1) ; (X = 2,Y = 2)),S).", + [["S = [_126,1,2]", "X = _0", "Y = _5"]] + ); assert_prolog_failure!(&mut wam, "forall(true,false)."); assert_prolog_success!(&mut wam, "forall(false,true)."); - assert_prolog_success!(&mut wam, "catch(forall(_,true),error(instantiation_error,_),true)."); - assert_prolog_success!(&mut wam, "catch(forall(true,_),error(instantiation_error,_),true)."); - assert_prolog_success!(&mut wam, "catch(forall(1,true),error(type_error(callable,1),_),true)."); - assert_prolog_success!(&mut wam, "catch(forall(true,1),error(type_error(callable,1),_),true)."); + assert_prolog_success!( + &mut wam, + "catch(forall(_,true),error(instantiation_error,_),true)." + ); + assert_prolog_success!( + &mut wam, + "catch(forall(true,_),error(instantiation_error,_),true)." + ); + assert_prolog_success!( + &mut wam, + "catch(forall(1,true),error(type_error(callable,1),_),true)." + ); + assert_prolog_success!( + &mut wam, + "catch(forall(true,1),error(type_error(callable,1),_),true)." + ); - submit(&mut wam, " + submit( + &mut wam, + " :- dynamic(cat/0). cat. @@ -1822,36 +2459,68 @@ legs(A,7) :- A,call(A). :- dynamic(insect/1). insect(ant). -insect(bee)."); +insect(bee).", + ); assert_prolog_success!(&mut wam, "clause(cat,true)."); assert_prolog_success!(&mut wam, "clause(dog,true)."); - assert_prolog_success!(&mut wam, "clause(legs(I,6),Body).", - [["I = _1","Body = insect(_1)"]]); - assert_prolog_success!(&mut wam, "clause(legs(C,7),Body).", - [["C = _1","Body = (_1,call(C))"]]); - assert_prolog_success!(&mut wam, "clause(insect(I),T).", - [["I = ant","T = true"], - ["I = bee","T = true"]]); + assert_prolog_success!( + &mut wam, + "clause(legs(I,6),Body).", + [["I = _1", "Body = insect(_1)"]] + ); + assert_prolog_success!( + &mut wam, + "clause(legs(C,7),Body).", + [["C = _1", "Body = (_1,call(C))"]] + ); + assert_prolog_success!( + &mut wam, + "clause(insect(I),T).", + [["I = ant", "T = true"], ["I = bee", "T = true"]] + ); assert_prolog_failure!(&mut wam, "clause(x,Body)."); - assert_prolog_success!(&mut wam, "catch(clause(_,_),error(instantiation_error,_),true)."); - assert_prolog_success!(&mut wam, "catch(clause(4,_),error(type_error(callable,4),_),true)."); - assert_prolog_success!(&mut wam, "catch(clause(elk(N),_),error(permission_error(access,private_procedure,elk/1),_),true)."); - assert_prolog_success!(&mut wam, "catch(clause(atom(N),_),error(permission_error(access,private_procedure,atom/1),_),true)."); + assert_prolog_success!( + &mut wam, + "catch(clause(_,_),error(instantiation_error,_),true)." + ); + assert_prolog_success!( + &mut wam, + "catch(clause(4,_),error(type_error(callable,4),_),true)." + ); + assert_prolog_success!( + &mut wam, + "catch(clause(elk(N),_),error(permission_error(access,private_procedure,elk/1),_),true)." + ); + assert_prolog_success!( + &mut wam, + "catch(clause(atom(N),_),error(permission_error(access,private_procedure,atom/1),_),true)." + ); assert_prolog_success!(&mut wam, "asserta(legs(octopus,8))."); assert_prolog_success!(&mut wam, "asserta( (legs(A,4) :- animal(A)) )."); assert_prolog_success!(&mut wam, "asserta( (foo(X) :- X,call(X)) )."); - assert_prolog_success!(&mut wam, "catch(asserta(_),error(instantiation_error,_),true)."); + assert_prolog_success!( + &mut wam, + "catch(asserta(_),error(instantiation_error,_),true)." + ); assert_prolog_failure!(&mut wam, "asserta(_)."); - assert_prolog_success!(&mut wam, "catch(asserta(4),error(type_error(callable,4),_),true)."); + assert_prolog_success!( + &mut wam, + "catch(asserta(4),error(type_error(callable,4),_),true)." + ); assert_prolog_failure!(&mut wam, "asserta(4)."); - assert_prolog_success!(&mut wam, "catch(asserta( (foo :- 4) ),error(type_error(callable,4),_),true)."); + assert_prolog_success!( + &mut wam, + "catch(asserta( (foo :- 4) ),error(type_error(callable,4),_),true)." + ); assert_prolog_failure!(&mut wam, "asserta( (foo :- 4) )."); assert_prolog_success!(&mut wam, "catch(asserta( (atom(_) :- true) ),error(permission_error(modify,static_procedure,atom/1),_),true)."); assert_prolog_failure!(&mut wam, "asserta( (atom(_) :- true) )."); - submit(&mut wam, " + submit( + &mut wam, + " :- dynamic(cat/0). cat. @@ -1866,21 +2535,33 @@ legs(A,7) :- A,call(A). :- dynamic(insect/1). insect(ant). -insect(bee)."); +insect(bee).", + ); assert_prolog_success!(&mut wam, "assertz(legs(octopus,8))."); assert_prolog_success!(&mut wam, "assertz( (legs(A,4) :- animal(A)) )."); assert_prolog_success!(&mut wam, "assertz( (foo(X) :- X,call(X)) )."); - assert_prolog_success!(&mut wam, "catch(assertz(_),error(instantiation_error,_),true)."); + assert_prolog_success!( + &mut wam, + "catch(assertz(_),error(instantiation_error,_),true)." + ); assert_prolog_failure!(&mut wam, "assertz(_)."); - assert_prolog_success!(&mut wam, "catch(assertz(4),error(type_error(callable,4),_),true)."); + assert_prolog_success!( + &mut wam, + "catch(assertz(4),error(type_error(callable,4),_),true)." + ); assert_prolog_failure!(&mut wam, "assertz(4)."); - assert_prolog_success!(&mut wam, "catch(assertz( (foo :- 4) ),error(type_error(callable,4),_),true)."); + assert_prolog_success!( + &mut wam, + "catch(assertz( (foo :- 4) ),error(type_error(callable,4),_),true)." + ); assert_prolog_failure!(&mut wam, "assertz( (foo :- 4) )."); assert_prolog_success!(&mut wam, "catch(assertz( (atom(_) :- true) ),error(permission_error(modify,static_procedure,atom/1),_),true)."); assert_prolog_failure!(&mut wam, "assertz( (atom(_) :- true) )."); - submit(&mut wam, " + submit( + &mut wam, + " :- dynamic(legs/2). legs(A,4) :- animal(A). legs(octopus,8). @@ -1894,129 +2575,225 @@ insect(bee). :- dynamic(foo/1). foo(X) :- call(X),call(X). -foo(X) :- call(X) -> call(X)."); +foo(X) :- call(X) -> call(X).", + ); assert_prolog_success!(&mut wam, "retract(legs(octopus,8))."); assert_prolog_failure!(&mut wam, "retract(legs(spider,6))."); - assert_prolog_success!(&mut wam, "retract( (legs(X,2) :- T) ).", - [["X = _1","T = bird(_1)"]]); - assert_prolog_success!(&mut wam, "retract( (legs(X,Y) :- Z) ).", - [["X = _1","Y = 4","Z = animal(_1)"], - ["X = _1","Y = 6","Z = insect(_1)"], - ["X = spider","Y = 8","Z = true"]]); + assert_prolog_success!( + &mut wam, + "retract( (legs(X,2) :- T) ).", + [["X = _1", "T = bird(_1)"]] + ); + assert_prolog_success!( + &mut wam, + "retract( (legs(X,Y) :- Z) ).", + [ + ["X = _1", "Y = 4", "Z = animal(_1)"], + ["X = _1", "Y = 6", "Z = insect(_1)"], + ["X = spider", "Y = 8", "Z = true"] + ] + ); assert_prolog_failure!(&mut wam, "retract( (legs(X,Y) :- Z) )."); - assert_prolog_success!(&mut wam, "retract(insect(I)).", - [["I = ant"], - ["I = bee"]]); - assert_prolog_success!(&mut wam, "retract(( foo(A) :- A,call(A) )).", - [["A = call(A)"]]); + assert_prolog_success!(&mut wam, "retract(insect(I)).", [["I = ant"], ["I = bee"]]); + assert_prolog_success!( + &mut wam, + "retract(( foo(A) :- A,call(A) )).", + [["A = call(A)"]] + ); assert_prolog_success!(&mut wam, "foo(atom(atom))."); - assert_prolog_success!(&mut wam, "retract(( foo(C) :- A -> B )).", - [["A = call(_1)","B = call(_1)","C = _1"]]); + assert_prolog_success!( + &mut wam, + "retract(( foo(C) :- A -> B )).", + [["A = call(_1)", "B = call(_1)", "C = _1"]] + ); assert_prolog_failure!(&mut wam, "retract( (X :- in_eec(Y)) )."); - assert_prolog_success!(&mut wam, "catch(retract( (X :- in_eec(Y)) ),error(instantiation_error,_),true)."); + assert_prolog_success!( + &mut wam, + "catch(retract( (X :- in_eec(Y)) ),error(instantiation_error,_),true)." + ); assert_prolog_failure!(&mut wam, "retract( (4 :- X) )."); - assert_prolog_success!(&mut wam, "catch(retract( (4 :- X) ),error(type_error(callable,4),_),true)."); + assert_prolog_success!( + &mut wam, + "catch(retract( (4 :- X) ),error(type_error(callable,4),_),true)." + ); assert_prolog_failure!(&mut wam, "retract( (atom(X) :- X == '[]') )."); assert_prolog_success!(&mut wam, "catch(retract( (atom(X) :- X == '[]') ),error(permission_error(modify,static_procedure,atom/1),_),true)."); /* This example shows why machine::compile::localize_self_calls is necessary. */ -submit(&mut wam, " + submit( + &mut wam, + " :- dynamic(p/1). p(a). p(b). p(c) :- p(d). -p(d)."); +p(d).", + ); - assert_prolog_success!(&mut wam, "p(X),retract(p(_)).", - [["X = a"], - ["X = a"], - ["X = a"]]); + assert_prolog_success!( + &mut wam, + "p(X),retract(p(_)).", + [["X = a"], ["X = a"], ["X = a"]] + ); - submit(&mut wam, " + submit( + &mut wam, + " :- dynamic(foo/1). foo(X) :- call(X),call(X). -foo(X) :- call(X) -> call(X)."); +foo(X) :- call(X) -> call(X).", + ); assert_prolog_success!(&mut wam, "abolish(foo/2)."); assert_prolog_failure!(&mut wam, "abolish(foo/_)."); - assert_prolog_success!(&mut wam, "catch(abolish(foo/_),error(instantiation_error,abolish/1),true)."); + assert_prolog_success!( + &mut wam, + "catch(abolish(foo/_),error(instantiation_error,abolish/1),true)." + ); assert_prolog_failure!(&mut wam, "abolish(foo)."); - assert_prolog_success!(&mut wam, "catch(abolish(foo),error(type_error(predicate_indicator,foo),abolish/1),true)."); + assert_prolog_success!( + &mut wam, + "catch(abolish(foo),error(type_error(predicate_indicator,foo),abolish/1),true)." + ); assert_prolog_failure!(&mut wam, "abolish(foo(_))."); - assert_prolog_success!(&mut wam, "catch(abolish(foo(_)),error(type_error(predicate_indicator,foo(_)),abolish/1),true)."); + assert_prolog_success!( + &mut wam, + "catch(abolish(foo(_)),error(type_error(predicate_indicator,foo(_)),abolish/1),true)." + ); assert_prolog_failure!(&mut wam, "abolish(abolish/1)."); assert_prolog_success!(&mut wam, "catch(abolish(abolish/1),error(permission_error(modify,static_procedure,abolish/1),abolish/1),true)."); - assert_prolog_success!(&mut wam, "atom_length('enchanted evening',N).", - [["N = 17"]]); - assert_prolog_success!(&mut wam,r"atom_length('enchanted\ + assert_prolog_success!( + &mut wam, + "atom_length('enchanted evening',N).", + [["N = 17"]] + ); + assert_prolog_success!( + &mut wam, + r"atom_length('enchanted\ evening',N).", - [["N = 17"]]); - assert_prolog_success!(&mut wam, "atom_length('',N).", - [["N = 0"]]); + [["N = 17"]] + ); + assert_prolog_success!(&mut wam, "atom_length('',N).", [["N = 0"]]); assert_prolog_failure!(&mut wam, "atom_length('scarlet',5)."); - assert_prolog_success!(&mut wam, "catch((atom_length(Atom,4),false),error(instantiation_error,_),true)."); - assert_prolog_success!(&mut wam, "catch((atom_length(1.23,4),false),error(type_error(atom,1.23),_),true)."); - assert_prolog_success!(&mut wam, "catch((atom_length(atom,'4'),false),error(type_error(integer,'4'),_),true)."); + assert_prolog_success!( + &mut wam, + "catch((atom_length(Atom,4),false),error(instantiation_error,_),true)." + ); + assert_prolog_success!( + &mut wam, + "catch((atom_length(1.23,4),false),error(type_error(atom,1.23),_),true)." + ); + assert_prolog_success!( + &mut wam, + "catch((atom_length(atom,'4'),false),error(type_error(integer,'4'),_),true)." + ); } #[test] -fn test_queries_on_setup_call_cleanup() -{ +fn test_queries_on_setup_call_cleanup() { let mut wam = Machine::new(readline::input_stream()); submit(&mut wam, ":- use_module('src/prolog/lib/non_iso.pl')."); - + // Test examples from the ISO Prolog page for setup_call_catch. assert_prolog_failure!(&mut wam, "setup_call_cleanup(false, _, _)."); - assert_prolog_success!(&mut wam, "catch(setup_call_cleanup(true, throw(unthrown), _), error(instantiation_error, _), true)."); - assert_prolog_success!(&mut wam, "setup_call_cleanup(true, true, (true ; throw(x)))."); - assert_prolog_success!(&mut wam, "setup_call_cleanup(true, X = 1, X = 2).", - [["X = 1"]]); - assert_prolog_success!(&mut wam, "setup_call_cleanup(true, true, X = 2).", - [["X = 2"]]); - assert_prolog_success!(&mut wam, "catch(setup_call_cleanup(true, X=true, X), error(E, _), true).", - [["E = instantiation_error", "X = _1"]]); - assert_prolog_success!(&mut wam, "catch(setup_call_cleanup(X=throw(ex), true, X), E, true).", - [["E = ex", "X = _3"]]); + assert_prolog_success!( + &mut wam, + "catch(setup_call_cleanup(true, throw(unthrown), _), error(instantiation_error, _), true)." + ); + assert_prolog_success!( + &mut wam, + "setup_call_cleanup(true, true, (true ; throw(x)))." + ); + assert_prolog_success!( + &mut wam, + "setup_call_cleanup(true, X = 1, X = 2).", + [["X = 1"]] + ); + assert_prolog_success!( + &mut wam, + "setup_call_cleanup(true, true, X = 2).", + [["X = 2"]] + ); + assert_prolog_success!( + &mut wam, + "catch(setup_call_cleanup(true, X=true, X), error(E, _), true).", + [["E = instantiation_error", "X = _1"]] + ); + assert_prolog_success!( + &mut wam, + "catch(setup_call_cleanup(X=throw(ex), true, X), E, true).", + [["E = ex", "X = _3"]] + ); assert_prolog_success!(&mut wam, "setup_call_cleanup(true, true, false)."); - assert_prolog_success!(&mut wam, "setup_call_cleanup(S = 1, G = 2, C = 3).", - [["S = 1", "G = 2", "C = 3"]]); - assert_prolog_success!(&mut wam, "setup_call_cleanup((S=1;S=2), G=3, C=4).", - [["S = 1", "G = 3", "C = 4"]]); - assert_prolog_success!(&mut wam, "setup_call_cleanup(S=1, G=2, writeq(S+G)).", - [["S = 1", "G = 2"]]); - assert_prolog_success!(&mut wam, "setup_call_cleanup(S=1, (G=2;G=3), writeq(S+G)).", - [["S = 1", "G = 2"], - ["S = 1", "G = 3"]]); - assert_prolog_success!(&mut wam, "setup_call_cleanup(S=1, G=2, writeq(S+G>A+B)), A=3, B=4.", - [["S = 1", "G = 2", "A = 3", "B = 4"]]); - assert_prolog_success!(&mut wam, - "catch(setup_call_cleanup(S=1, (G=2;G=3,throw(x)), writeq(S+G)), E, true).", - [["S = 1", "G = 2", "E = _26"], ["G = _4", "E = x", "S = _1"]]); - assert_prolog_success!(&mut wam, - "setup_call_cleanup(S=1, (G=2;G=3),writeq(S+G>B)), B=4, !.", - [["S = 1", "B = 4", "G = 2"]]); - assert_prolog_success!(&mut wam, - "setup_call_cleanup(S=1,G=2,writeq(S+G>B)),B=3,!.", - [["S = 1", "G = 2", "B = 3"]]); - assert_prolog_success!(&mut wam, - "setup_call_cleanup(S=1,(G=2;false),writeq(S+G>B)),B=3,!.", - [["S = 1", "G = 2", "B = 3"]]); - assert_prolog_success!(&mut wam, - "setup_call_cleanup(S=1,(G=2;S=2),writeq(S+G>B)), B=3, !.", - [["S = 1", "B = 3", "G = 2"]]); - assert_prolog_failure!(&mut wam, - "setup_call_cleanup(S=1,(G=2;G=3), writeq(S+G>B)), B=4, !, throw(x)."); + assert_prolog_success!( + &mut wam, + "setup_call_cleanup(S = 1, G = 2, C = 3).", + [["S = 1", "G = 2", "C = 3"]] + ); + assert_prolog_success!( + &mut wam, + "setup_call_cleanup((S=1;S=2), G=3, C=4).", + [["S = 1", "G = 3", "C = 4"]] + ); + assert_prolog_success!( + &mut wam, + "setup_call_cleanup(S=1, G=2, writeq(S+G)).", + [["S = 1", "G = 2"]] + ); + assert_prolog_success!( + &mut wam, + "setup_call_cleanup(S=1, (G=2;G=3), writeq(S+G)).", + [["S = 1", "G = 2"], ["S = 1", "G = 3"]] + ); + assert_prolog_success!( + &mut wam, + "setup_call_cleanup(S=1, G=2, writeq(S+G>A+B)), A=3, B=4.", + [["S = 1", "G = 2", "A = 3", "B = 4"]] + ); + assert_prolog_success!( + &mut wam, + "catch(setup_call_cleanup(S=1, (G=2;G=3,throw(x)), writeq(S+G)), E, true).", + [["S = 1", "G = 2", "E = _26"], ["G = _4", "E = x", "S = _1"]] + ); + assert_prolog_success!( + &mut wam, + "setup_call_cleanup(S=1, (G=2;G=3),writeq(S+G>B)), B=4, !.", + [["S = 1", "B = 4", "G = 2"]] + ); + assert_prolog_success!( + &mut wam, + "setup_call_cleanup(S=1,G=2,writeq(S+G>B)),B=3,!.", + [["S = 1", "G = 2", "B = 3"]] + ); + assert_prolog_success!( + &mut wam, + "setup_call_cleanup(S=1,(G=2;false),writeq(S+G>B)),B=3,!.", + [["S = 1", "G = 2", "B = 3"]] + ); + assert_prolog_success!( + &mut wam, + "setup_call_cleanup(S=1,(G=2;S=2),writeq(S+G>B)), B=3, !.", + [["S = 1", "B = 3", "G = 2"]] + ); + assert_prolog_failure!( + &mut wam, + "setup_call_cleanup(S=1,(G=2;G=3), writeq(S+G>B)), B=4, !, throw(x)." + ); - assert_prolog_success!(&mut wam, - "catch(setup_call_cleanup(true,throw(goal),throw(cl)), Pat, true).", - [["Pat = goal"]]); - assert_prolog_success!(&mut wam, - "catch(( setup_call_cleanup(true,(G=1;G=2),throw(cl)), throw(cont)), Pat, true).", - [["Pat = cont", "G = _1"]]); + assert_prolog_success!( + &mut wam, + "catch(setup_call_cleanup(true,throw(goal),throw(cl)), Pat, true).", + [["Pat = goal"]] + ); + assert_prolog_success!( + &mut wam, + "catch(( setup_call_cleanup(true,(G=1;G=2),throw(cl)), throw(cont)), Pat, true).", + [["Pat = cont", "G = _1"]] + ); // fails here. assert_prolog_success!(&mut wam, @@ -2025,137 +2802,237 @@ fn test_queries_on_setup_call_cleanup() } #[test] -fn test_queries_on_call_with_inference_limit() -{ +fn test_queries_on_call_with_inference_limit() { let mut wam = Machine::new(readline::input_stream()); submit(&mut wam, ":- use_module('src/prolog/lib/non_iso.pl')."); - - assert_prolog_success!(&mut wam, "call_with_inference_limit(throw(error), 0, R).", - [["R = inference_limit_exceeded"]]); - assert_prolog_success!(&mut wam, "catch(call_with_inference_limit(throw(error), 1, R), error, true)."); + + assert_prolog_success!( + &mut wam, + "call_with_inference_limit(throw(error), 0, R).", + [["R = inference_limit_exceeded"]] + ); + assert_prolog_success!( + &mut wam, + "catch(call_with_inference_limit(throw(error), 1, R), error, true)." + ); assert_prolog_failure!(&mut wam, "call_with_inference_limit(g(X), 5, R)."); submit(&mut wam, "g(1). g(2). g(3). g(4). g(5)."); - assert_prolog_success!(&mut wam, "call_with_inference_limit(g(X), 5, R).", - [["R = true", "X = 1"], - ["R = true", "X = 2"], - ["R = true", "X = 3"], - ["R = true", "X = 4"], - ["R = !", "X = 5"]]); - assert_prolog_success!(&mut wam, "call_with_inference_limit(g(X), 5, R), call(true).", - [["R = true", "X = 1"], - ["R = true", "X = 2"], - ["R = true", "X = 3"], - ["R = true", "X = 4"], - ["R = !", "X = 5"]]); - assert_prolog_success!(&mut wam, "call_with_inference_limit(g(X), 2, R).", - [["R = true", "X = 1"], - ["R = true", "X = 2"], - ["R = inference_limit_exceeded", "X = _1"]]); - assert_prolog_success!(&mut wam, "call_with_inference_limit(g(X), 3, R1), + assert_prolog_success!( + &mut wam, + "call_with_inference_limit(g(X), 5, R).", + [ + ["R = true", "X = 1"], + ["R = true", "X = 2"], + ["R = true", "X = 3"], + ["R = true", "X = 4"], + ["R = !", "X = 5"] + ] + ); + assert_prolog_success!( + &mut wam, + "call_with_inference_limit(g(X), 5, R), call(true).", + [ + ["R = true", "X = 1"], + ["R = true", "X = 2"], + ["R = true", "X = 3"], + ["R = true", "X = 4"], + ["R = !", "X = 5"] + ] + ); + assert_prolog_success!( + &mut wam, + "call_with_inference_limit(g(X), 2, R).", + [ + ["R = true", "X = 1"], + ["R = true", "X = 2"], + ["R = inference_limit_exceeded", "X = _1"] + ] + ); + assert_prolog_success!( + &mut wam, + "call_with_inference_limit(g(X), 3, R1), call_with_inference_limit(g(X), 5, R2).", - [["X = 1", "R1 = true", "R2 = !"], - ["X = 2", "R1 = true", "R2 = !"], - ["X = 3", "R1 = true", "R2 = !"], - ["X = 4", "R1 = true", "R2 = !"], - ["X = 5", "R1 = !", "R2 = !"]]); + [ + ["X = 1", "R1 = true", "R2 = !"], + ["X = 2", "R1 = true", "R2 = !"], + ["X = 3", "R1 = true", "R2 = !"], + ["X = 4", "R1 = true", "R2 = !"], + ["X = 5", "R1 = !", "R2 = !"] + ] + ); submit(&mut wam, "f(X) :- call_with_inference_limit(g(X), 5, _)."); - assert_prolog_success!(&mut wam, "call_with_inference_limit(f(X), 7, R).", - [["R = true", "X = 1"], - ["R = true", "X = 2"], - ["R = true", "X = 3"], - ["R = true", "X = 4"], - ["R = !", "X = 5"]]); - assert_prolog_success!(&mut wam, "call_with_inference_limit(f(X), 6, R).", - [["R = true", "X = 1"], - ["R = true", "X = 2"], - ["R = true", "X = 3"], - ["R = true", "X = 4"], - ["R = inference_limit_exceeded", "X = _1"]]); - assert_prolog_success!(&mut wam, "call_with_inference_limit(f(X), 4, R).", - [["R = true", "X = 1"], - ["R = true", "X = 2"], - ["R = inference_limit_exceeded", "X = _1"]]); - assert_prolog_success!(&mut wam, "call_with_inference_limit(f(X), 3, R).", - [["R = true", "X = 1"], - ["R = inference_limit_exceeded", "X = _1"]]); - assert_prolog_success!(&mut wam, "call_with_inference_limit(f(X), 2, R).", - [["R = inference_limit_exceeded", "X = _1"]]); + assert_prolog_success!( + &mut wam, + "call_with_inference_limit(f(X), 7, R).", + [ + ["R = true", "X = 1"], + ["R = true", "X = 2"], + ["R = true", "X = 3"], + ["R = true", "X = 4"], + ["R = !", "X = 5"] + ] + ); + assert_prolog_success!( + &mut wam, + "call_with_inference_limit(f(X), 6, R).", + [ + ["R = true", "X = 1"], + ["R = true", "X = 2"], + ["R = true", "X = 3"], + ["R = true", "X = 4"], + ["R = inference_limit_exceeded", "X = _1"] + ] + ); + assert_prolog_success!( + &mut wam, + "call_with_inference_limit(f(X), 4, R).", + [ + ["R = true", "X = 1"], + ["R = true", "X = 2"], + ["R = inference_limit_exceeded", "X = _1"] + ] + ); + assert_prolog_success!( + &mut wam, + "call_with_inference_limit(f(X), 3, R).", + [ + ["R = true", "X = 1"], + ["R = inference_limit_exceeded", "X = _1"] + ] + ); + assert_prolog_success!( + &mut wam, + "call_with_inference_limit(f(X), 2, R).", + [["R = inference_limit_exceeded", "X = _1"]] + ); submit(&mut wam, "e(X) :- call_with_inference_limit(f(X), 10, _)."); - assert_prolog_success!(&mut wam, "call_with_inference_limit(e(X), 10, R).", - [["R = true", "X = 1"], - ["R = true", "X = 2"], - ["R = true", "X = 3"], - ["R = true", "X = 4"], - ["R = !", "X = 5"]]); - assert_prolog_success!(&mut wam, "call_with_inference_limit(e(X), 8, R).", - [["R = true", "X = 1"], - ["R = true", "X = 2"], - ["R = true", "X = 3"], - ["R = true", "X = 4"], - ["R = inference_limit_exceeded", "X = _1"]]); - assert_prolog_success!(&mut wam, "call_with_inference_limit(e(X), 6, R).", - [["R = true", "X = 1"], - ["R = true", "X = 2"], - ["R = inference_limit_exceeded", "X = _1"]]); - assert_prolog_success!(&mut wam, "call_with_inference_limit(e(X), 5, R).", - [["R = true", "X = 1"], - ["R = inference_limit_exceeded", "X = _1"]]); - assert_prolog_success!(&mut wam, "call_with_inference_limit(e(X), 4, R).", - [["R = inference_limit_exceeded", "X = _1"]]); - - submit(&mut wam, "f(X, R) :- call_with_inference_limit(g(X), 5, R)."); - - assert_prolog_success!(&mut wam, "call_with_inference_limit(f(X, R), 4, S).", - [["S = true", "X = 1", "R = true"], - ["S = true", "X = 2", "R = true"], - ["S = inference_limit_exceeded", "X = _1", "R = _2"]]); - assert_prolog_success!(&mut wam, "call_with_inference_limit(f(X, R), 8, R).", - [["R = true", "X = 1"], - ["R = true", "X = 2"], - ["R = true", "X = 3"], - ["R = true", "X = 4"], - ["R = !", "X = 5"]]); + assert_prolog_success!( + &mut wam, + "call_with_inference_limit(e(X), 10, R).", + [ + ["R = true", "X = 1"], + ["R = true", "X = 2"], + ["R = true", "X = 3"], + ["R = true", "X = 4"], + ["R = !", "X = 5"] + ] + ); + assert_prolog_success!( + &mut wam, + "call_with_inference_limit(e(X), 8, R).", + [ + ["R = true", "X = 1"], + ["R = true", "X = 2"], + ["R = true", "X = 3"], + ["R = true", "X = 4"], + ["R = inference_limit_exceeded", "X = _1"] + ] + ); + assert_prolog_success!( + &mut wam, + "call_with_inference_limit(e(X), 6, R).", + [ + ["R = true", "X = 1"], + ["R = true", "X = 2"], + ["R = inference_limit_exceeded", "X = _1"] + ] + ); + assert_prolog_success!( + &mut wam, + "call_with_inference_limit(e(X), 5, R).", + [ + ["R = true", "X = 1"], + ["R = inference_limit_exceeded", "X = _1"] + ] + ); + assert_prolog_success!( + &mut wam, + "call_with_inference_limit(e(X), 4, R).", + [["R = inference_limit_exceeded", "X = _1"]] + ); + + submit( + &mut wam, + "f(X, R) :- call_with_inference_limit(g(X), 5, R).", + ); + + assert_prolog_success!( + &mut wam, + "call_with_inference_limit(f(X, R), 4, S).", + [ + ["S = true", "X = 1", "R = true"], + ["S = true", "X = 2", "R = true"], + ["S = inference_limit_exceeded", "X = _1", "R = _2"] + ] + ); + assert_prolog_success!( + &mut wam, + "call_with_inference_limit(f(X, R), 8, R).", + [ + ["R = true", "X = 1"], + ["R = true", "X = 2"], + ["R = true", "X = 3"], + ["R = true", "X = 4"], + ["R = !", "X = 5"] + ] + ); submit(&mut wam, "g(1). g(2). g(3). g(4). g(5). g(6)."); - assert_prolog_success!(&mut wam, "call_with_inference_limit(f(X, R), 8, S).", - [["R = true", "X = 1", "S = true"], - ["R = true", "X = 2", "S = true"], - ["R = true", "X = 3", "S = true"], - ["R = true", "X = 4", "S = true"], - ["R = true", "X = 5", "S = true"], - ["R = inference_limit_exceeded", "S = !", "X = _1"]]); - assert_prolog_success!(&mut wam, "call_with_inference_limit(g(X), 2, R), call_with_inference_limit(g(X), 1, S).", - [["R = true", "X = 1", "S = !"], - ["R = true", "X = 2", "S = !"], - ["R = true", "X = 3", "S = !"], - ["R = true", "X = 4", "S = !"], - ["R = true", "X = 5", "S = !"], - ["R = !", "X = 6", "S = !"]]); - assert_prolog_success!(&mut wam, "call_with_inference_limit(g(X), 2, R), call_with_inference_limit(g(X), 1, R).", - [["R = !", "X = 6"]]); - assert_prolog_success!(&mut wam, "call_with_inference_limit(g(X), 1, R), call_with_inference_limit(g(X), 1, R).", - [["R = inference_limit_exceeded", "X = _1"]]); + assert_prolog_success!( + &mut wam, + "call_with_inference_limit(f(X, R), 8, S).", + [ + ["R = true", "X = 1", "S = true"], + ["R = true", "X = 2", "S = true"], + ["R = true", "X = 3", "S = true"], + ["R = true", "X = 4", "S = true"], + ["R = true", "X = 5", "S = true"], + ["R = inference_limit_exceeded", "S = !", "X = _1"] + ] + ); + assert_prolog_success!( + &mut wam, + "call_with_inference_limit(g(X), 2, R), call_with_inference_limit(g(X), 1, S).", + [ + ["R = true", "X = 1", "S = !"], + ["R = true", "X = 2", "S = !"], + ["R = true", "X = 3", "S = !"], + ["R = true", "X = 4", "S = !"], + ["R = true", "X = 5", "S = !"], + ["R = !", "X = 6", "S = !"] + ] + ); + assert_prolog_success!( + &mut wam, + "call_with_inference_limit(g(X), 2, R), call_with_inference_limit(g(X), 1, R).", + [["R = !", "X = 6"]] + ); + assert_prolog_success!( + &mut wam, + "call_with_inference_limit(g(X), 1, R), call_with_inference_limit(g(X), 1, R).", + [["R = inference_limit_exceeded", "X = _1"]] + ); } #[test] -fn test_queries_on_dcgs() -{ +fn test_queries_on_dcgs() { let mut wam = Machine::new(readline::input_stream()); submit(&mut wam, ":- use_module('src/prolog/lib/dcgs.pl')."); // test case by YeGoblynQueene from hacker news. - submit_code(&mut wam, - " ability(destroy, X) --> destroy(X). + submit_code( + &mut wam, + " ability(destroy, X) --> destroy(X). destroy(X) --> [destroy], target(X). target(X) --> [target], permanent(X). permanent(X) --> [creature], creature(X). @@ -2169,21 +3046,26 @@ fn test_queries_on_dcgs() land('Mountain') --> []. % etc permanents sorcery('Duress') --> []. - instant('Lightning Bolt') --> []."); + instant('Lightning Bolt') --> [].", + ); - assert_prolog_success!(&mut wam, "phrase(ability(destroy, X), P).", - [["P = [destroy,target,creature]","X = 'Llanowar Elves'"], - ["P = [destroy,target,artifact]","X = 'Ankh of Mishra'"], - ["P = [destroy,target,land]","X = 'Mountain'"]]); + assert_prolog_success!( + &mut wam, + "phrase(ability(destroy, X), P).", + [ + ["P = [destroy,target,creature]", "X = 'Llanowar Elves'"], + ["P = [destroy,target,artifact]", "X = 'Ankh of Mishra'"], + ["P = [destroy,target,land]", "X = 'Mountain'"] + ] + ); } #[test] -fn test_queries_on_string_lists() -{ +fn test_queries_on_string_lists() { let mut wam = Machine::new(readline::input_stream()); submit(&mut wam, ":- use_module('src/prolog/lib/non_iso.pl')."); - + // double_quotes is chars by default. assert_prolog_success!(&mut wam, "variant(\"\", [])."); assert_prolog_failure!(&mut wam, "\"\" == []."); @@ -2202,251 +3084,459 @@ fn test_queries_on_string_lists() assert_prolog_success!(&mut wam, "\"koen\" = [k, o, e, n]."); assert_prolog_success!(&mut wam, "variant(\"koen\", [k, o, e, n])."); assert_prolog_success!(&mut wam, "variant(\"koen\", \"koen\")."); - assert_prolog_success!(&mut wam, "\"koen\" = [k, o | X].", - [["X = [e,n]"]]); - assert_prolog_success!(&mut wam, "\"koen\" = [k, o | X], X = \"en\".", - [["X = [e,n]"]]); + assert_prolog_success!(&mut wam, "\"koen\" = [k, o | X].", [["X = [e,n]"]]); + assert_prolog_success!( + &mut wam, + "\"koen\" = [k, o | X], X = \"en\".", + [["X = [e,n]"]] + ); assert_prolog_failure!(&mut wam, "\"koen\" = [k, o | X], X == \"en\"."); - assert_prolog_success!(&mut wam, "\"koen\" = [k, o | X], variant(X, \"en\").", - [["X = [e,n]"]]); + assert_prolog_success!( + &mut wam, + "\"koen\" = [k, o | X], variant(X, \"en\").", + [["X = [e,n]"]] + ); assert_prolog_failure!(&mut wam, "X = \"abc\", Y = \"abc\", X == Y."); - assert_prolog_failure!(&mut wam, "partial_string(\"abc\", X), partial_string(\"abc\", Y), X == Y."); + assert_prolog_failure!( + &mut wam, + "partial_string(\"abc\", X), partial_string(\"abc\", Y), X == Y." + ); assert_prolog_success!(&mut wam, "X = \"abc\", Y = \"abc\", variant(X, Y)."); - assert_prolog_success!(&mut wam, "partial_string(\"abc\", X), partial_string(\"abc\", Y), variant(X, Y)."); + assert_prolog_success!( + &mut wam, + "partial_string(\"abc\", X), partial_string(\"abc\", Y), variant(X, Y)." + ); submit(&mut wam, "matcher([a,b,c|X], ['d','e','f'|X])."); assert_prolog_success!(&mut wam, "matcher(\"abcdef\", \"defdef\")."); assert_prolog_failure!(&mut wam, "matcher(\"abcdef\", \"defdff\")."); - assert_prolog_success!(&mut wam, "matcher([X, Y, Z | W], [A, B, C | W]).", - [["A = d", "B = e", "C = f", "W = _1", "X = a", "Y = b", "Z = c"]]); + assert_prolog_success!( + &mut wam, + "matcher([X, Y, Z | W], [A, B, C | W]).", + [["A = d", "B = e", "C = f", "W = _1", "X = a", "Y = b", "Z = c"]] + ); assert_prolog_failure!(&mut wam, "matcher([X, Y, Z | W], [X, B, C | W])."); submit(&mut wam, "matcher([a,b,c|X], X)."); - assert_prolog_success!(&mut wam, "matcher(\"abcdef\", X), X = [d,e,f|Y], variant(Y, []), X = \"def\".", - [["X = [d,e,f]", "Y = []"]]); - assert_prolog_success!(&mut wam, "matcher(\"abcdef\", X), X = [d,e,f|Y], variant(Y, []), variant(X, \"def\").", - [["X = [d,e,f]", "Y = []"]]); - assert_prolog_success!(&mut wam, "X = ['a', 'b', 'c' | \"def\"].", - [["X = [a,b,c,d,e,f]"]]); + assert_prolog_success!( + &mut wam, + "matcher(\"abcdef\", X), X = [d,e,f|Y], variant(Y, []), X = \"def\".", + [["X = [d,e,f]", "Y = []"]] + ); + assert_prolog_success!( + &mut wam, + "matcher(\"abcdef\", X), X = [d,e,f|Y], variant(Y, []), variant(X, \"def\").", + [["X = [d,e,f]", "Y = []"]] + ); + assert_prolog_success!( + &mut wam, + "X = ['a', 'b', 'c' | \"def\"].", + [["X = [a,b,c,d,e,f]"]] + ); - assert_prolog_success!(&mut wam, "X = [a,b,c|\"abc\"].", - [["X = [a,b,c,a,b,c]"]]); + assert_prolog_success!(&mut wam, "X = [a,b,c|\"abc\"].", [["X = [a,b,c,a,b,c]"]]); assert_prolog_success!(&mut wam, "set_prolog_flag(double_quotes, atom)."); - assert_prolog_success!(&mut wam, "matcher(X, Y).", - [["X = [a,b,c|_1]", "Y = _1"]]); + assert_prolog_success!(&mut wam, "matcher(X, Y).", [["X = [a,b,c|_1]", "Y = _1"]]); assert_prolog_failure!(&mut wam, "matcher(\"abcdef\", Y)."); assert_prolog_success!(&mut wam, "set_prolog_flag(double_quotes, chars)."); - assert_prolog_success!(&mut wam, "X = \"abc\", X = ['a' | Y], set_prolog_flag(double_quotes, atom).", - [["X = \"abc\"", "Y = \"bc\""]]); + assert_prolog_success!( + &mut wam, + "X = \"abc\", X = ['a' | Y], set_prolog_flag(double_quotes, atom).", + [["X = \"abc\"", "Y = \"bc\""]] + ); // partial strings. assert_prolog_success!(&mut wam, "set_prolog_flag(double_quotes, chars)."); assert_prolog_failure!(&mut wam, "Y = 5, partial_string(\"abc\", Y)."); - assert_prolog_success!(&mut wam, "partial_string(\"abc\", X).", - [["X = [a,b,c|_]"]]); + assert_prolog_success!(&mut wam, "partial_string(\"abc\", X).", [["X = [a,b,c|_]"]]); - assert_prolog_failure!(&mut wam, "partial_string(\"abc\", X), partial_string(\"abc\", Y), matcher(X, V), - matcher(Y, Z), V = Z."); + assert_prolog_failure!( + &mut wam, + "partial_string(\"abc\", X), partial_string(\"abc\", Y), matcher(X, V), + matcher(Y, Z), V = Z." + ); submit(&mut wam, "matcher([a, b, c | X], X)."); - assert_prolog_success!(&mut wam, "partial_string(\"abc\", X), matcher(X, Y).", - [["X = [a,b,c|_]", "Y = _"]]); - assert_prolog_success!(&mut wam, "partial_string(\"abc\", X), matcher(X, Y), Y = \"def\".", - [["X = [a,b,c,d,e,f]", "Y = [d,e,f]"]]); - assert_prolog_success!(&mut wam, "partial_string(\"abc\", X), matcher(X, Y), \"def\" = Y.", - [["X = [a,b,c,d,e,f]", "Y = [d,e,f]"]]); - - assert_prolog_success!(&mut wam, "partial_string(\"abc\", X), matcher(X, Y), partial_string(\"def\", Y).", - [["X = [a,b,c,d,e,f|_]", - "Y = [d,e,f|_]"]]); - assert_prolog_success!(&mut wam, "partial_string(\"abc\", X), matcher(X, Y), partial_string(\"def\", Y), + assert_prolog_success!( + &mut wam, + "partial_string(\"abc\", X), matcher(X, Y).", + [["X = [a,b,c|_]", "Y = _"]] + ); + assert_prolog_success!( + &mut wam, + "partial_string(\"abc\", X), matcher(X, Y), Y = \"def\".", + [["X = [a,b,c,d,e,f]", "Y = [d,e,f]"]] + ); + assert_prolog_success!( + &mut wam, + "partial_string(\"abc\", X), matcher(X, Y), \"def\" = Y.", + [["X = [a,b,c,d,e,f]", "Y = [d,e,f]"]] + ); + + assert_prolog_success!( + &mut wam, + "partial_string(\"abc\", X), matcher(X, Y), partial_string(\"def\", Y).", + [["X = [a,b,c,d,e,f|_]", "Y = [d,e,f|_]"]] + ); + assert_prolog_success!( + &mut wam, + "partial_string(\"abc\", X), matcher(X, Y), partial_string(\"def\", Y), Y = \"defghijkl\".", - [["X = [a,b,c,d,e,f,g,h,i,j,k,l]", - "Y = [d,e,f,g,h,i,j,k,l]"]]); - - assert_prolog_success!(&mut wam, "partial_string(\"abc\", X), matcher(X, Y), Y = [d, e, f | G].", - [["X = [a,b,c,d,e,f|_]","Y = [d,e,f|_]","G = _"]]); - assert_prolog_success!(&mut wam, "partial_string(\"abc\",X),matcher(X,Y),[d,e,f | G] = Y.", - [["X = [a,b,c,d,e,f|_]","Y = [d,e,f|_]","G = _"]]); - assert_prolog_success!(&mut wam, "partial_string(\"abc\",X),matcher(X,Y),Y = [d,e,f | G], G = \"ghi\".", - [["X = [a,b,c,d,e,f,g,h,i]","Y = [d,e,f,g,h,i]","G = [g,h,i]"]]); - assert_prolog_success!(&mut wam, "partial_string(\"abc\",X),matcher(X,Y),Y = [d,e,f | G], + [["X = [a,b,c,d,e,f,g,h,i,j,k,l]", "Y = [d,e,f,g,h,i,j,k,l]"]] + ); + + assert_prolog_success!( + &mut wam, + "partial_string(\"abc\", X), matcher(X, Y), Y = [d, e, f | G].", + [["X = [a,b,c,d,e,f|_]", "Y = [d,e,f|_]", "G = _"]] + ); + assert_prolog_success!( + &mut wam, + "partial_string(\"abc\",X),matcher(X,Y),[d,e,f | G] = Y.", + [["X = [a,b,c,d,e,f|_]", "Y = [d,e,f|_]", "G = _"]] + ); + assert_prolog_success!( + &mut wam, + "partial_string(\"abc\",X),matcher(X,Y),Y = [d,e,f | G], G = \"ghi\".", + [[ + "X = [a,b,c,d,e,f,g,h,i]", + "Y = [d,e,f,g,h,i]", + "G = [g,h,i]" + ]] + ); + assert_prolog_success!( + &mut wam, + "partial_string(\"abc\",X),matcher(X,Y),Y = [d,e,f | G], is_partial_string(Y),G = \"ghi\".", - [["X = [a,b,c,d,e,f,g,h,i]","Y = [d,e,f,g,h,i]","G = [g,h,i]"]]); - assert_prolog_success!(&mut wam, "partial_string(\"abc\",X),matcher(X,Y),Y = [d,e,f | G], + [[ + "X = [a,b,c,d,e,f,g,h,i]", + "Y = [d,e,f,g,h,i]", + "G = [g,h,i]" + ]] + ); + assert_prolog_success!( + &mut wam, + "partial_string(\"abc\",X),matcher(X,Y),Y = [d,e,f | G], is_partial_string(Y),is_partial_string(G),G = \"ghi\".", - [["X = [a,b,c,d,e,f,g,h,i]","Y = [d,e,f,g,h,i]","G = [g,h,i]"]]); - assert_prolog_success!(&mut wam, "partial_string(\"abc\",X),partial_string(\"ababc\",Y),Y = [a,b|Z], + [[ + "X = [a,b,c,d,e,f,g,h,i]", + "Y = [d,e,f,g,h,i]", + "G = [g,h,i]" + ]] + ); + assert_prolog_success!( + &mut wam, + "partial_string(\"abc\",X),partial_string(\"ababc\",Y),Y = [a,b|Z], variant(X, Z).", - [["X = [a,b,c|_]","Y = [a,b,a,b,c|_]","Z = [a,b,c|_]"]]); - assert_prolog_failure!(&mut wam, "partial_string(\"abc\",X),partial_string(\"ababc\",Y),Y = [a,b|Z], - X == Z."); + [["X = [a,b,c|_]", "Y = [a,b,a,b,c|_]", "Z = [a,b,c|_]"]] + ); + assert_prolog_failure!( + &mut wam, + "partial_string(\"abc\",X),partial_string(\"ababc\",Y),Y = [a,b|Z], + X == Z." + ); assert_prolog_success!(&mut wam, "partial_string(\"abc\",X), X @> \"abc\"."); - assert_prolog_failure!(&mut wam, "partial_string(\"abc\",X), \\+ variant(X, \"abc\")."); + assert_prolog_failure!( + &mut wam, + "partial_string(\"abc\",X), \\+ variant(X, \"abc\")." + ); assert_prolog_failure!(&mut wam, "partial_string(\"abc\",X), X @< \"abc\"."); - assert_prolog_success!(&mut wam, "partial_string(\"ab\",X),matcher(X,Y),Y = [a,b|V], + assert_prolog_success!( + &mut wam, + "partial_string(\"ab\",X),matcher(X,Y),Y = [a,b|V], matcher(Y,Z),is_partial_string(Y).", - [["V = [c|_]","X = [a,b,c,a,b,c|_]","Y = [a,b,c|_]","Z = _"]]); - assert_prolog_success!(&mut wam, "partial_string(\"a\",X),matcher(X,Y).", - [["X = [a,b,c|_]","Y = _"]]); - assert_prolog_success!(&mut wam, "partial_string(\"a\",X),matcher(X,Y),is_partial_string(Y).", - [["X = [a,b,c|_]","Y = _"]]); - assert_prolog_success!(&mut wam, "partial_string(\"a\",X),matcher(X,Y),Y = \"def\".", - [["X = [a,b,c,d,e,f]","Y = [d,e,f]"]]); + [["V = [c|_]", "X = [a,b,c,a,b,c|_]", "Y = [a,b,c|_]", "Z = _"]] + ); + assert_prolog_success!( + &mut wam, + "partial_string(\"a\",X),matcher(X,Y).", + [["X = [a,b,c|_]", "Y = _"]] + ); + assert_prolog_success!( + &mut wam, + "partial_string(\"a\",X),matcher(X,Y),is_partial_string(Y).", + [["X = [a,b,c|_]", "Y = _"]] + ); + assert_prolog_success!( + &mut wam, + "partial_string(\"a\",X),matcher(X,Y),Y = \"def\".", + [["X = [a,b,c,d,e,f]", "Y = [d,e,f]"]] + ); - submit(&mut wam, "matcher([a,b,c|X],X). - matcher([a,b,d|X],X)."); + submit( + &mut wam, + "matcher([a,b,c|X],X). + matcher([a,b,d|X],X).", + ); - assert_prolog_success!(&mut wam, "partial_string(\"ab\",X),matcher(X,Y).", - [["X = [a,b,c|_]","Y = _"], - ["X = [a,b,d|_]","Y = _"]]); + assert_prolog_success!( + &mut wam, + "partial_string(\"ab\",X),matcher(X,Y).", + [["X = [a,b,c|_]", "Y = _"], ["X = [a,b,d|_]", "Y = _"]] + ); - submit(&mut wam, "matcher([a,b,c,d|X],X). - matcher([a,c,d|X],X)."); + submit( + &mut wam, + "matcher([a,b,c,d|X],X). + matcher([a,c,d|X],X).", + ); - assert_prolog_success!(&mut wam, "partial_string(\"ab\",X),matcher(X,Y).", - [["X = [a,b,c,d|_]","Y = _"]]); + assert_prolog_success!( + &mut wam, + "partial_string(\"ab\",X),matcher(X,Y).", + [["X = [a,b,c,d|_]", "Y = _"]] + ); - assert_prolog_success!(&mut wam, "partial_string(\"a\",X),matcher(X,Y).", - [["X = [a,b,c,d|_]","Y = _"], - ["X = [a,c,d|_]","Y = _"]]); + assert_prolog_success!( + &mut wam, + "partial_string(\"a\",X),matcher(X,Y).", + [["X = [a,b,c,d|_]", "Y = _"], ["X = [a,c,d|_]", "Y = _"]] + ); - submit(&mut wam, "matcher([a,b,c,d|X],X). + submit( + &mut wam, + "matcher([a,b,c,d|X],X). matcher([a,c,d|X],X). - matcher([a,e,f|X],X)."); - - assert_prolog_success!(&mut wam, "partial_string(\"a\",X),matcher(X,Y).", - [["X = [a,b,c,d|_]","Y = _"], - ["X = [a,c,d|_]","Y = _"], - ["X = [a,e,f|_]","Y = _"]]); - assert_prolog_success!(&mut wam, "partial_string(\"a\",X),matcher(X,Y),Y = \" t\".", - [["X = [a,b,c,d,' ',t]","Y = [' ',t]"], - ["X = [a,c,d,' ',t]","Y = [' ',t]"], - ["X = [a,e,f,' ',t]","Y = [' ',t]"]]); - - submit(&mut wam, "matcher([a,b,c|X],X) :- X = []. - matcher([a,b,c|X],X)."); - - assert_prolog_success!(&mut wam, "partial_string(\"abc\",X),matcher(X,Y).", - [["X = [a,b,c]","Y = []"], - ["X = [a,b,c|_]","Y = _"]]); - assert_prolog_success!(&mut wam, "partial_string(\"a\",X),matcher(X,Y).", - [["X = [a,b,c]","Y = []"], - ["X = [a,b,c|_]","Y = _"]]); - - assert_prolog_failure!(&mut wam, "partial_string(\"abc\",X),partial_string(\"bc\",Y),X = [a|Y]."); - - submit(&mut wam, "matcher([a|X],X) :- matcher2(X,_). + matcher([a,e,f|X],X).", + ); + + assert_prolog_success!( + &mut wam, + "partial_string(\"a\",X),matcher(X,Y).", + [ + ["X = [a,b,c,d|_]", "Y = _"], + ["X = [a,c,d|_]", "Y = _"], + ["X = [a,e,f|_]", "Y = _"] + ] + ); + assert_prolog_success!( + &mut wam, + "partial_string(\"a\",X),matcher(X,Y),Y = \" t\".", + [ + ["X = [a,b,c,d,' ',t]", "Y = [' ',t]"], + ["X = [a,c,d,' ',t]", "Y = [' ',t]"], + ["X = [a,e,f,' ',t]", "Y = [' ',t]"] + ] + ); + + submit( + &mut wam, + "matcher([a,b,c|X],X) :- X = []. + matcher([a,b,c|X],X).", + ); + + assert_prolog_success!( + &mut wam, + "partial_string(\"abc\",X),matcher(X,Y).", + [["X = [a,b,c]", "Y = []"], ["X = [a,b,c|_]", "Y = _"]] + ); + assert_prolog_success!( + &mut wam, + "partial_string(\"a\",X),matcher(X,Y).", + [["X = [a,b,c]", "Y = []"], ["X = [a,b,c|_]", "Y = _"]] + ); + + assert_prolog_failure!( + &mut wam, + "partial_string(\"abc\",X),partial_string(\"bc\",Y),X = [a|Y]." + ); + + submit( + &mut wam, + "matcher([a|X],X) :- matcher2(X,_). matcher([b|X],X) :- matcher2(X,_). matcher2([c|X],X). - matcher2([d|X],X)."); - - assert_prolog_success!(&mut wam, "partial_string(\"\",X),matcher(X,Y).", - [["X = [a,c|_]","Y = [c|_]"], - ["X = [a,d|_]","Y = [d|_]"], - ["X = [b,c|_]","Y = [c|_]"], - ["X = [b,d|_]","Y = [d|_]"]]); - assert_prolog_success!(&mut wam, "partial_string(\"a\",X),matcher(X,Y).", - [["X = [a,c|_]","Y = [c|_]"], - ["X = [a,d|_]","Y = [d|_]"]]); - assert_prolog_success!(&mut wam, "partial_string(\"b\",X),matcher(X,Y).", - [["X = [b,c|_]","Y = [c|_]"], - ["X = [b,d|_]","Y = [d|_]"]]); - assert_prolog_success!(&mut wam, "partial_string(\"bc\",X),matcher(X,Y).", - [["X = [b,c|_]","Y = [c|_]"]]); - - submit(&mut wam, "f(\"appendy jones\"). + matcher2([d|X],X).", + ); + + assert_prolog_success!( + &mut wam, + "partial_string(\"\",X),matcher(X,Y).", + [ + ["X = [a,c|_]", "Y = [c|_]"], + ["X = [a,d|_]", "Y = [d|_]"], + ["X = [b,c|_]", "Y = [c|_]"], + ["X = [b,d|_]", "Y = [d|_]"] + ] + ); + assert_prolog_success!( + &mut wam, + "partial_string(\"a\",X),matcher(X,Y).", + [["X = [a,c|_]", "Y = [c|_]"], ["X = [a,d|_]", "Y = [d|_]"]] + ); + assert_prolog_success!( + &mut wam, + "partial_string(\"b\",X),matcher(X,Y).", + [["X = [b,c|_]", "Y = [c|_]"], ["X = [b,d|_]", "Y = [d|_]"]] + ); + assert_prolog_success!( + &mut wam, + "partial_string(\"bc\",X),matcher(X,Y).", + [["X = [b,c|_]", "Y = [c|_]"]] + ); + + submit( + &mut wam, + "f(\"appendy jones\"). f(\"appendy smithers jones\"). - f(\"appendy o'toole\")."); + f(\"appendy o'toole\").", + ); - assert_prolog_success!(&mut wam, "partial_string(\"appendy\",X),f(X).", - [["X = [a,p,p,e,n,d,y,' ',j,o,n,e,s]"], - ["X = [a,p,p,e,n,d,y,' ',s,m,i,t,h,e,r,s,' ',j,o,n,e,s]"], - ["X = [a,p,p,e,n,d,y,' ',o,'\\'',t,o,o,l,e]"]]); + assert_prolog_success!( + &mut wam, + "partial_string(\"appendy\",X),f(X).", + [ + ["X = [a,p,p,e,n,d,y,' ',j,o,n,e,s]"], + ["X = [a,p,p,e,n,d,y,' ',s,m,i,t,h,e,r,s,' ',j,o,n,e,s]"], + ["X = [a,p,p,e,n,d,y,' ',o,'\\'',t,o,o,l,e]"] + ] + ); - assert_prolog_success!(&mut wam, "partial_string(\"abc\",X),partial_string(\"abcdef\",X).", - [["X = [a,b,c,d,e,f|_]"]]); - assert_prolog_success!(&mut wam, "partial_string(\"abc\",X),partial_string(\"abcdef\",X),X = \"abcdef\".", - [["X = [a,b,c,d,e,f]"]]); + assert_prolog_success!( + &mut wam, + "partial_string(\"abc\",X),partial_string(\"abcdef\",X).", + [["X = [a,b,c,d,e,f|_]"]] + ); + assert_prolog_success!( + &mut wam, + "partial_string(\"abc\",X),partial_string(\"abcdef\",X),X = \"abcdef\".", + [["X = [a,b,c,d,e,f]"]] + ); } #[test] -fn test_queries_on_attributed_variables() -{ +fn test_queries_on_attributed_variables() { let mut wam = Machine::new(readline::input_stream()); - submit(&mut wam, " + submit( + &mut wam, + " :- module(my_mod, []). :- use_module('src/prolog/lib/atts.pl'). -:- attribute dif/1, frozen/1."); +:- attribute dif/1, frozen/1.", + ); - assert_prolog_success!(&mut wam, "( put_atts(V, my_mod, dif(1)) ; put_atts(V, my_mod, dif(2)) ), + 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 = _10"], - ["L = [dif(2)]", "V = _10"]]); + [["L = [dif(1)]", "V = _10"], ["L = [dif(2)]", "V = _10"]] + ); - assert_prolog_success!(&mut wam, "put_atts(V, my_mod, frozen(a)), + 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 = _10"], - ["Ls = [dif(2)]", "V = _10"], - ["Ls = [frozen(a),dif(different)]", "V = _10"]]); + [ + ["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)]), + 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 = _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)]), + [ + ["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 = _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)]), + [ + ["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 = 2", "V = _29"]]); - assert_prolog_success!(&mut wam, "put_atts(V, my_mod, [dif(1), dif(2), frozen(a), frozen(b)]), + [["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 = _112", "Ls = [frozen(b)]", "V = _29"]]); - assert_prolog_success!(&mut wam, "put_atts(V, my_mod, [dif(1), frozen(a), dif(2), frozen(b)]), + [["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 = _114", "Ls = [frozen(b)]", "V = _29"]]); + [["A = _114", "Ls = [frozen(b)]", "V = _29"]] + ); - submit(&mut wam, ":- use_module('src/prolog/examples/minatotask.pl')."); + submit( + &mut wam, + ":- use_module('src/prolog/examples/minatotask.pl').", + ); - assert_prolog_failure!(&mut wam, "ZDD = ( X -> b(true) ; ( Y -> b(true) ; b(false) ) ), + assert_prolog_failure!( + &mut wam, + "ZDD = ( X -> b(true) ; ( Y -> b(true) ; b(false) ) ), Vs = [X,Y], variables_set_zdd(Vs, ZDD), - Vs = [1,1]."); - assert_prolog_success!(&mut wam, "ZDD = ( X -> b(true) ; ( Y -> b(true) ; b(false) ) ), + Vs = [1,1]." + ); + assert_prolog_success!( + &mut wam, + "ZDD = ( X -> b(true) ; ( Y -> b(true) ; b(false) ) ), Vs = [X,Y], variables_set_zdd(Vs, ZDD), X = 1.", - [["X = 1", "Y = 0", "Vs = [1,0]", "ZDD = (1->b(true);0->b(true);b(false))"]]); - assert_prolog_success!(&mut wam, "ZDD = ( X -> b(true) ; ( Y -> b(true) ; b(false) ) ), + [[ + "X = 1", + "Y = 0", + "Vs = [1,0]", + "ZDD = (1->b(true);0->b(true);b(false))" + ]] + ); + assert_prolog_success!( + &mut wam, + "ZDD = ( X -> b(true) ; ( Y -> b(true) ; b(false) ) ), Vs = [X,Y], variables_set_zdd(Vs, ZDD), X = 0.", - [["Vs = [0,_58]", "X = 0", "Y = _58", "ZDD = (0->b(true);_58->b(true);b(false))"]]); + [[ + "Vs = [0,_58]", + "X = 0", + "Y = _58", + "ZDD = (0->b(true);_58->b(true);b(false))" + ]] + ); } -- 2.54.0