From e0e52a30901ca7d8424d5aff959c353285077f64 Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Thu, 30 Apr 2020 00:01:00 -0600 Subject: [PATCH] fix 'drain lower bound was too large', store user-level expansions to modules (#416) --- src/prolog/codegen.rs | 4 +- src/prolog/lib/builtins.pl | 25 +++++++------ src/prolog/machine/compile.rs | 51 +++++++++++--------------- src/prolog/machine/dynamic_database.rs | 6 +++ src/prolog/machine/modules.rs | 2 + src/prolog/machine/toplevel.rs | 1 + 6 files changed, 46 insertions(+), 43 deletions(-) diff --git a/src/prolog/codegen.rs b/src/prolog/codegen.rs index ffe9490d..7e0bdd86 100644 --- a/src/prolog/codegen.rs +++ b/src/prolog/codegen.rs @@ -343,7 +343,9 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator { &mut ControlInstruction::CallClause(_, _, _, ref mut last_call, _) => { *last_call = true } - &mut ControlInstruction::JmpBy(_, _, _, ref mut last_call) => *last_call = true, + &mut ControlInstruction::JmpBy(_, _, _, ref mut last_call) => { + *last_call = true + } &mut ControlInstruction::Proceed => {} _ => dealloc_index += 1, }, diff --git a/src/prolog/lib/builtins.pl b/src/prolog/lib/builtins.pl index 7a1a7061..381c6131 100644 --- a/src/prolog/lib/builtins.pl +++ b/src/prolog/lib/builtins.pl @@ -569,18 +569,19 @@ setof(Template, Goal, Solution) :- clause(H, B) :- ( var(H) -> throw(error(instantiation_error, clause/2)) - ; functor(H, Name, Arity) -> ( Name == '.' -> throw(error(type_error(callable, H), clause/2)) - ; Name == (:), Arity =:= 2 -> - arg(1, H, Module), - arg(2, H, F), - '$module_clause'(F, B, Module) - %% '$no_such_predicate' fails if H is not callable. - ; '$no_such_predicate'(H) -> '$fail' - ; '$head_is_dynamic'(H) -> '$clause_body_is_valid'(B), - '$get_clause'(H, B) - ; throw(error(permission_error(access, private_procedure, Name/Arity), - clause/2)) - ) + ; functor(H, Name, Arity) -> + ( Name == '.' -> throw(error(type_error(callable, H), clause/2)) + ; Name == (:), Arity =:= 2 -> + arg(1, H, Module), + arg(2, H, F), + '$module_clause'(F, B, Module) + %% '$no_such_predicate' fails if H is not callable. + ; '$no_such_predicate'(H) -> '$fail' + ; '$head_is_dynamic'(H) -> '$clause_body_is_valid'(B), + '$get_clause'(H, B) + ; throw(error(permission_error(access, private_procedure, Name/Arity), + clause/2)) + ) ; throw(error(type_error(callable, H), clause/2)) ). diff --git a/src/prolog/machine/compile.rs b/src/prolog/machine/compile.rs index 10bc46e9..92d71d97 100644 --- a/src/prolog/machine/compile.rs +++ b/src/prolog/machine/compile.rs @@ -188,6 +188,8 @@ fn set_first_index(code: &mut Code) { if *offset == 0 => { *offset = code_len - idx; + debug_assert!(*offset > 0); + break; } _ => {} @@ -634,7 +636,7 @@ impl ListingCompiler { .term_dir_entry_len((clause_name!("term_expansion"), 2)), orig_goal_expansion_lens: code_repo .term_dir_entry_len((clause_name!("goal_expansion"), 2)), - initialization_goals: (vec![], VecDeque::from(vec![])), + initialization_goals: (vec![], VecDeque::from(vec![])), suppress_warnings, listing_src } @@ -880,36 +882,25 @@ impl ListingCompiler { 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()) - .or_insert((Predicate::new(), VecDeque::from(vec![]))); + 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 { - module.add_expansion_record(hook, clause.clone(), queue.clone()); - module.add_local_expansion(hook, clause.clone(), queue.clone()); - } + if let Some(ref mut module) = &mut self.module { + module.add_expansion_record(hook, clause.clone(), queue.clone()); + module.add_local_expansion(hook, clause.clone(), queue.clone()); + } - (module_preds.0).0.push(clause); - module_preds.1.extend(queue.into_iter()); + (module_preds.0).0.push(clause); + module_preds.1.extend(queue.into_iter()); - (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()) - .or_insert((Predicate::new(), VecDeque::from(vec![]))); + (preds.0).0.extend((module_preds.0).0.iter().cloned()); + preds.1.extend(module_preds.1.iter().cloned()); + if !(self.module.is_some() && hook.has_module_scope()) { len += 1; queue_len += queue_len; - - (preds.0).0.push(clause); - preds.1.extend(queue.into_iter()); - - (preds.0).0.extend((module_preds.0).0.iter().cloned()); - preds.1.extend(module_preds.1.iter().cloned()); } (len, queue_len) @@ -980,12 +971,12 @@ impl ListingCompiler { Err(SessionError::from(ParserError::InvalidModuleDecl)) } } - Declaration::ModuleInitialization(query_terms, queue) => { - self.initialization_goals.0.extend(query_terms.into_iter()); - self.initialization_goals.1.extend(queue.into_iter()); + Declaration::ModuleInitialization(query_terms, queue) => { + self.initialization_goals.0.extend(query_terms.into_iter()); + self.initialization_goals.1.extend(queue.into_iter()); - Ok(()) - } + Ok(()) + } Declaration::MultiFile(..) => { Ok(()) } diff --git a/src/prolog/machine/dynamic_database.rs b/src/prolog/machine/dynamic_database.rs index 7fd0a8c1..c90a085a 100644 --- a/src/prolog/machine/dynamic_database.rs +++ b/src/prolog/machine/dynamic_database.rs @@ -307,6 +307,12 @@ impl Machine { } } } + Addr::Usize(n) => { + n + } + Addr::Fixnum(n) => { + usize::try_from(n).unwrap() + } _ => { unreachable!() } diff --git a/src/prolog/machine/modules.rs b/src/prolog/machine/modules.rs index 4c54d39b..472723a4 100644 --- a/src/prolog/machine/modules.rs +++ b/src/prolog/machine/modules.rs @@ -48,6 +48,7 @@ impl Module { (te.0) .0 .extend((self.user_term_expansions.0).0.iter().cloned()); + te.1.extend(self.user_term_expansions.1.iter().cloned()); } @@ -60,6 +61,7 @@ impl Module { (ge.0) .0 .extend((self.user_goal_expansions.0).0.iter().cloned()); + ge.1.extend(self.user_goal_expansions.1.iter().cloned()); } diff --git a/src/prolog/machine/toplevel.rs b/src/prolog/machine/toplevel.rs index c8004aca..ccc7d452 100644 --- a/src/prolog/machine/toplevel.rs +++ b/src/prolog/machine/toplevel.rs @@ -872,6 +872,7 @@ impl RelationWorker { let term = Term::Clause(Cell::default(), clause_name!(";"), terms, None); let (stub, clauses) = self.fabricate_disjunct(term); + debug_assert!(clauses.len() > 0); self.queue.push_back(clauses); Ok(QueryTerm::Jump(stub)) } -- 2.54.0