]> Repositorios git - scryer-prolog.git/commitdiff
inline metacalls
authorMark Thom <[email protected]>
Wed, 13 Jul 2022 04:39:50 +0000 (22:39 -0600)
committerMark Thom <[email protected]>
Thu, 27 Oct 2022 05:36:07 +0000 (23:36 -0600)
44 files changed:
build/instructions_template.rs
src/arena.rs
src/arithmetic.rs
src/codegen.rs
src/forms.rs
src/heap_iter.rs
src/heap_print.rs
src/iterators.rs
src/lib/builtins.pl
src/lib/clpb.pl
src/lib/clpz.pl
src/lib/dcgs.pl
src/lib/error.pl
src/lib/freeze.pl
src/lib/iso_ext.pl
src/lib/pairs.pl
src/lib/reif.pl
src/lib/tabling.pl
src/lib/terms.pl
src/loader.pl
src/machine/arithmetic_ops.rs
src/machine/attributed_variables.pl
src/machine/compile.rs
src/machine/copier.rs
src/machine/dispatch.rs
src/machine/gc.rs
src/machine/heap.rs
src/machine/load_state.rs
src/machine/loader.rs
src/machine/machine_indices.rs
src/machine/machine_state.rs
src/machine/machine_state_impl.rs
src/machine/mock_wam.rs
src/machine/mod.rs
src/machine/preprocessor.rs
src/machine/streams.rs
src/machine/system_calls.rs
src/macros.rs
src/parser/ast.rs
src/parser/lexer.rs
src/read.rs
src/targets.rs
src/toplevel.pl
src/types.rs

index ed891b4956926da3441f0a7cdd236b8a29e13fd2..51421227e8552a184e9d9dfd2c0e6fbb92c06979 100644 (file)
@@ -548,6 +548,12 @@ enum SystemClauseType {
     PredicateDefined,
     #[strum_discriminants(strum(props(Arity = "3", Name = "$strip_module")))]
     StripModule,
+    #[strum_discriminants(strum(props(Arity = "4", Name = "$compile_inline_or_expanded_goal")))]
+    CompileInlineOrExpandedGoal,
+    #[strum_discriminants(strum(props(Arity = "arity", Name = "$call_inline")))]
+    InlineCallN(usize),
+    #[strum_discriminants(strum(props(Arity = "1", Name = "$is_expanded_or_inlined")))]
+    IsExpandedOrInlined,
     REPL(REPLCodePtr),
 }
 
@@ -1435,6 +1441,12 @@ fn generate_instruction_preface() -> TokenStream {
                     &Instruction::DefaultExecuteN(arity, _) => {
                         functor!(atom!("execute_default_n"), [fixnum(arity)])
                     }
+                    &Instruction::CallInlineCallN(arity, _) => {
+                        functor!(atom!("call_n_inline"), [fixnum(arity)])
+                    }
+                    &Instruction::ExecuteInlineCallN(arity, _) => {
+                        functor!(atom!("call_n_inline"), [fixnum(arity)])
+                    }
                     &Instruction::CallTermGreaterThan(_) |
                     &Instruction::CallTermLessThan(_) |
                     &Instruction::CallTermGreaterThanOrEqual(_) |
@@ -1597,6 +1609,8 @@ fn generate_instruction_preface() -> TokenStream {
                     &Instruction::CallDeleteHeadAttribute(_) |
                     &Instruction::CallDynamicModuleResolution(..) |
                     &Instruction::CallPrepareCallClause(..) |
+                    &Instruction::CallCompileInlineOrExpandedGoal(..) |
+                    &Instruction::CallIsExpandedOrInlined(_) |
                     &Instruction::CallEnqueueAttributedVar(_) |
                     &Instruction::CallFetchGlobalVar(_) |
                     &Instruction::CallFirstStream(_) |
@@ -1804,6 +1818,8 @@ fn generate_instruction_preface() -> TokenStream {
                     &Instruction::ExecuteDeleteHeadAttribute(_) |
                     &Instruction::ExecuteDynamicModuleResolution(..) |
                     &Instruction::ExecutePrepareCallClause(..) |
+                    &Instruction::ExecuteCompileInlineOrExpandedGoal(..) |
+                    &Instruction::ExecuteIsExpandedOrInlined(_) |
                     &Instruction::ExecuteEnqueueAttributedVar(_) |
                     &Instruction::ExecuteFetchGlobalVar(_) |
                     &Instruction::ExecuteFirstStream(_) |
@@ -2412,6 +2428,12 @@ pub fn generate_instructions_rs() -> TokenStream {
                         SystemClauseType::#ident(temp_v!(1))
                     )
                 }
+            } else if ident.to_string() == "InlineCallN" {
+                quote! {
+                    (atom!(#name), arity) => ClauseType::System(
+                        SystemClauseType::#ident(arity)
+                    )
+                }
             } else {
                 quote! {
                     (atom!(#name), #arity) => ClauseType::System(
@@ -2442,6 +2464,7 @@ pub fn generate_instructions_rs() -> TokenStream {
         });
 
         let ident = variant.ident;
+
         let instr_ident = if ident != "CallContinuation" {
             format_ident!("Call{}", ident)
         } else {
@@ -2537,7 +2560,7 @@ pub fn generate_instructions_rs() -> TokenStream {
 
         if ident == "Named" {
             clause_type_from_name_and_arity_arms.push(quote! {
-                (name, arity) => ClauseType::Named(arity, name, CodeIndex::default())
+                (name, arity) => ClauseType::Named(arity, name, CodeIndex::default(arena))
             });
 
             clause_type_to_instr_arms.push(quote! {
@@ -2933,7 +2956,7 @@ pub fn generate_instructions_rs() -> TokenStream {
         }
 
         impl ClauseType {
-            pub fn from(name: Atom, arity: usize) -> ClauseType {
+            pub fn from(name: Atom, arity: usize, arena: &mut Arena) -> ClauseType {
                 match (name, arity) {
                     #(
                         #clause_type_from_name_and_arity_arms,
index 2f9a60184fc805dc917889ed3204c0bc9a08b478..bf0cd3ce8c9b2613b17162a6136d9ea703058435 100644 (file)
@@ -4,7 +4,6 @@ use crate::machine::streams::*;
 use crate::raw_block::*;
 use crate::read::*;
 
-use modular_bitfield::prelude::*;
 use ordered_float::OrderedFloat;
 use crate::parser::rug::{Integer, Rational};
 
@@ -21,7 +20,7 @@ macro_rules! arena_alloc {
     ($e:expr, $arena:expr) => {{
         let result = $e;
         #[allow(unused_unsafe)]
-        unsafe { $arena.alloc(result) }
+        unsafe { ArenaAllocated::alloc($arena, result) }
     }};
 }
 
@@ -149,6 +148,10 @@ pub enum ArenaHeaderTag {
     NullStream = 0b111100,
     TcpListener = 0b1000000,
     Dropped = 0b1000100,
+    IndexPtrDynamicUndefined = 0b1000101,
+    IndexPtrDynamicIndex = 0b1000110,
+    IndexPtrIndex = 0b1000111,
+    IndexPtrUndefined = 0b1001000,
 }
 
 #[bitfield]
@@ -234,7 +237,7 @@ impl<T: fmt::Display> fmt::Display for TypedArenaPtr<T> {
     }
 }
 
-impl<T: ?Sized> TypedArenaPtr<T> {
+impl<T: ?Sized + ArenaAllocated> TypedArenaPtr<T> {
     #[inline]
     pub const fn new(data: *mut T) -> Self {
         unsafe { TypedArenaPtr(ptr::NonNull::new_unchecked(data)) }
@@ -248,14 +251,14 @@ impl<T: ?Sized> TypedArenaPtr<T> {
     #[inline]
     pub fn header_ptr(&self) -> *const ArenaHeader {
         let mut ptr = self.as_ptr() as *const u8 as usize;
-        ptr -= mem::size_of::<*const ArenaHeader>();
+        ptr -= T::header_offset_from_payload(); // mem::size_of::<*const ArenaHeader>();
         ptr as *const ArenaHeader
     }
 
     #[inline]
     fn header_ptr_mut(&mut self) -> *mut ArenaHeader {
         let mut ptr = self.as_ptr() as *const u8 as usize;
-        ptr -= mem::size_of::<*const ArenaHeader>();
+        ptr -= T::header_offset_from_payload(); // mem::size_of::<*const ArenaHeader>();
         ptr as *mut ArenaHeader
     }
 
@@ -289,14 +292,35 @@ impl<T: ?Sized> TypedArenaPtr<T> {
     }
 }
 
-pub trait ArenaAllocated {
+pub trait ArenaAllocated: Sized {
     type PtrToAllocated;
 
     fn tag() -> ArenaHeaderTag;
     fn size(&self) -> usize;
-    fn copy_to_arena(self, dst: *mut Self) -> Self::PtrToAllocated
-    where
-        Self: Sized;
+    fn copy_to_arena(self, dst: *mut Self) -> Self::PtrToAllocated;
+
+    fn header_offset_from_payload() -> usize {
+        mem::size_of::<*const ArenaHeader>()
+    }
+
+    unsafe fn alloc(arena: &mut Arena, value: Self) -> Self::PtrToAllocated {
+        let size = value.size() + mem::size_of::<AllocSlab>();
+
+        let align = mem::align_of::<AllocSlab>();
+        let layout = alloc::Layout::from_size_align_unchecked(size, align);
+
+        let slab = alloc::alloc(layout) as *mut AllocSlab;
+
+        (*slab).next = arena.base;
+        (*slab).header = ArenaHeader::build_with(value.size() as u64, Self::tag());
+
+        let offset = (*slab).payload_offset();
+        let result = value.copy_to_arena(offset as *mut Self);
+
+        arena.base = slab;
+
+        result
+    }
 }
 
 #[derive(Copy, Clone, Debug)]
@@ -536,6 +560,49 @@ impl ArenaAllocated for TcpListener {
     }
 }
 
+impl ArenaAllocated for IndexPtr {
+    type PtrToAllocated = TypedArenaPtr<IndexPtr>;
+
+    #[inline]
+    fn tag() -> ArenaHeaderTag {
+        ArenaHeaderTag::IndexPtrUndefined
+    }
+
+    #[inline]
+    fn size(&self) -> usize {
+        mem::size_of::<Self>()
+    }
+
+    #[inline]
+    fn copy_to_arena(self, dst: *mut Self) -> Self::PtrToAllocated {
+        unsafe {
+            ptr::write(dst, self);
+            TypedArenaPtr::new(dst as *mut Self)
+        }
+    }
+
+    #[inline]
+    fn header_offset_from_payload() -> usize {
+        0
+    }
+
+    unsafe fn alloc(arena: &mut Arena, value: Self) -> Self::PtrToAllocated {
+        let size = mem::size_of::<AllocSlab>();
+
+        let align = mem::align_of::<AllocSlab>();
+        let layout = alloc::Layout::from_size_align_unchecked(size, align);
+
+        let slab = alloc::alloc(layout) as *mut AllocSlab;
+
+        (*slab).next = arena.base;
+
+        let result = value.copy_to_arena(mem::transmute::<_, *mut IndexPtr>(&(*slab).header));
+        arena.base = slab;
+
+        result
+    }
+}
+
 #[derive(Clone, Copy, Debug)]
 struct AllocSlab {
     next: *mut AllocSlab,
@@ -556,25 +623,6 @@ impl Arena {
     pub fn new() -> Self {
         Arena { base: ptr::null_mut(), f64_tbl: F64Table::new() }
     }
-
-    pub unsafe fn alloc<T: ArenaAllocated>(&mut self, value: T) -> T::PtrToAllocated {
-        let size = value.size() + mem::size_of::<AllocSlab>();
-
-        let align = mem::align_of::<AllocSlab>();
-        let layout = alloc::Layout::from_size_align_unchecked(size, align);
-
-        let slab = alloc::alloc(layout) as *mut AllocSlab;
-
-        (*slab).next = self.base;
-        (*slab).header = ArenaHeader::build_with(value.size() as u64, T::tag());
-
-        let offset = (*slab).payload_offset();
-        let result = value.copy_to_arena(offset as *mut T);
-
-        self.base = slab;
-
-        result
-    }
 }
 
 unsafe fn drop_slab_in_place(value: &mut AllocSlab) {
@@ -628,7 +676,9 @@ unsafe fn drop_slab_in_place(value: &mut AllocSlab) {
         ArenaHeaderTag::StandardErrorStream => {
             ptr::drop_in_place(value.payload_offset::<StreamLayout<StandardErrorStream>>());
         }
-        ArenaHeaderTag::NullStream => {
+        ArenaHeaderTag::NullStream | ArenaHeaderTag::IndexPtrUndefined |
+        ArenaHeaderTag::IndexPtrDynamicUndefined | ArenaHeaderTag::IndexPtrDynamicIndex |
+        ArenaHeaderTag::IndexPtrIndex => {
         }
     }
 }
@@ -745,7 +795,8 @@ mod tests {
         // integer
 
         let big_int: Integer = 2 * Integer::from(1u64 << 63);
-        let big_int_ptr: TypedArenaPtr<Integer> = arena_alloc!(big_int, wam.machine_st.arena);
+        let big_int_ptr: TypedArenaPtr<Integer> =
+            arena_alloc!(big_int, &mut wam.machine_st.arena);
 
         assert!(!big_int_ptr.as_ptr().is_null());
 
index 02870f8106baf704e11bc6d9bf2f36f73a9c6d4b..172af5bb19ac9e158df7da167e8fb72efaafdd24 100644 (file)
@@ -13,7 +13,6 @@ use crate::parser::rug::ops::PowAssign;
 use crate::parser::rug::{Assign, Integer, Rational};
 
 use crate::machine::machine_errors::*;
-use crate::machine::machine_indices::*;
 
 use ordered_float::*;
 
@@ -65,19 +64,22 @@ impl<'a> ArithInstructionIterator<'a> {
     fn from(term: &'a Term) -> Result<Self, ArithmeticError> {
         let state = match term {
             Term::AnonVar => return Err(ArithmeticError::UninstantiatedVar),
-            Term::Clause(cell, name, terms) => match ClauseType::from(*name, terms.len()) {
+            Term::Clause(cell, name, terms) => {
+                TermIterState::Clause(Level::Shallow, 0, cell, *name, terms)
+            }
+            /* match ClauseType::from(*name, terms.len()) {
                 ct @ ClauseType::Named(..) => {
                     Ok(TermIterState::Clause(Level::Shallow, 0, cell, ct, terms))
                 }
-                ClauseType::Inlined(InlinedClauseType::IsFloat(_)) => {
-                    let ct = ClauseType::Named(1, atom!("float"), CodeIndex::default());
+                ct @ ClauseType::Inlined(InlinedClauseType::IsFloat(_)) => {
+                    // let ct = ClauseType::Named(1, atom!("float"), CodeIndex::default());
                     Ok(TermIterState::Clause(Level::Shallow, 0, cell, ct, terms))
                 }
                 _ => Err(ArithmeticError::NonEvaluableFunctor(
                     Literal::Atom(*name),
                     terms.len(),
                 )),
-            }?,
+            }?,*/
             Term::Literal(cell, cons) => TermIterState::Literal(Level::Shallow, cell, cons),
             Term::Cons(..) | Term::PartialString(..) | Term::CompleteString(..) => {
                 return Err(ArithmeticError::NonEvaluableFunctor(
@@ -108,17 +110,17 @@ impl<'a> Iterator for ArithInstructionIterator<'a> {
         while let Some(iter_state) = self.state_stack.pop() {
             match iter_state {
                 TermIterState::AnonVar(_) => return Some(Err(ArithmeticError::UninstantiatedVar)),
-                TermIterState::Clause(lvl, child_num, cell, ct, subterms) => {
+                TermIterState::Clause(lvl, child_num, cell, name, subterms) => {
                     let arity = subterms.len();
 
                     if child_num == arity {
-                        return Some(Ok(ArithTermRef::Op(ct.name(), arity)));
+                        return Some(Ok(ArithTermRef::Op(name, arity)));
                     } else {
                         self.state_stack.push(TermIterState::Clause(
                             lvl,
                             child_num + 1,
                             cell,
-                            ct,
+                            name,
                             subterms,
                         ));
 
index 832c4c898ef9697638bd1d35e0a9e1d4a30b44e8..2a9d5b62fe3556f78067722ab99843b812a64463 100644 (file)
@@ -369,9 +369,15 @@ impl<'b> CodeGenerator<'b> {
                         self.marker.mark_anon_var::<Target>(lvl, term_loc, &mut target);
                     }
                 }
-                TermRef::Clause(lvl, cell, ct, terms) => {
+                TermRef::Clause(lvl, cell, name, terms) => {
                     self.marker.mark_non_var::<Target>(lvl, term_loc, cell, &mut target);
-                    target.push(Target::to_structure(ct.name(), terms.len(), cell.get()));
+                    target.push(Target::to_structure(name, terms.len(), cell.get()));
+
+                    if let Some(instr) = target.last_mut() {
+                        if let Some(term) = terms.last() {
+                            Target::trim_structure_by_last_arg(instr, term);
+                        }
+                    }
 
                     for subterm in terms {
                         self.subterm_to_instr::<Target>(subterm, term_loc, is_exposed, &mut target);
@@ -1039,10 +1045,7 @@ impl<'b> CodeGenerator<'b> {
         let iter = query_term_post_order_iter(term);
         let query = self.compile_target::<QueryInstruction, _>(iter, term_loc, is_exposed);
 
-        if !query.is_empty() {
-            code.extend(query.into_iter());
-        }
-
+        code.extend(query.into_iter());
         self.add_conditional_call(code, term, num_perm_vars_left);
     }
 
index 8433e1e6b3907a33523fb8c708a1a091c1079546..9786437090de56540dfe9b9494e5678c17d389b5 100644 (file)
@@ -154,24 +154,21 @@ impl ClauseInfo for PredicateKey {
 
 impl ClauseInfo for Term {
     fn name(&self) -> Option<Atom> {
-        //, atom_tbl: &AtomTable) -> Option<StringBuffer> {
         match self {
             Term::Clause(_, name, terms) => {
-                // let str_buf = StringBuffer::from(*name, atom_tbl);
 
-                match name.as_str() {
-                    // str_buf.as_str() {
-                    ":-" => {
+                match name {
+                    atom!(":-") => {
                         match terms.len() {
                             1 => None,            // a declaration.
-                            2 => terms[0].name(), //.map(|name| StringBuffer::from(name, atom_tbl)),
+                            2 => terms[0].name(),
                             _ => Some(*name),
                         }
                     }
                     _ => Some(*name), //str_buf),
                 }
             }
-            Term::Literal(_, Literal::Atom(name)) => Some(*name), //Some(StringBuffer::from(*name, atom_tbl)),
+            Term::Literal(_, Literal::Atom(name)) => Some(*name),
             _ => None,
         }
     }
index 4ef5e633503a706fc78e136741f288dd7bfc4846..f3b36334c9ff70125be42448f246e5b4eda09864 100644 (file)
@@ -89,6 +89,17 @@ impl<'a> Drop for StackfulPreOrderHeapIter<'a> {
     }
 }
 
+pub trait FocusedHeapIter: Iterator<Item = HeapCellValue> {
+    fn focus(&self) -> usize;
+}
+
+impl<'a> FocusedHeapIter for StackfulPreOrderHeapIter<'a> {
+    #[inline]
+    fn focus(&self) -> usize {
+        self.h
+    }
+}
+
 impl<'a> StackfulPreOrderHeapIter<'a> {
     #[inline]
     fn new(heap: &'a mut Vec<HeapCellValue>, cell: HeapCellValue) -> Self {
@@ -126,11 +137,6 @@ impl<'a> StackfulPreOrderHeapIter<'a> {
         None
     }
 
-    #[inline]
-    pub fn focus(&self) -> usize {
-        self.h
-    }
-
     #[inline]
     pub fn pop_stack(&mut self) -> Option<HeapCellValue> {
         while let Some(h) = self.stack.pop() {
@@ -271,13 +277,14 @@ pub(crate) fn stackful_preorder_iter(
 }
 
 #[derive(Debug)]
-pub(crate) struct PostOrderIterator<Iter: Iterator<Item = HeapCellValue>> {
+pub(crate) struct PostOrderIterator<Iter: FocusedHeapIter> {
+    focus: usize,
     base_iter: Iter,
     base_iter_valid: bool,
-    parent_stack: Vec<(usize, HeapCellValue)>, // number of children, parent node.
+    parent_stack: Vec<(usize, HeapCellValue, usize)>, // number of children, parent node, focus.
 }
 
-impl<Iter: Iterator<Item = HeapCellValue>> Deref for PostOrderIterator<Iter> {
+impl<Iter: FocusedHeapIter> Deref for PostOrderIterator<Iter> {
     type Target = Iter;
 
     fn deref(&self) -> &Self::Target {
@@ -285,9 +292,10 @@ impl<Iter: Iterator<Item = HeapCellValue>> Deref for PostOrderIterator<Iter> {
     }
 }
 
-impl<Iter: Iterator<Item = HeapCellValue>> PostOrderIterator<Iter> {
+impl<Iter: FocusedHeapIter> PostOrderIterator<Iter> {
     pub(crate) fn new(base_iter: Iter) -> Self {
         PostOrderIterator {
+            focus: 0,
             base_iter,
             base_iter_valid: true,
             parent_stack: vec![],
@@ -295,32 +303,36 @@ impl<Iter: Iterator<Item = HeapCellValue>> PostOrderIterator<Iter> {
     }
 }
 
-impl<Iter: Iterator<Item = HeapCellValue>> Iterator for PostOrderIterator<Iter> {
+impl<Iter: FocusedHeapIter> Iterator for PostOrderIterator<Iter> {
     type Item = HeapCellValue;
 
     fn next(&mut self) -> Option<Self::Item> {
         loop {
-            if let Some((child_count, node)) = self.parent_stack.pop() {
+            if let Some((child_count, node, focus)) = self.parent_stack.pop() {
                 if child_count == 0 {
+                    self.focus = focus;
                     return Some(node);
                 }
 
-                self.parent_stack.push((child_count - 1, node));
+                self.parent_stack.push((child_count - 1, node, focus));
             }
 
             if self.base_iter_valid {
                 if let Some(item) = self.base_iter.next() {
+                    let focus = self.base_iter.focus();
+
                     read_heap_cell!(item,
                         (HeapCellValueTag::Atom, (_name, arity)) => {
-                            self.parent_stack.push((arity, item));
+                            self.parent_stack.push((arity, item, focus));
                         }
                         (HeapCellValueTag::Lis) => {
-                            self.parent_stack.push((2, item));
+                            self.parent_stack.push((2, item, focus));
                         }
                         (HeapCellValueTag::PStr | HeapCellValueTag::PStrOffset) => {
-                            self.parent_stack.push((1, item));
+                            self.parent_stack.push((1, item, focus));
                         }
                         _ => {
+                            self.focus = focus;
                             return Some(item);
                         }
                     );
@@ -338,12 +350,19 @@ impl<Iter: Iterator<Item = HeapCellValue>> Iterator for PostOrderIterator<Iter>
     }
 }
 
+impl<Iter: FocusedHeapIter> FocusedHeapIter for PostOrderIterator<Iter> {
+    #[inline]
+    fn focus(&self) -> usize {
+        self.focus
+    }
+}
+
 pub(crate) type LeftistPostOrderHeapIter<'a> = PostOrderIterator<StackfulPreOrderHeapIter<'a>>;
 
 impl<'a> LeftistPostOrderHeapIter<'a> {
     #[inline]
     pub fn pop_stack(&mut self) {
-        if let Some((child_count, _)) = self.parent_stack.last() {
+        if let Some((child_count, ..)) = self.parent_stack.last() {
             for _ in 0 .. *child_count {
                 self.base_iter.pop_stack();
             }
index 41d2b80900130c9a15b0cd5ac697a3687f0f862f..28c2e3724c0400fd69e80f10ef677f1d7b8a7632 100644 (file)
@@ -1,6 +1,5 @@
 use crate::arena::*;
 use crate::atom_table::*;
-use crate::instructions::*;
 use crate::parser::ast::*;
 use crate::parser::rug::{Integer, Rational};
 use crate::{
@@ -377,9 +376,9 @@ impl HCValueOutputter for PrinterOutputter {
     }
 }
 
-#[inline]
-fn is_numbered_var(ct: &ClauseType, arity: usize) -> bool {
-    arity == 1 && ct.name() == atom!("$VAR")
+#[inline(always)]
+fn is_numbered_var(name: Atom, arity: usize) -> bool {
+    arity == 1 && name == atom!("$VAR")
 }
 
 #[inline]
@@ -469,7 +468,6 @@ pub fn fmt_float(mut fl: f64) -> String {
 pub struct HCPrinter<'a, Outputter> {
     outputter: Outputter,
     iter: StackfulPreOrderHeapIter<'a>,
-    arena: &'a mut Arena,
     op_dir: &'a OpDir,
     state_stack: Vec<TokenOrRedirect>,
     toplevel_spec: Option<DirectedOp>,
@@ -534,7 +532,6 @@ pub(crate) fn numbervar(offset: &Integer, addr: HeapCellValue) -> Option<String>
 impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
     pub fn new(
         heap: &'a mut Heap,
-        arena: &'a mut Arena,
         op_dir: &'a OpDir,
         output: Outputter,
         cell: HeapCellValue,
@@ -542,7 +539,6 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
         HCPrinter {
             outputter: output,
             iter: stackful_preorder_iter(heap, cell),
-            arena,
             op_dir,
             state_stack: vec![],
             toplevel_spec: None,
@@ -563,9 +559,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
         requires_space(tail, atom)
     }
 
-    fn enqueue_op(&mut self, mut max_depth: usize, ct: ClauseType, spec: OpDesc) {
-        let name = ct.name();
-
+    fn enqueue_op(&mut self, mut max_depth: usize, name: Atom, spec: OpDesc) {
         if is_postfix!(spec.get_spec()) {
             if self.check_max_depth(&mut max_depth) {
                 self.iter.pop_stack();
@@ -652,25 +646,30 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
                 self.iter.pop_stack();
             }
 
-            self.state_stack.push(TokenOrRedirect::Close);
-            self.state_stack.push(TokenOrRedirect::Atom(atom!("...")));
-            self.state_stack.push(TokenOrRedirect::Open);
+            if arity > 0 {
+                self.state_stack.push(TokenOrRedirect::Close);
+                self.state_stack.push(TokenOrRedirect::Atom(atom!("...")));
+                self.state_stack.push(TokenOrRedirect::Open);
+            }
 
             self.state_stack.push(TokenOrRedirect::Atom(name));
 
             return false;
         }
 
-        self.state_stack.push(TokenOrRedirect::Close);
+        if arity > 0 {
+            self.state_stack.push(TokenOrRedirect::Close);
 
-        for _ in 0..arity {
-            self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth));
-            self.state_stack.push(TokenOrRedirect::Comma);
-        }
+            for _ in 0..arity {
+                self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth));
+                self.state_stack.push(TokenOrRedirect::Comma);
+            }
 
-        self.state_stack.pop();
+            self.state_stack.pop();
+
+            self.state_stack.push(TokenOrRedirect::Open);
+        }
 
-        self.state_stack.push(TokenOrRedirect::Open);
         self.state_stack.push(TokenOrRedirect::Atom(name));
 
         true
@@ -763,21 +762,21 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
         false
     }
 
+    // TODO: remove ClauseType here?
     fn format_clause(
         &mut self,
         max_depth: usize,
         arity: usize,
-        ct: ClauseType,
+        name: Atom,
         op_desc: Option<OpDesc>,
     ) -> bool {
-        if self.numbervars && is_numbered_var(&ct, arity) {
+        if self.numbervars && is_numbered_var(name, arity) {
             if self.format_numbered_vars() {
                 return true;
             }
         }
 
         let dot_atom = atom!(".");
-        let name = ct.name();
 
         if let Some(spec) = op_desc {
             if dot_atom == name && is_infix!(spec.get_spec()) {
@@ -788,7 +787,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
             }
 
             if !self.ignore_ops && spec.get_prec() > 0 {
-                self.enqueue_op(max_depth, ct, spec);
+                self.enqueue_op(max_depth, name, spec);
                 return true;
             }
         }
@@ -858,7 +857,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
                     None
                 }
                 var_opt => {
-                    if is_cyclic && addr.is_compound() {
+                    if is_cyclic && addr.is_compound(self.iter.heap) {
                         // self-referential variables are marked "cyclic".
                         match var_opt {
                             Some(var) => {
@@ -1333,9 +1332,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
             self.state_stack.push(TokenOrRedirect::Close);
         }
 
-        let ct = ClauseType::from(name, arity);
-
-        if self.format_clause(max_depth, arity, ct, Some(op_desc)) && add_brackets {
+        if self.format_clause(max_depth, arity, name, Some(op_desc)) && add_brackets {
             self.state_stack.push(TokenOrRedirect::Open);
 
             if let Some(ref op) = &op {
@@ -1349,10 +1346,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
     #[allow(dead_code)]
     fn print_tcp_listener(&mut self, tcp_listener: &TcpListener, max_depth: usize) {
         let (ip, port) = if let Some(addr) = tcp_listener.local_addr().ok() {
-            (
-                addr.ip(),
-                Number::arena_from(addr.port() as usize, self.arena),
-            )
+            (addr.ip(), addr.port())
         } else {
             let disconnected_atom = atom!("$disconnected_tcp_listener");
             self.state_stack
@@ -1371,7 +1365,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
 
             self.state_stack.push(TokenOrRedirect::NumberFocus(
                 max_depth,
-                NumberFocus::Unfocused(port),
+                NumberFocus::Unfocused(Number::Fixnum(Fixnum::build_with(port as i64))),
                 None,
             ));
             self.state_stack.push(TokenOrRedirect::Comma);
@@ -1439,8 +1433,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
                         );
                     } else {
                         push_space_if_amb!(self, name.as_str(), {
-                            let ct = ClauseType::from(name, arity);
-                             self.format_clause(max_depth, arity, ct, None);
+                             self.format_clause(max_depth, arity, name, None);
                         });
                     }
                 } else if fetch_op_spec(name, arity, self.op_dir).is_some() {
@@ -1485,8 +1478,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
                         );
                 } else {
                     push_space_if_amb!(self, name.as_str(), {
-                        let ct = ClauseType::from(name, arity);
-                        self.format_clause(max_depth, arity, ct, None);
+                        self.format_clause(max_depth, arity, name, None);
                     });
                 }
             }
@@ -1536,6 +1528,9 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
                     (ArenaHeaderTag::Dropped, _value) => {
                         append_str!(self, "'$dropped_value'");
                     }
+                    (ArenaHeaderTag::IndexPtr, _index_ptr) => {
+                        append_str!(self, "'$index_ptr'");
+                    }
                     _ => {
                     }
                 );
@@ -1631,7 +1626,6 @@ mod tests {
         {
             let printer = HCPrinter::new(
                 &mut wam.machine_st.heap,
-                &mut wam.machine_st.arena,
                 &wam.op_dir,
                 PrinterOutputter::new(),
                 heap_loc_as_cell!(0)
@@ -1659,7 +1653,6 @@ mod tests {
         {
             let printer = HCPrinter::new(
                 &mut wam.machine_st.heap,
-                &mut wam.machine_st.arena,
                 &wam.op_dir,
                 PrinterOutputter::new(),
                 heap_loc_as_cell!(0)
@@ -1682,7 +1675,6 @@ mod tests {
         {
             let printer = HCPrinter::new(
                 &mut wam.machine_st.heap,
-                &mut wam.machine_st.arena,
                 &wam.op_dir,
                 PrinterOutputter::new(),
                 heap_loc_as_cell!(0)
@@ -1694,7 +1686,6 @@ mod tests {
 
             let mut printer = HCPrinter::new(
                 &mut wam.machine_st.heap,
-                &mut wam.machine_st.arena,
                 &wam.op_dir,
                 PrinterOutputter::new(),
                 heap_loc_as_cell!(0)
@@ -1726,7 +1717,6 @@ mod tests {
         {
             let printer = HCPrinter::new(
                 &mut wam.machine_st.heap,
-                &mut wam.machine_st.arena,
                 &wam.op_dir,
                 PrinterOutputter::new(),
                 heap_loc_as_cell!(0),
@@ -1744,7 +1734,6 @@ mod tests {
         {
             let printer = HCPrinter::new(
                 &mut wam.machine_st.heap,
-                &mut wam.machine_st.arena,
                 &wam.op_dir,
                 PrinterOutputter::new(),
                 heap_loc_as_cell!(0),
@@ -1760,7 +1749,6 @@ mod tests {
         {
             let mut printer = HCPrinter::new(
                 &mut wam.machine_st.heap,
-                &mut wam.machine_st.arena,
                 &wam.op_dir,
                 PrinterOutputter::new(),
                 heap_loc_as_cell!(0)
@@ -1791,7 +1779,6 @@ mod tests {
         {
             let mut printer = HCPrinter::new(
                 &mut wam.machine_st.heap,
-                &mut wam.machine_st.arena,
                 &wam.op_dir,
                 PrinterOutputter::new(),
                 heap_loc_as_cell!(0)
@@ -1813,7 +1800,6 @@ mod tests {
         {
             let printer = HCPrinter::new(
                 &mut wam.machine_st.heap,
-                &mut wam.machine_st.arena,
                 &wam.op_dir,
                 PrinterOutputter::new(),
                 pstr_loc_as_cell!(0)
@@ -1840,7 +1826,6 @@ mod tests {
         {
             let printer = HCPrinter::new(
                 &mut wam.machine_st.heap,
-                &mut wam.machine_st.arena,
                 &wam.op_dir,
                 PrinterOutputter::new(),
                 heap_loc_as_cell!(0),
index f6ee98f2ed02febf508c6451d9d98b5d2f723bfd..62054b044c95f2694ece6533fd350dfa23c1b82d 100644 (file)
@@ -1,7 +1,6 @@
 use crate::atom_table::*;
 use crate::forms::*;
 use crate::instructions::*;
-use crate::machine::machine_indices::*;
 use crate::parser::ast::*;
 
 use std::cell::Cell;
@@ -16,7 +15,7 @@ pub(crate) enum TermRef<'a> {
     AnonVar(Level),
     Cons(Level, &'a Cell<RegType>, &'a Term, &'a Term),
     Literal(Level, &'a Cell<RegType>, &'a Literal),
-    Clause(Level, &'a Cell<RegType>, ClauseType, &'a Vec<Term>),
+    Clause(Level, &'a Cell<RegType>, Atom, &'a Vec<Term>),
     PartialString(Level, &'a Cell<RegType>, &'a String, &'a Box<Term>),
     CompleteString(Level, &'a Cell<RegType>, Atom),
     Var(Level, &'a Cell<VarReg>, Rc<String>),
@@ -40,7 +39,7 @@ impl<'a> TermRef<'a> {
 pub(crate) enum TermIterState<'a> {
     AnonVar(Level),
     Literal(Level, &'a Cell<RegType>, &'a Literal),
-    Clause(Level, usize, &'a Cell<RegType>, ClauseType, &'a Vec<Term>),
+    Clause(Level, usize, &'a Cell<RegType>, Atom, &'a Vec<Term>),
     InitialCons(Level, &'a Cell<RegType>, &'a Term, &'a Term),
     FinalCons(Level, &'a Cell<RegType>, &'a Term, &'a Term),
     InitialPartialString(Level, &'a Cell<RegType>, &'a String, &'a Box<Term>),
@@ -54,8 +53,7 @@ impl<'a> TermIterState<'a> {
         match term {
             Term::AnonVar => TermIterState::AnonVar(lvl),
             Term::Clause(cell, name, subterms) => {
-                let ct = ClauseType::Named(subterms.len(), *name, CodeIndex::default());
-                TermIterState::Clause(lvl, 0, cell, ct, subterms)
+                TermIterState::Clause(lvl, 0, cell, *name, subterms)
             }
             Term::Cons(cell, head, tail) => {
                 TermIterState::InitialCons(lvl, cell, head.as_ref(), tail.as_ref())
@@ -105,7 +103,7 @@ impl<'a> QueryIterator<'a> {
                 Level::Root,
                 0,
                 r,
-                ClauseType::from(*name, terms.len()),
+                *name,
                 terms,
             ),
             Term::Var(cell, var) => TermIterState::Var(Level::Root, cell, var.clone()),
@@ -118,14 +116,14 @@ impl<'a> QueryIterator<'a> {
 
     fn new(term: &'a QueryTerm) -> Self {
         match term {
-            &QueryTerm::Clause(ref cell, ClauseType::CallN(arity), ref terms, _) => {
-                let state = TermIterState::Clause(Level::Root, 1, cell, ClauseType::CallN(arity), terms);
+            &QueryTerm::Clause(ref cell, ClauseType::CallN(_), ref terms, _) => {
+                let state = TermIterState::Clause(Level::Root, 1, cell, atom!("$call"), terms);
                 QueryIterator {
                     state_stack: vec![state],
                 }
             }
             &QueryTerm::Clause(ref cell, ref ct, ref terms, _) => {
-                let state = TermIterState::Clause(Level::Root, 0, cell, ct.clone(), terms);
+                let state = TermIterState::Clause(Level::Root, 0, cell, ct.name(), terms);
                 QueryIterator {
                     state_stack: vec![state],
                 }
@@ -167,28 +165,25 @@ impl<'a> Iterator for QueryIterator<'a> {
                 TermIterState::AnonVar(lvl) => {
                     return Some(TermRef::AnonVar(lvl));
                 }
-                TermIterState::Clause(lvl, child_num, cell, ct, child_terms) => {
+                TermIterState::Clause(lvl, child_num, cell, name, child_terms) => {
                     if child_num == child_terms.len() {
-                        match ct {
-                            ClauseType::CallN(_) => {
+                        match name {
+                            atom!("$call") if lvl == Level::Root => {
                                 self.push_subterm(Level::Shallow, &child_terms[0]);
                             }
-                            ClauseType::Named(..) => {
+                            _ => {
                                 return match lvl {
                                     Level::Root => None,
-                                    lvl => Some(TermRef::Clause(lvl, cell, ct, child_terms)),
+                                    lvl => Some(TermRef::Clause(lvl, cell, name, child_terms)),
                                 }
                             }
-                            _ => {
-                                return None;
-                            }
                         };
                     } else {
                         self.state_stack.push(TermIterState::Clause(
                             lvl,
                             child_num + 1,
                             cell,
-                            ct,
+                            name,
                             child_terms,
                         ));
 
@@ -257,8 +252,7 @@ impl<'a> FactIterator<'a> {
                 vec![TermIterState::AnonVar(Level::Root)]
             }
             Term::Clause(cell, name, terms) => {
-                let ct = ClauseType::from(*name, terms.len());
-                vec![TermIterState::Clause(Level::Root, 0, cell, ct, terms)]
+                vec![TermIterState::Clause(Level::Root, 0, cell, *name, terms)]
             }
             Term::Cons(cell, head, tail) => vec![TermIterState::InitialCons(
                 Level::Root,
@@ -305,14 +299,14 @@ impl<'a> Iterator for FactIterator<'a> {
                 TermIterState::AnonVar(lvl) => {
                     return Some(TermRef::AnonVar(lvl));
                 }
-                TermIterState::Clause(lvl, _, cell, ct, child_terms) => {
+                TermIterState::Clause(lvl, _, cell, name, child_terms) => {
                     for child_term in child_terms {
                         self.push_subterm(lvl.child_level(), child_term);
                     }
 
                     match lvl {
                         Level::Root if !self.iterable_root => continue,
-                        _ => return Some(TermRef::Clause(lvl, cell, ct, child_terms)),
+                        _ => return Some(TermRef::Clause(lvl, cell, name, child_terms)),
                     };
                 }
                 TermIterState::InitialCons(lvl, cell, head, tail) => {
index 59f214c934fffef4af1940d4553a5db155ab9361..9d7fcd022b3fce0f3dfbe308efb430f2c99e69ee 100644 (file)
@@ -1,7 +1,7 @@
 :- module(builtins, [(=)/2, (\=)/2, (\+)/1, !/0, (',')/2, (->)/2,
-                     (;)/2, (=..)/2, (:)/2, (:)/3, (:)/4, (:)/5,
+                     (;)/2, (=..)/2, /* (:)/2, (:)/3, (:)/4, (:)/5,
                      (:)/6, (:)/7, (:)/8, (:)/9, (:)/10, (:)/11,
-                     (:)/12, abolish/1, asserta/1, assertz/1,
+                     (:)/12, */ abolish/1, asserta/1, assertz/1,
                      at_end_of_stream/0, at_end_of_stream/1,
                      atom_chars/2, atom_codes/2, atom_concat/3,
                      atom_length/2, bagof/3, call/1, call/2, call/3,
@@ -41,82 +41,87 @@ false :- '$fail'.
 % Once Scryer is bootstrapped, each is replaced with a version that
 % uses expand_goal to pass the expanded goal along to '$call'.
 
-call(G) :- '$call'(G).
+call(_).
 
-call(G, A) :- '$call'(G, A).
+call(_, _).
 
-call(G, A, B) :- '$call'(G, A, B).
+call(_, _, _).
 
-call(G, A, B, C) :- '$call'(G, A, B, C).
+call(_, _, _, _).
 
-call(G, A, B, C, D) :- '$call'(G, A, B, C, D).
+call(_, _, _, _, _).
 
-call(G, A, B, C, D, E) :- '$call'(G, A, B, C, D, E).
+call(_, _, _, _, _, _).
 
-call(G, A, B, C, D, E, F) :- '$call'(G, A, B, C, D, E, F).
+call(_, _, _, _, _, _, _).
 
-call(G, A, B, C, D, E, F, G) :- '$call'(G, A, B, C, D, E, F, G).
+call(_, _, _, _, _, _, _, _).
 
-call(G, A, B, C, D, E, F, G, H) :- '$call'(G, A, B, C, D, E, F, G, H).
+call(_, _, _, _, _, _, _, _, _).
 
 % dynamic module resolution.
 
+/*
+
 Module : Predicate :-
     (  atom(Module) -> '$module_call'(Module, Predicate)
     ;  throw(error(type_error(atom, Module), (:)/2))
     ).
 
 :(Module, Predicate, A1) :-
-    (  atom(Module) ->
-       '$module_call'(A1, Module, Predicate)
+    (  atom(Module) -> '$module_call'(Module, Predicate, A1)
     ;  throw(error(type_error(atom, Module), (:)/2))
     ).
 
 :(Module, Predicate, A1, A2) :-
-    (  atom(Module) -> '$module_call'(A1, A2, Module, Predicate)
+    (  atom(Module) -> '$module_call'(Module, Predicate, A1, A2)
     ;  throw(error(type_error(atom, Module), (:)/2))
     ).
 
 :(Module, Predicate, A1, A2, A3) :-
-    (  atom(Module) -> '$module_call'(A1, A2, A3, Module, Predicate)
+    (  atom(Module) -> '$module_call'(Module, Predicate, A1, A2, A3)
     ;  throw(error(type_error(atom, Module), (:)/2))
     ).
 
 :(Module, Predicate, A1, A2, A3, A4) :-
-    (  atom(Module) -> '$module_call'(A1, A2, A3, A4, Module, Predicate)
+    (  atom(Module) -> '$module_call'(A4, Module, Predicate, A1, A2, A3)
     ;  throw(error(type_error(atom, Module), (:)/2))
     ).
 
 :(Module, Predicate, A1, A2, A3, A4, A5) :-
-    (  atom(Module) -> '$module_call'(A1, A2, A3, A4, A5, Module, Predicate)
+    (  atom(Module) -> '$module_call'(Module, Predicate, A1, A2, A3, A4, A5)
     ;  throw(error(type_error(atom, Module), (:)/2))
     ).
 
 :(Module, Predicate, A1, A2, A3, A4, A5, A6) :-
-    (  atom(Module) -> '$module_call'(A1, A2, A3, A4, A5, A6, Module, Predicate)
+    (  atom(Module) -> '$module_call'(Module, Predicate, A1, A2, A3, A4, A5, A6)
     ;  throw(error(type_error(atom, Module), (:)/2))
     ).
 
 :(Module, Predicate, A1, A2, A3, A4, A5, A6, A7) :-
-    (  atom(Module) -> '$module_call'(A1, A2, A3, A4, A5, A6, A7, Module, Predicate)
+    (  atom(Module) -> '$module_call'(Module, Predicate, A1, A2, A3, A4, A5, A6, A7)
     ;  throw(error(type_error(atom, Module), (:)/2))
     ).
 
 :(Module, Predicate, A1, A2, A3, A4, A5, A6, A7, A8) :-
-    (  atom(Module) -> '$module_call'(A1, A2, A3, A4, A5, A6, A7, A8, Module, Predicate)
+    (  atom(Module) -> '$module_call'(Module, Predicate, A1, A2, A3, A4, A5, A6, A7, A8)
     ;  throw(error(type_error(atom, Module), (:)/2))
     ).
 
 :(Module, Predicate, A1, A2, A3, A4, A5, A6, A7, A8, A9) :-
-    (  atom(Module) -> '$module_call'(A1, A2, A3, A4, A5, A6, A7, A8, A9, Module, Predicate)
+    (  atom(Module) -> '$module_call'(Module, Predicate, A1, A2, A3, A4, A5, A6, A7, A8, A9)
     ;  throw(error(type_error(atom, Module), (:)/2))
     ).
 
 :(Module, Predicate, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10) :-
-    (  atom(Module) -> '$module_call'(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, Module, Predicate)
+    (  atom(Module) -> '$module_call'(Module, Predicate, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)
     ;  throw(error(type_error(atom, Module), (:)/2))
     ).
 
+*/
+
+:- meta_predicate catch(0, ?, 0).
+
 % flags.
 
 current_prolog_flag(Flag, Value) :- Flag == max_arity, !, Value = 1023.
@@ -185,7 +190,7 @@ fail :- '$fail'.
 
 :- meta_predicate \+(0).
 
-\+ G :- '$call'(G), !, false.
+\+ G :- call(G), !, false.
 \+ _.
 
 
@@ -195,7 +200,7 @@ _ \= _.
 
 :- meta_predicate once(0).
 
-once(G) :- '$call'(G), !.
+once(G) :- call(G), !.
 
 
 repeat.
@@ -216,17 +221,17 @@ G1 -> G2 :- control_entry_point((G1 -> G2)).
 
 staggered_if_then(G1, G2) :-
     '$get_staggered_cp'(B),
-    '$call'(G1),
+    call(G1),
     '$set_cp'(B),
-    '$call'(G2).
+    call(G2).
 
 G1 ; G2 :- control_entry_point((G1 ; G2)).
 
 
 :- non_counted_backtracking staggered_sc/2.
 
-staggered_sc(G, _) :- '$call'(G).
-staggered_sc(_, G) :- '$call'(G).
+staggered_sc(G, _) :- call(G).
+staggered_sc(_, G) :- call(G).
 
 
 !.
@@ -257,7 +262,7 @@ control_entry_point_(G) :-
 :- non_counted_backtracking cont_list_to_goal/2.
 
 cont_list_goal([Cont], Cont) :- !.
-cont_list_goal(Conts, builtins:dispatch_call_list(Conts)).
+cont_list_goal(Conts, '$call'(builtins:dispatch_call_list(Conts))).
 
 
 :- non_counted_backtracking module_qualified_cut/1.
@@ -289,7 +294,7 @@ dispatch_prep(Gs, B, [Cont|Conts]) :-
           dispatch_prep(G2, B, IConts1),
           cont_list_goal(IConts0, Cont0),
           cont_list_goal(IConts1, Cont1),
-          Cont = builtins:staggered_sc(Cont0, Cont1),
+          Cont = '$call'(builtins:staggered_sc(Cont0, Cont1)),
           Conts = []
        ;  functor(Gs, ->, 2) ->
           arg(1, Gs, G1),
@@ -298,10 +303,10 @@ dispatch_prep(Gs, B, [Cont|Conts]) :-
           dispatch_prep(G2, B, IConts2),
           cont_list_goal(IConts1, Cont1),
           cont_list_goal(IConts2, Cont2),
-          Cont = builtins:staggered_if_then(Cont1, Cont2),
+          Cont = '$call'(builtins:staggered_if_then(Cont1, Cont2)),
           Conts = []
        ;  ( Gs == ! ; module_qualified_cut(Gs) ) ->
-          Cont = builtins:set_cp(B),
+          Cont = '$call'(builtins:set_cp(B)),
           Conts = []
        ;  Cont = Gs,
           Conts = []
@@ -318,56 +323,56 @@ dispatch_prep(Gs, B, [Cont|Conts]) :-
 dispatch_call_list([]).
 dispatch_call_list([G1,G2,G3,G4,G5,G6,G7,G8|Gs]) :-
     !,
-    '$call_with_inference_counting'('$call'(G1)),
-    '$call_with_inference_counting'('$call'(G2)),
-    '$call_with_inference_counting'('$call'(G3)),
-    '$call_with_inference_counting'('$call'(G4)),
-    '$call_with_inference_counting'('$call'(G5)),
-    '$call_with_inference_counting'('$call'(G6)),
-    '$call_with_inference_counting'('$call'(G7)),
-    '$call_with_inference_counting'('$call'(G8)),
+    '$call_with_inference_counting'(call(G1)),
+    '$call_with_inference_counting'(call(G2)),
+    '$call_with_inference_counting'(call(G3)),
+    '$call_with_inference_counting'(call(G4)),
+    '$call_with_inference_counting'(call(G5)),
+    '$call_with_inference_counting'(call(G6)),
+    '$call_with_inference_counting'(call(G7)),
+    '$call_with_inference_counting'(call(G8)),
     dispatch_call_list(Gs).
 dispatch_call_list([G1,G2,G3,G4,G5,G6,G7]) :-
     !,
-    '$call_with_inference_counting'('$call'(G1)),
-    '$call_with_inference_counting'('$call'(G2)),
-    '$call_with_inference_counting'('$call'(G3)),
-    '$call_with_inference_counting'('$call'(G4)),
-    '$call_with_inference_counting'('$call'(G5)),
-    '$call_with_inference_counting'('$call'(G6)),
-    '$call_with_inference_counting'('$call'(G7)).
+    '$call_with_inference_counting'(call(G1)),
+    '$call_with_inference_counting'(call(G2)),
+    '$call_with_inference_counting'(call(G3)),
+    '$call_with_inference_counting'(call(G4)),
+    '$call_with_inference_counting'(call(G5)),
+    '$call_with_inference_counting'(call(G6)),
+    '$call_with_inference_counting'(call(G7)).
 dispatch_call_list([G1,G2,G3,G4,G5,G6]) :-
     !,
-    '$call_with_inference_counting'('$call'(G1)),
-    '$call_with_inference_counting'('$call'(G2)),
-    '$call_with_inference_counting'('$call'(G3)),
-    '$call_with_inference_counting'('$call'(G4)),
-    '$call_with_inference_counting'('$call'(G5)),
-    '$call_with_inference_counting'('$call'(G6)).
+    '$call_with_inference_counting'(call(G1)),
+    '$call_with_inference_counting'(call(G2)),
+    '$call_with_inference_counting'(call(G3)),
+    '$call_with_inference_counting'(call(G4)),
+    '$call_with_inference_counting'(call(G5)),
+    '$call_with_inference_counting'(call(G6)).
 dispatch_call_list([G1,G2,G3,G4,G5]) :-
     !,
-    '$call_with_inference_counting'('$call'(G1)),
-    '$call_with_inference_counting'('$call'(G2)),
-    '$call_with_inference_counting'('$call'(G3)),
-    '$call_with_inference_counting'('$call'(G4)),
-    '$call_with_inference_counting'('$call'(G5)).
+    '$call_with_inference_counting'(call(G1)),
+    '$call_with_inference_counting'(call(G2)),
+    '$call_with_inference_counting'(call(G3)),
+    '$call_with_inference_counting'(call(G4)),
+    '$call_with_inference_counting'(call(G5)).
 dispatch_call_list([G1,G2,G3,G4]) :-
     !,
-    '$call_with_inference_counting'('$call'(G1)),
-    '$call_with_inference_counting'('$call'(G2)),
-    '$call_with_inference_counting'('$call'(G3)),
-    '$call_with_inference_counting'('$call'(G4)).
+    '$call_with_inference_counting'(call(G1)),
+    '$call_with_inference_counting'(call(G2)),
+    '$call_with_inference_counting'(call(G3)),
+    '$call_with_inference_counting'(call(G4)).
 dispatch_call_list([G1,G2,G3]) :-
     !,
-    '$call_with_inference_counting'('$call'(G1)),
-    '$call_with_inference_counting'('$call'(G2)),
-    '$call_with_inference_counting'('$call'(G3)).
+    '$call_with_inference_counting'(call(G1)),
+    '$call_with_inference_counting'(call(G2)),
+    '$call_with_inference_counting'(call(G3)).
 dispatch_call_list([G1,G2]) :-
     !,
-    '$call_with_inference_counting'('$call'(G1)),
-    '$call_with_inference_counting'('$call'(G2)).
+    '$call_with_inference_counting'(call(G1)),
+    '$call_with_inference_counting'(call(G2)).
 dispatch_call_list([G1]) :-
-    '$call_with_inference_counting'('$call'(G1)).
+    '$call_with_inference_counting'(call(G1)).
 
 
 % univ.
@@ -444,7 +449,7 @@ get_args([Arg|Args], Func, I0, N) :-
     get_args(Args, Func, I1, N).
 
 
-:- meta_predicate parse_options_list(?, 0, ?, ?, ?).
+:- meta_predicate parse_options_list(?, 2, ?, ?, ?).
 
 parse_options_list(Options, Selector, DefaultPairs, OptionValues, Stub) :-
     '$skip_max_list'(_, _, Options, Tail),
@@ -455,7 +460,10 @@ parse_options_list(Options, Selector, DefaultPairs, OptionValues, Stub) :-
     ;  Tail \== [] ->
        throw(error(type_error(list, Options), Stub)) % 8.11.5.3e)
     ),
-    (  lists:maplist(nonvar, Options),
+    (  lists:maplist('$call'(nonvar), Options), % need '$call' because
+                                                % maplist isn't
+                                                % declared as a
+                                                % meta-predicate yet
        catch(lists:maplist(Selector, Options, OptionPairs0),
              error(E, _),
              builtins:throw(error(E, Stub))) ->
@@ -619,8 +627,6 @@ term_variables(Term, Vars) :-
 
 % exceptions.
 
-:- meta_predicate catch(0, ?, 0).
-
 :- non_counted_backtracking catch/3.
 
 catch(G,C,R) :-
@@ -633,7 +639,7 @@ catch(G,C,R) :-
 
 catch(G,C,R,Bb) :-
     '$install_new_block'(NBb),
-    '$call_with_inference_counting'('$call'(G)),
+    '$call_with_inference_counting'(call(G)),
     end_block(Bb, NBb).
 catch(G,C,R,Bb) :-
     '$reset_block'(Bb),
@@ -655,7 +661,7 @@ end_block(Bb, NBb) :-
 handle_ball(C, C, R) :-
     !,
     '$erase_ball',
-    '$call'(R).
+    call(R).
 handle_ball(_, _, _) :-
     '$unwind_stack'.
 
@@ -671,7 +677,7 @@ throw(Ball) :-
 :- non_counted_backtracking '$iterate_find_all'/4.
 
 '$iterate_find_all'(Template, Goal, _, LhOffset) :-
-    '$call_with_inference_counting'('$call'(Goal)),
+    '$call_with_inference_counting'(call(Goal)),
     '$copy_to_lh'(LhOffset, Template),
     '$fail'.
 '$iterate_find_all'(_, _, Solutions, LhOffset) :-
@@ -697,7 +703,7 @@ findall(Template, Goal, Solutions) :-
 :- non_counted_backtracking '$iterate_find_all_diff'/5.
 
 '$iterate_find_all_diff'(Template, Goal, _, _, LhOffset) :-
-    '$call_with_inference_counting'('$call'(Goal)),
+    '$call_with_inference_counting'(call(Goal)),
     '$copy_to_lh'(LhOffset, Template),
     '$fail'.
 '$iterate_find_all_diff'(_, _, Solutions0, Solutions1, LhOffset) :-
@@ -897,33 +903,7 @@ module_asserta_clause(Head, Body, Module) :-
     ;  throw(error(type_error(callable, Head), asserta/1))
     ).
 
-
-asserta_clause(Head, Body) :-
-    (  var(Head) ->
-       throw(error(instantiation_error, asserta/1))
-    ;  callable(Head), functor(Head, Name, Arity) ->
-       ( Name == (:),
-         Arity =:= 2 ->
-         arg(1, Head, Module),
-         arg(2, Head, HeadAndBody),
-         (  HeadAndBody = (F :- Body1) ->
-            true
-         ;  F = HeadAndBody,
-            Body1 = true
-         ),
-         module_asserta_clause(F, Body1, Module)
-       ; '$head_is_dynamic'(user, Head) ->
-          call_asserta(Head, Body, Name, Arity, user)
-       ; '$no_such_predicate'(user, Head) ->
-          call_asserta(Head, Body, Name, Arity, user)
-       ;  throw(error(permission_error(modify, static_procedure, Name/Arity),
-                      asserta/1))
-       )
-    ;  throw(error(type_error(callable, Head), asserta/1))
-    ).
-
-
-:- meta_predicate asserta(0).
+:- meta_predicate asserta(:).
 
 asserta(Clause0) :-
     loader:strip_module(Clause0, Module, Clause),
@@ -959,33 +939,7 @@ call_assertz(Head, Body, Name, Arity, Module) :-
     functor(_, Name, Arity),
     '$assertz'(Head, Body, Name, Arity, Module).
 
-
-assertz_clause(Head, Body) :-
-    (  var(Head) ->
-       throw(error(instantiation_error, assertz/1))
-    ;  callable(Head), functor(Head, Name, Arity) ->
-       (  Name == (:),
-          Arity =:= 2 ->
-          arg(1, Head, Module),
-          arg(2, Head, HeadAndBody),
-          (  HeadAndBody = (F :- Body1) ->
-             true
-          ;  F = HeadAndBody,
-             Body1 = true
-          ),
-          module_assertz_clause(F, Body1, Module)
-       ;  '$head_is_dynamic'(user, Head) ->
-          call_assertz(Head, Body, Name, Arity, user)
-       ;  '$no_such_predicate'(user, Head) ->
-          call_assertz(Head, Body, Name, Arity, user)
-       ;  throw(error(permission_error(modify, static_procedure, Name/Arity),
-                      assertz/1))
-       )
-    ;  throw(error(type_error(callable, Head), assertz/1))
-    ).
-
-
-:- meta_predicate assertz(0).
+:- meta_predicate assertz(:).
 
 assertz(Clause0) :-
     loader:strip_module(Clause0, Module, Clause),
@@ -1086,7 +1040,7 @@ retract_clause(Head, Body) :-
     ).
 
 
-:- meta_predicate retract(0).
+:- meta_predicate retract(:).
 
 retract(Clause0) :-
     loader:strip_module(Clause0, Module, Clause),
@@ -1102,7 +1056,7 @@ retract(Clause0) :-
     ).
 
 
-:- meta_predicate retractall(0).
+:- meta_predicate retractall(:).
 
 retractall(Head) :-
    retract_clause(Head, _),
@@ -1139,7 +1093,7 @@ module_abolish(Pred, Module) :-
     ).
 
 
-:- meta_predicate abolish(0).
+:- meta_predicate abolish(:).
 
 abolish(Pred) :-
     (  var(Pred) ->
index f41e2100bd84dbfb2607ede25917aa7a017b5ebc..e2e9ce662ad48e752924658fe9788050469a2ced 100644 (file)
@@ -1122,6 +1122,8 @@ indomain(1).
 % CountAnd = 1.
 % ==
 
+
+
 sat_count(Sat0, N) :-
         catch((parse_sat(Sat0, Sat),
                sat_bdd(Sat, BDD),
index bb9ffcba08f0f3b69de30f8f272555523695da5e..2c472a82bfb8f2144fa66723c8143039ae7968cd 100644 (file)
@@ -7611,7 +7611,7 @@ verify_attributes(Var, Other, Gs) :-
                 ),
                 domain_contains(Dom, Other),
                 phrase(trigger_props(Ps), [Q], [_]),
-                Gs = [phrase(do_queue, [Q], _)]
+                Gs = [phrase(clpz:do_queue, [Q], _)]
             ;   (   get_atts(Other, clpz(clpz_attr(_,_,_,OD,OPs,_))) ->
                     domains_intersection(OD, Dom, Dom1),
                     append_propagators(Ps, OPs, Ps1),
@@ -7619,7 +7619,7 @@ verify_attributes(Var, Other, Gs) :-
                     variables_same_queue([Var,Other]),
                     phrase((fd_put(Other,Dom1,Ps1),
                             trigger_props(Ps1)), [Q0], _),
-                    Gs = [phrase(do_queue, [Q0], _)]
+                    Gs = [phrase(clpz:do_queue, [Q0], _)]
                 ;   put_atts(Other, clpz(CLPZ)),
                     Gs = []
                 )
index 0c30447a417526e3d45aaab5daa595b2c3f416bb..1cfb32dfd43045a97dbf3c68fad4a89222ea7b5f 100644 (file)
@@ -18,7 +18,7 @@ load_context(GRBody, Module, GRBody0) :-
        true
     ;  prolog_load_context(module, Module) ->
        true
-    ;  true
+    ;  Module = user
     ).
 
 
@@ -34,7 +34,7 @@ phrase(GRBody, S0, S) :-
     (  var(GRBody0) ->
        instantiation_error(phrase/3)
     ;  dcg_body(GRBody0, S0, S, GRBody1, Module) ->
-       call(GRBody1)
+       call(Module:GRBody1)
     ;  type_error(callable, GRBody0, phrase/3)
     ).
 
index 08919d51e801d62ee6ba454a53345d2b11cdf632..4c5af7c2354ca728870b4be9d651b59eeb81fd52 100644 (file)
                   type_error/3
                   ]).
 
+
+:- meta_predicate check_(1, ?, ?).
+
+
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    must_be(Type, Term)
 
index c005672f1d4247d4dce78c211a9816aa20088ed1..4b235928c459c35225ab5cf69b59495735582f3a 100644 (file)
@@ -3,7 +3,7 @@
 :- use_module(library(atts)).
 :- use_module(library(dcgs)).
 
-:- meta_predicate freeze(?, 0).
+:- meta_predicate freeze(?, :).
 
 :- attribute frozen/1.
 
index 52dbd178e5dcd0ff79c021550fd22686b80c4923..b9dc1040fdd6b8305733e140ebd66fae55c6b738 100644 (file)
@@ -1,8 +1,3 @@
-%% for builtins that are not part of the ISO standard.
-%% must be loaded at the REPL with
-
-%% ?- use_module(library(iso_ext)).
-
 :- module(iso_ext, [bb_b_put/2,
                     bb_get/2,
                     bb_put/2,
@@ -14,7 +9,6 @@
                     partial_string_tail/2,
                     setup_call_cleanup/3,
                     call_nth/2,
-%                   variant/2,
                     copy_term_nat/2]).
 
 :- use_module(library(error), [can_be/2,
@@ -64,7 +58,7 @@ call_cleanup(G, C) :- setup_call_cleanup(true, G, C).
 
 setup_call_cleanup(S, G, C) :-
     '$get_b_value'(B),
-    '$call_with_inference_counting'('$call'(S)),
+    '$call_with_inference_counting'(call(S)),
     '$set_cp_by_default'(B),
     '$get_current_block'(Bb),
     (  C = _:CC,
@@ -80,7 +74,7 @@ setup_call_cleanup(S, G, C) :-
 scc_helper(C, G, Bb) :-
     '$get_cp'(Cp),
     '$install_scc_cleaner'(C, NBb),
-    '$call_with_inference_counting'('$call'(G)),
+    '$call_with_inference_counting'(call(G)),
     ( '$check_cp'(Cp) ->
       '$reset_block'(Bb),
       run_cleaners_without_handling(Cp)
@@ -115,7 +109,7 @@ run_cleaners_with_handling :-
 run_cleaners_without_handling(Cp) :-
     '$get_scc_cleaner'(C),
     '$get_level'(B),
-    '$call'(C),
+    call(C),
     '$set_cp_by_default'(B),
     run_cleaners_without_handling(Cp).
 run_cleaners_without_handling(Cp) :-
@@ -170,7 +164,7 @@ install_inference_counter(B, L, Count0) :-
 call_with_inference_limit(G, L, R, Bb, B) :-
     '$install_new_block'(NBb),
     '$install_inference_counter'(B, L, Count0),
-    '$call_with_inference_counting'('$call'(G)),
+    '$call_with_inference_counting'(call(G)),
     '$inference_level'(R, B),
     '$remove_inference_counter'(B, Count1),
     is(Diff, L - (Count1 - Count0)),
index d802385676682c683492a51c79324c182b507963..8ed7477752ea98ec87353cba50bb766b622e343e 100644 (file)
@@ -5,7 +5,7 @@
                  map_list_to_pairs/3]).
 
 
-:- meta_predicate map_list_to_pairs(0, ?, ?).
+:- meta_predicate map_list_to_pairs(2, ?, ?).
 
 pairs_keys_values([], [], []).
 pairs_keys_values([A-B|ABs], [A|As], [B|Bs]) :-
index c0e14989227d7543975cbc94927c10986904b26d..0e43a89729c8c28c4511054a969c36627126482e 100644 (file)
@@ -1,6 +1,6 @@
 :- module(reif, [if_/3, (=)/3, (',')/3, (;)/3, cond_t/3, dif/3,
-                memberd_t/3, tfilter/3, tmember/2, tmember_t/3,
-                tpartition/4]).
+                        memberd_t/3, tfilter/3, tmember/2, tmember_t/3,
+                        tpartition/4]).
 
 :- use_module(library(dif)).
 
@@ -30,13 +30,10 @@ non(false, true).
 
 :- meta_predicate(tfilter(2, ?, ?)).
 
-tfilter(C_2, Es, Fs) :-
-   i_tfilter(Es, C_2, Fs).
-
-i_tfilter([], _, []).
-i_tfilter([E|Es], C_2, Fs0) :-
+tfilter(_, [], []).
+tfilter(C_2, [E|Es], Fs0) :-
    if_(call(C_2, E), Fs0 = [E|Fs], Fs0 = Fs),
-   i_tfilter(Es, C_2, Fs).
+   tfilter(C_2, Es, Fs).
 
 :- meta_predicate(tpartition(2, ?, ?, ?)).
 
index 2163c791ecda22b78f719af933fe6bfafa4f087f..94dd4238bfa01ff4d3753122a675baea6cd9fb89 100644 (file)
@@ -67,7 +67,7 @@ table_and_status_for_variant(V,T,S) :-
   tbd_table_status(T,S).
 
 
-:- meta_predicate start_tabling(?, 0).
+:- meta_predicate start_tabling(?, :).
 
 start_tabling(Wrapper,Worker) :-
   put_new_trie_table_link,
index d9f41528b7260665a7ac10de01b12eadf3f42755..af817dff6e9de60f628c08e2209b64923be52786 100644 (file)
@@ -4,8 +4,8 @@
 
 numbervars(Term, N0, N) :-
    catch(internal_numbervars(Term, N0, N),
-        error(E,Ctx),
-        ( ( var(Ctx) -> Ctx = numbervars/3 ; true ), throw(error(E,Ctx) ) ) ).
+            error(E,Ctx),
+            ( ( var(Ctx) -> Ctx = numbervars/3 ; true ), throw(error(E,Ctx) ) ) ).
 
 internal_numbervars(Term, N0, N) :-
    must_be(integer, N0),
index 0179bd7bf5b94f82c61fafd90380e665b5b92a98..f454de893401abd8ad75a7c9e605666804d97db0 100644 (file)
@@ -16,7 +16,6 @@
 :- use_module(library(lists)).
 :- use_module(library(pairs)).
 
-
 write_error(Error) :-
     % '$fetch_global_var' is the core system call of bb_get/2, but
     % bb_get may not exist when write_error is first called, so fall
@@ -43,9 +42,9 @@ write_error(Error) :-
 
 expand_term(Term, ExpandedTerm) :-
     (  '$predicate_defined'(user, term_expansion, 2),
-       catch('$call'(user:term_expansion(Term, ExpandedTerm0)),
+       catch(user:term_expansion(Term, ExpandedTerm0),
              E,
-             '$call'(loader:'$print_message_and_fail'(E))) ->
+             loader:'$print_message_and_fail'(E)) ->
        (  var(ExpandedTerm0) ->
           error:instantiation_error(term_expansion/2)
        ;  ExpandedTerm0 = [_|_] ->
@@ -73,7 +72,7 @@ goal_expansion(Goal, Module, ExpandedGoal) :-
        '$predicate_defined'(Module, goal_expansion, 2),
        catch('$call'(Module:goal_expansion(Goal, ExpandedGoal0)),
              E,
-             '$call'(loader:'$print_message_and_fail'(E))) ->
+             loader:'$print_message_and_fail'(E)) ->
        (  var(ExpandedGoal0) ->
           error:instantiation_error(goal_expansion/2)
        ;  goal_expansion(ExpandedGoal0, Module, ExpandedGoal)
@@ -97,13 +96,14 @@ unload_evacuable(Evacuable) :-
 
 run_initialization_goals(Module) :-
     (  predicate_property(Module:'$initialization_goals'(_), dynamic) ->
-       % FIXME: failing here. also, see add_module.
-       findall(Module:Goal, '$call'(builtins:retract(Module:'$initialization_goals'(Goal))), Goals),
+       findall(Module:Goal, builtins:retract(Module:'$initialization_goals'(Goal)), Goals),
        abolish(Module:'$initialization_goals'/1),
        maplist(loader:success_or_warning, Goals)
     ;  true
     ).
 
+:- meta_predicate success_or_warning(0).
+
 success_or_warning(Goal) :-
     (   call(Goal) ->
         true
@@ -126,29 +126,32 @@ file_load(Stream, Path) :-
     false.        %% Clear the heap.
 file_load(_, _).
 
+file_load_init(Stream, Evacuable) :-
+    load_loop(Stream, Evacuable),
+    run_initialization_goals.
+
+file_load_cleanup(Evacuable, Error) :-
+    unload_evacuable(Evacuable),
+    '$print_message_and_fail'(Error),
+       throw(Error).
+
 file_load(Stream, Path, Evacuable) :-
     create_file_load_context(Stream, Path, Evacuable),
     % '$add_in_situ_filename_module' removes user level predicates,
     % local predicate clauses, etc. from a previous load of the file
     % at Path.
     '$add_in_situ_filename_module'(Evacuable),
-    catch((loader:load_loop(Stream, Evacuable),
-           loader:run_initialization_goals),
+    catch(loader:file_load_init(Stream, Evacuable),
           E,
-          builtins:(loader:unload_evacuable(Evacuable),
-                    loader:'$print_message_and_fail'(E),
-                           builtins:throw(E))),
+          loader:file_load_cleanup(Evacuable, E)),
     '$pop_load_context'.
 
 
 load(Stream) :-
     create_load_context(Stream, Evacuable),
-    catch((loader:load_loop(Stream, Evacuable),
-           loader:run_initialization_goals),
+    catch(loader:file_load_init(Stream, Evacuable),
           E,
-          builtins:(loader:unload_evacuable(Evacuable),
-                    loader:'$print_message_and_fail'(E),
-                           builtins:throw(E))),
+          loader:file_load_cleanup(Evacuable, E)),
     '$pop_load_context',
     false.        %% Clear the heap.
 load(_).
@@ -214,23 +217,23 @@ compile_term(Term, Evacuable) :-
     ;  compile_dispatch_or_clause(Terms, Evacuable)
     ).
 
+complete_partial_goal(N, HeadArg, InnerHeadArgs, SuppArgs, CompleteHeadArg) :-
+    integer(N),
+    N >= 0,
+    HeadArg =.. [Functor | InnerHeadArgs],
+    length(SuppArgs, N),
+    append(InnerHeadArgs, SuppArgs, InnerHeadArgs0),
+    CompleteHeadArg =.. [Functor | InnerHeadArgs0].
 
 inner_meta_specs(0, HeadArg, InnerHeadArgs, InnerMetaSpecs) :-
     !,
     predicate_property(HeadArg, meta_predicate(InnerMetaSpecs0)),
     InnerMetaSpecs0 =.. [_ | InnerMetaSpecs],
     HeadArg =.. [_ | InnerHeadArgs].
-
 inner_meta_specs((:), _, [], []) :-
     !.
-
 inner_meta_specs(N, HeadArg, InnerHeadArgs, InnerMetaSpecs) :-
-    integer(N),
-    N >= 0,
-    HeadArg =.. [Functor | InnerHeadArgs],
-    length(InnerHeadArgs1, N),
-    append(InnerHeadArgs, InnerHeadArgs1, InnerHeadArgs0),
-    CompleteHeadArg =.. [Functor | InnerHeadArgs0],
+    complete_partial_goal(N, HeadArg, InnerHeadArgs, _, CompleteHeadArg),
     predicate_property(CompleteHeadArg, meta_predicate(InnerMetaSpecs0)),
     InnerMetaSpecs0 =.. [_ | InnerMetaSpecs].
 
@@ -242,7 +245,7 @@ module_expanded_head_variables_([HeadArg | HeadArgs], [MetaSpec | MetaSpecs], He
           MetaSpec >= 0
        )  ->
        (  var(HeadArg) ->
-          HeadVars = [HeadArg-HeadArg | HeadVars1],
+          HeadVars = [HeadArg-MetaSpec | HeadVars1],
           module_expanded_head_variables_(HeadArgs, MetaSpecs, HeadVars1, HeadVars0)
        ;  inner_meta_specs(MetaSpec, HeadArg, InnerHeadArgs, InnerMetaSpecs) ->
           module_expanded_head_variables_(InnerHeadArgs, InnerMetaSpecs, HeadVars, HeadVars1),
@@ -518,6 +521,11 @@ path_atom(Dir/File, Path) :-
 path_atom(Path, Path) :-
     must_be(atom, Path).
 
+
+open_file_cleanup(Path, Stream) :-
+    atom_concat(Path, '.pl', ExtendedPath),
+    open(ExtendedPath, read, Stream).
+
 % Try to open the file with the Path name as given; if that fails,
 % append '.pl' and try again.
 open_file(Path, Stream) :-
@@ -525,9 +533,7 @@ open_file(Path, Stream) :-
        open(Path, read, Stream)
     ;  catch(open(Path, read, Stream),
              error(existence_error(source_sink, _), _),
-             ( atom_concat(Path, '.pl', ExtendedPath),
-               open(ExtendedPath, read, Stream)
-             )
+             loader:open_file_cleanup(Path, Stream)
             )
     ).
 
@@ -609,28 +615,34 @@ predicate_property(Callable, Property) :-
 strip_module(Goal, M, G) :-
     '$strip_module'(Goal, M, G).
 
+
+:- non_counted_backtracking strip_subst_module/4.
+
+strip_subst_module(Goal, M1, M2, G) :-
+    '$strip_module'(Goal, M2, G),
+    (  var(M2) ->
+       M2 = M1
+    ;  true
+    ).
+
 :- non_counted_backtracking expand_subgoal/5.
 
-expand_subgoal(UnexpandedGoals, MS, Module, ExpandedGoals, HeadVars) :-
-    (  var(UnexpandedGoals) ->
-       UnexpandedGoals = ExpandedGoals
-    ;  (  MS == 0 ->
-          % only expand complete goals. call/N will take care of incomplete goals
-          % by calling goal expansion after it is supplied the remaining arguments.
-          (  goal_expansion(UnexpandedGoals, Module, UnexpandedGoals1),
-             (  Module \== user ->
-                goal_expansion(UnexpandedGoals1, user, Goals)
-             ;  Goals = UnexpandedGoals1
-             )
-          )
-       ;  Goals = UnexpandedGoals
-       ),
-       (  inner_meta_specs(MS, Goals, _, MetaSpecs) ->
-          expand_module_names(Goals, MetaSpecs, Module, ExpandedGoals, HeadVars)
-       ;  Goals = ExpandedGoals
+expand_subgoal(UnexpandedGoals, MS, M, ExpandedGoals, HeadVars) :-
+    strip_subst_module(UnexpandedGoals, M, Module, UnexpandedGoals0),
+    nonvar(UnexpandedGoals0),
+    complete_partial_goal(MS, UnexpandedGoals0, _, SuppArgs, UnexpandedGoals1),
+    (  goal_expansion(UnexpandedGoals1, Module, UnexpandedGoals2),
+       (  Module \== user ->
+          goal_expansion(UnexpandedGoals2, user, UnexpandedGoals3)
+       ;  UnexpandedGoals3 = UnexpandedGoals2
        )
-    ;  UnexpandedGoals = ExpandedGoals
-    ).
+    ),
+    strip_subst_module(UnexpandedGoals3, Module, Module1, UnexpandedGoals4),
+    (  inner_meta_specs(0, UnexpandedGoals4, _, MetaSpecs) ->
+       expand_module_names(UnexpandedGoals4, MetaSpecs, Module1, ExpandedGoals0, HeadVars)
+    ;  ExpandedGoals0 = UnexpandedGoals4
+    ),
+    '$compile_inline_or_expanded_goal'(ExpandedGoals0, SuppArgs, ExpandedGoals, Module1).
 
 
 :- non_counted_backtracking expand_module_name/4.
@@ -650,27 +662,42 @@ expand_module_name(ESG0, MS, M, ESG) :-
     ).
 
 
+:- non_counted_backtracking eq_member/2.
+
+eq_member(V, [L-_|Ls]) :-
+    V == L.
+eq_member(V, [_|Ls]) :-
+    eq_member(V, Ls).
+
+:- non_counted_backtracking qualified_spec/1.
+
+qualified_spec((:)).
+qualified_spec(MS) :- integer(MS), MS >= 0.
+
+
 :- non_counted_backtracking expand_meta_predicate_subgoals/5.
 
 expand_meta_predicate_subgoals([SG | SGs], [MS | MSs], M, [ESG | ESGs], HeadVars) :-
-    (  (  integer(MS),
-          MS >= 0
-       ;  MS == (:)
-       )  ->
-       (  var(SG),
-          pairs:same_key(SG, HeadVars, [_|_], _) ->
-          expand_subgoal(SG, MS, M, ESG, HeadVars)
-       ;  expand_subgoal(SG, MS, M, ESG0, HeadVars),
-          expand_module_name(ESG0, MS, M, ESG)
-       ),
-       expand_meta_predicate_subgoals(SGs, MSs, M, ESGs, HeadVars)
-    ;  ESG = SG,
-       expand_meta_predicate_subgoals(SGs, MSs, M, ESGs, HeadVars)
-    ).
+    (  var(SG) ->
+       (  qualified_spec(MS) ->
+          (  eq_member(SG, HeadVars) ->
+             ESG = SG
+          ;  expand_module_name(SG, MS, M, ESG)
+          )
+       ;  ESG = SG
+       )
+    ;  MS == (:) ->
+       expand_module_name(SG, MS, M, ESG)
+    ;  '$is_expanded_or_inlined'(SG) ->
+       ESG = SG
+    ;  expand_subgoal(SG, MS, M, ESG, HeadVars) ->
+       true
+    ;  SG = ESG
+    ),
+    expand_meta_predicate_subgoals(SGs, MSs, M, ESGs, HeadVars).
 
 expand_meta_predicate_subgoals([], _, _, [], _).
 
-
 :- non_counted_backtracking expand_module_names/5.
 
 expand_module_names(Goals, MetaSpecs, Module, ExpandedGoals, HeadVars) :-
@@ -684,15 +711,17 @@ expand_module_names(Goals, MetaSpecs, Module, ExpandedGoals, HeadVars) :-
     ).
 
 
+
 :- non_counted_backtracking expand_goal/3.
 
 expand_goal(UnexpandedGoals, Module, ExpandedGoals) :-
     % if a goal isn't callable, defer to call/N to report the error.
-    catch('$call'(loader:expand_goal(UnexpandedGoals, Module, ExpandedGoals, [])),
+    catch(loader:expand_goal(UnexpandedGoals, Module, ExpandedGoals, []),
           error(type_error(callable, _), _),
-          '$call'(UnexpandedGoals = ExpandedGoals)),
+          UnexpandedGoals = ExpandedGoals),
     !.
 
+
 :- non_counted_backtracking expand_goal/4.
 
 expand_goal(UnexpandedGoals, Module, ExpandedGoals, HeadVars) :-
@@ -713,6 +742,7 @@ expand_goal(UnexpandedGoals, Module, ExpandedGoals, HeadVars) :-
        )
     ).
 
+
 :- non_counted_backtracking expand_goal_cases/4.
 
 expand_goal_cases((Goal0, Goals0), Module, ExpandedGoals, HeadVars) :-
@@ -752,6 +782,7 @@ thread_goals(Goals0, Goals1, Functor) :-
     ;  Goals1 = Goals0
     ).
 
+
 :- non_counted_backtracking thread_goals/4.
 
 thread_goals(Goals0, Goals1, Hole, Functor) :-
@@ -773,818 +804,1081 @@ thread_goals(Goals0, Goals1, Hole, Functor) :-
 % The program used to generate the call/N predicates:
 %
 %
-%
 % :- use_module(library(between)).
 % :- use_module(library(error)).
 % :- use_module(library(lists)).
 % :- use_module(library(format)).
 %
-% n_call_clause(N, Clause) :-
+% n_call_clause(N, Clauses) :-
 %     length(Args, N),
 %     Head =.. [call, G | Args],
+%     CallNHead =.. [call, '$call'(G) | Args],
 %     N1 is N + 1,
-%     CallClause0 =.. ['$prepare_call_clause', G1, M, G0 | Args],
-%     CallClause =.. ['$prepare_call_clause', G1, M, G | Args],
-%     Clause = (Head :- (  var(G) ->
-%                          instantiation_error(call/N1)
-%                       ;  G = '$call'(G0) ->
-%                          CallClause0,
-%                          '$call_with_inference_counting'('$call'(M:G1))
-%                       ;  CallClause,
-%                          expand_goal(call(M:G1), M, call(G2)),
-%                          '$call_with_inference_counting'('$call'(G2))
-%                       )
-%              ).
+%     InlineCall =.. ['$call_inline', G | Args],
+%     CallClause =.. ['$prepare_call_clause', G1, M1, G | Args],
+%     ModuleCallClause0 =.. ['$module_call', M1, G1],
+%     ModuleCallClause1 =.. ['$module_call', M2, G3],
+%     Clauses = [(Head :- var(G),
+%                         instantiation_error(call/N1)),
+%                (Head :- InlineCall),
+%                (CallNHead :- !,
+%                     CallClause,
+%                     '$call_with_inference_counting'(ModuleCallClause0)),
+%                (Head :- CallClause,
+%                         expand_goal(call(G1), M1, call(G2)),
+%                         strip_subst_module(G2, M1, M2, G3),
+%                         '$call_with_inference_counting'(ModuleCallClause1))].
 %
 % generate_call_forms :-
 %     between(1, 64, N),
-%     n_call_clause(N, Clause),
+%     n_call_clause(N, Clauses),
 %     N1 is N+1,
 %     portray_clause((:- non_counted_backtracking call/N1)),
-%     portray_clause(Clause),
+%     maplist(portray_clause, Clauses),
 %     nl,
 %     false.
+%
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 % The '$call' functor is an escape hatch from goal expansion. So far,
 % it is used only to avoid infinite recursion into expand_goal/3.
 
-:- non_counted_backtracking call/1.
+:-non_counted_backtracking call/1.
+call(G) :-
+   var(G),
+   instantiation_error(call/1).
 call(G) :-
-   (  var(G) ->
-      instantiation_error(call/1)
-   ;  G = '$call'(G0) ->
-      '$prepare_call_clause'(G1, M, G0),
-      '$call_with_inference_counting'('$call'(M:G1))
-   ;  '$prepare_call_clause'(G1, M, G),
-      expand_goal(call(M:G1), M, call(G2)),
-      '$call_with_inference_counting'('$call'(G2))
-   ).
+   '$call_inline'(G). %% '$call_inline' cuts (only) after succeeding.
+call('$call'(G0)) :-
+   !,
+   '$prepare_call_clause'(G,M,G0),
+   '$call_with_inference_counting'('$module_call'(M, G)).
+call(G) :-
+   '$prepare_call_clause'(G0,M1,G),
+   expand_goal(call(G0), M1, call(G1)),
+   strip_subst_module(G1, M1, M2, G2),
+   '$call_with_inference_counting'('$module_call'(M2, G2)).
 
 :-non_counted_backtracking call/2.
 call(A,B) :-
-   (  var(A) ->
-      instantiation_error(call/2)
-   ;  A= '$call'(C) ->
-      '$prepare_call_clause'(D,E,C,B),
-      '$call_with_inference_counting'('$call'(E:D))
-   ;  '$prepare_call_clause'(D,E,A,B),
-      expand_goal(call(E:D),E,call(F)),
-      '$call_with_inference_counting'('$call'(F))
-   ).
+   var(A),
+   instantiation_error(call/2).
+call(A,B) :-
+   '$call_inline'(A,B).
+call('$call'(A),B) :-
+   !,
+   '$prepare_call_clause'(C,D,A,B),
+   '$call_with_inference_counting'('$module_call'(D,C)).
+call(A,B) :-
+   '$prepare_call_clause'(C,D,A,B),
+   expand_goal(call(C),D,call(E)),
+   strip_subst_module(E,D,F,G),
+   '$call_with_inference_counting'('$module_call'(F,G)).
 
 :-non_counted_backtracking call/3.
 call(A,B,C) :-
-   (  var(A) ->
-      instantiation_error(call/3)
-   ;  A= '$call'(D) ->
-      '$prepare_call_clause'(E,F,D,B,C),
-      '$call_with_inference_counting'('$call'(F:E))
-   ;  '$prepare_call_clause'(E,F,A,B,C),
-      expand_goal(call(F:E),F,call(G)),
-      '$call_with_inference_counting'('$call'(G))
-   ).
+   var(A),
+   instantiation_error(call/3).
+call(A,B,C) :-
+   '$call_inline'(A,B,C).
+call('$call'(A),B,C) :-
+   !,
+   '$prepare_call_clause'(D,E,A,B,C),
+   '$call_with_inference_counting'('$module_call'(E,D)).
+call(A,B,C) :-
+   '$prepare_call_clause'(D,E,A,B,C),
+   expand_goal(call(D),E,call(F)),
+   strip_subst_module(F,E,G,H),
+   '$call_with_inference_counting'('$module_call'(G,H)).
 
 :-non_counted_backtracking call/4.
 call(A,B,C,D) :-
-   (  var(A) ->
-      instantiation_error(call/4)
-   ;  A= '$call'(E) ->
-      '$prepare_call_clause'(F,G,E,B,C,D),
-      '$call_with_inference_counting'('$call'(G:F))
-   ;  '$prepare_call_clause'(F,G,A,B,C,D),
-      expand_goal(call(G:F),G,call(H)),
-      '$call_with_inference_counting'('$call'(H))
-   ).
+   var(A),
+   instantiation_error(call/4).
+call(A,B,C,D) :-
+   '$call_inline'(A,B,C,D).
+call('$call'(A),B,C,D) :-
+   !,
+   '$prepare_call_clause'(E,F,A,B,C,D),
+   '$call_with_inference_counting'('$module_call'(F,E)).
+call(A,B,C,D) :-
+   '$prepare_call_clause'(E,F,A,B,C,D),
+   expand_goal(call(E),F,call(G)),
+   strip_subst_module(G,F,H,I),
+   '$call_with_inference_counting'('$module_call'(H,I)).
 
 :-non_counted_backtracking call/5.
 call(A,B,C,D,E) :-
-   (  var(A) ->
-      instantiation_error(call/5)
-   ;  A= '$call'(F) ->
-      '$prepare_call_clause'(G,H,F,B,C,D,E),
-      '$call_with_inference_counting'('$call'(H:G))
-   ;  '$prepare_call_clause'(G,H,A,B,C,D,E),
-      expand_goal(call(H:G),H,call(I)),
-      '$call_with_inference_counting'('$call'(I))
-   ).
+   var(A),
+   instantiation_error(call/5).
+call(A,B,C,D,E) :-
+   '$call_inline'(A,B,C,D,E).
+call('$call'(A),B,C,D,E) :-
+   !,
+   '$prepare_call_clause'(F,G,A,B,C,D,E),
+   '$call_with_inference_counting'('$module_call'(G,F)).
+call(A,B,C,D,E) :-
+   '$prepare_call_clause'(F,G,A,B,C,D,E),
+   expand_goal(call(F),G,call(H)),
+   strip_subst_module(H,G,I,J),
+   '$call_with_inference_counting'('$module_call'(I,J)).
 
 :-non_counted_backtracking call/6.
 call(A,B,C,D,E,F) :-
-   (  var(A) ->
-      instantiation_error(call/6)
-   ;  A= '$call'(G) ->
-      '$prepare_call_clause'(H,I,G,B,C,D,E,F),
-      '$call_with_inference_counting'('$call'(I:H))
-   ;  '$prepare_call_clause'(H,I,A,B,C,D,E,F),
-      expand_goal(call(I:H),I,call(J)),
-      '$call_with_inference_counting'('$call'(J))
-   ).
+   var(A),
+   instantiation_error(call/6).
+call(A,B,C,D,E,F) :-
+   '$call_inline'(A,B,C,D,E,F).
+call('$call'(A),B,C,D,E,F) :-
+   !,
+   '$prepare_call_clause'(G,H,A,B,C,D,E,F),
+   '$call_with_inference_counting'('$module_call'(H,G)).
+call(A,B,C,D,E,F) :-
+   '$prepare_call_clause'(G,H,A,B,C,D,E,F),
+   expand_goal(call(G),H,call(I)),
+   strip_subst_module(I,H,J,K),
+   '$call_with_inference_counting'('$module_call'(J,K)).
 
 :-non_counted_backtracking call/7.
 call(A,B,C,D,E,F,G) :-
-   (  var(A) ->
-      instantiation_error(call/7)
-   ;  A= '$call'(H) ->
-      '$prepare_call_clause'(I,J,H,B,C,D,E,F,G),
-      '$call_with_inference_counting'('$call'(J:I))
-   ;  '$prepare_call_clause'(I,J,A,B,C,D,E,F,G),
-      expand_goal(call(J:I),J,call(K)),
-      '$call_with_inference_counting'('$call'(K))
-   ).
+   var(A),
+   instantiation_error(call/7).
+call(A,B,C,D,E,F,G) :-
+   '$call_inline'(A,B,C,D,E,F,G).
+call('$call'(A),B,C,D,E,F,G) :-
+   !,
+   '$prepare_call_clause'(H,I,A,B,C,D,E,F,G),
+   '$call_with_inference_counting'('$module_call'(I,H)).
+call(A,B,C,D,E,F,G) :-
+   '$prepare_call_clause'(H,I,A,B,C,D,E,F,G),
+   expand_goal(call(H),I,call(J)),
+   strip_subst_module(J,I,K,L),
+   '$call_with_inference_counting'('$module_call'(K,L)).
 
 :-non_counted_backtracking call/8.
 call(A,B,C,D,E,F,G,H) :-
-   (  var(A) ->
-      instantiation_error(call/8)
-   ;  A= '$call'(I) ->
-      '$prepare_call_clause'(J,K,I,B,C,D,E,F,G,H),
-      '$call_with_inference_counting'('$call'(K:J))
-   ;  '$prepare_call_clause'(J,K,A,B,C,D,E,F,G,H),
-      expand_goal(call(K:J),K,call(L)),
-      '$call_with_inference_counting'('$call'(L))
-   ).
+   var(A),
+   instantiation_error(call/8).
+call(A,B,C,D,E,F,G,H) :-
+   '$call_inline'(A,B,C,D,E,F,G,H).
+call('$call'(A),B,C,D,E,F,G,H) :-
+   !,
+   '$prepare_call_clause'(I,J,A,B,C,D,E,F,G,H),
+   '$call_with_inference_counting'('$module_call'(J,I)).
+call(A,B,C,D,E,F,G,H) :-
+   '$prepare_call_clause'(I,J,A,B,C,D,E,F,G,H),
+   expand_goal(call(I),J,call(K)),
+   strip_subst_module(K,J,L,M),
+   '$call_with_inference_counting'('$module_call'(L,M)).
 
 :-non_counted_backtracking call/9.
 call(A,B,C,D,E,F,G,H,I) :-
-   (  var(A) ->
-      instantiation_error(call/9)
-   ;  A= '$call'(J) ->
-      '$prepare_call_clause'(K,L,J,B,C,D,E,F,G,H,I),
-      '$call_with_inference_counting'('$call'(L:K))
-   ;  '$prepare_call_clause'(K,L,A,B,C,D,E,F,G,H,I),
-      expand_goal(call(L:K),L,call(M)),
-      '$call_with_inference_counting'('$call'(M))
-   ).
+   var(A),
+   instantiation_error(call/9).
+call(A,B,C,D,E,F,G,H,I) :-
+   '$call_inline'(A,B,C,D,E,F,G,H,I).
+call('$call'(A),B,C,D,E,F,G,H,I) :-
+   !,
+   '$prepare_call_clause'(J,K,A,B,C,D,E,F,G,H,I),
+   '$call_with_inference_counting'('$module_call'(K,J)).
+call(A,B,C,D,E,F,G,H,I) :-
+   '$prepare_call_clause'(J,K,A,B,C,D,E,F,G,H,I),
+   expand_goal(call(J),K,call(L)),
+   strip_subst_module(L,K,M,N),
+   '$call_with_inference_counting'('$module_call'(M,N)).
 
 :-non_counted_backtracking call/10.
 call(A,B,C,D,E,F,G,H,I,J) :-
-   (  var(A) ->
-      instantiation_error(call/10)
-   ;  A= '$call'(K) ->
-      '$prepare_call_clause'(L,M,K,B,C,D,E,F,G,H,I,J),
-      '$call_with_inference_counting'('$call'(M:L))
-   ;  '$prepare_call_clause'(L,M,A,B,C,D,E,F,G,H,I,J),
-      expand_goal(call(M:L),M,call(N)),
-      '$call_with_inference_counting'('$call'(N))
-   ).
+   var(A),
+   instantiation_error(call/10).
+call(A,B,C,D,E,F,G,H,I,J) :-
+   '$call_inline'(A,B,C,D,E,F,G,H,I,J).
+call('$call'(A),B,C,D,E,F,G,H,I,J) :-
+   !,
+   '$prepare_call_clause'(K,L,A,B,C,D,E,F,G,H,I,J),
+   '$call_with_inference_counting'('$module_call'(L,K)).
+call(A,B,C,D,E,F,G,H,I,J) :-
+   '$prepare_call_clause'(K,L,A,B,C,D,E,F,G,H,I,J),
+   expand_goal(call(K),L,call(M)),
+   strip_subst_module(M,L,N,O),
+   '$call_with_inference_counting'('$module_call'(N,O)).
 
 :-non_counted_backtracking call/11.
 call(A,B,C,D,E,F,G,H,I,J,K) :-
-   (  var(A) ->
-      instantiation_error(call/11)
-   ;  A= '$call'(L) ->
-      '$prepare_call_clause'(M,N,L,B,C,D,E,F,G,H,I,J,K),
-      '$call_with_inference_counting'('$call'(N:M))
-   ;  '$prepare_call_clause'(M,N,A,B,C,D,E,F,G,H,I,J,K),
-      expand_goal(call(N:M),N,call(O)),
-      '$call_with_inference_counting'('$call'(O))
-   ).
+   var(A),
+   instantiation_error(call/11).
+call(A,B,C,D,E,F,G,H,I,J,K) :-
+   '$call_inline'(A,B,C,D,E,F,G,H,I,J,K).
+call('$call'(A),B,C,D,E,F,G,H,I,J,K) :-
+   !,
+   '$prepare_call_clause'(L,M,A,B,C,D,E,F,G,H,I,J,K),
+   '$call_with_inference_counting'('$module_call'(M,L)).
+call(A,B,C,D,E,F,G,H,I,J,K) :-
+   '$prepare_call_clause'(L,M,A,B,C,D,E,F,G,H,I,J,K),
+   expand_goal(call(L),M,call(N)),
+   strip_subst_module(N,M,O,P),
+   '$call_with_inference_counting'('$module_call'(O,P)).
 
 :-non_counted_backtracking call/12.
 call(A,B,C,D,E,F,G,H,I,J,K,L) :-
-   (  var(A) ->
-      instantiation_error(call/12)
-   ;  A= '$call'(M) ->
-      '$prepare_call_clause'(N,O,M,B,C,D,E,F,G,H,I,J,K,L),
-      '$call_with_inference_counting'('$call'(O:N))
-   ;  '$prepare_call_clause'(N,O,A,B,C,D,E,F,G,H,I,J,K,L),
-      expand_goal(call(O:N),O,call(P)),
-      '$call_with_inference_counting'('$call'(P))
-   ).
+   var(A),
+   instantiation_error(call/12).
+call(A,B,C,D,E,F,G,H,I,J,K,L) :-
+   '$call_inline'(A,B,C,D,E,F,G,H,I,J,K,L).
+call('$call'(A),B,C,D,E,F,G,H,I,J,K,L) :-
+   !,
+   '$prepare_call_clause'(M,N,A,B,C,D,E,F,G,H,I,J,K,L),
+   '$call_with_inference_counting'('$module_call'(N,M)).
+call(A,B,C,D,E,F,G,H,I,J,K,L) :-
+   '$prepare_call_clause'(M,N,A,B,C,D,E,F,G,H,I,J,K,L),
+   expand_goal(call(M),N,call(O)),
+   strip_subst_module(O,N,P,Q),
+   '$call_with_inference_counting'('$module_call'(P,Q)).
 
 :-non_counted_backtracking call/13.
 call(A,B,C,D,E,F,G,H,I,J,K,L,M) :-
-   (  var(A) ->
-      instantiation_error(call/13)
-   ;  A= '$call'(N) ->
-      '$prepare_call_clause'(O,P,N,B,C,D,E,F,G,H,I,J,K,L,M),
-      '$call_with_inference_counting'('$call'(P:O))
-   ;  '$prepare_call_clause'(O,P,A,B,C,D,E,F,G,H,I,J,K,L,M),
-      expand_goal(call(P:O),P,call(Q)),
-      '$call_with_inference_counting'('$call'(Q))
-   ).
+   var(A),
+   instantiation_error(call/13).
+call(A,B,C,D,E,F,G,H,I,J,K,L,M) :-
+   '$call_inline'(A,B,C,D,E,F,G,H,I,J,K,L,M).
+call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M) :-
+   !,
+   '$prepare_call_clause'(N,O,A,B,C,D,E,F,G,H,I,J,K,L,M),
+   '$call_with_inference_counting'('$module_call'(O,N)).
+call(A,B,C,D,E,F,G,H,I,J,K,L,M) :-
+   '$prepare_call_clause'(N,O,A,B,C,D,E,F,G,H,I,J,K,L,M),
+   expand_goal(call(N),O,call(P)),
+   strip_subst_module(P,O,Q,R),
+   '$call_with_inference_counting'('$module_call'(Q,R)).
 
 :-non_counted_backtracking call/14.
 call(A,B,C,D,E,F,G,H,I,J,K,L,M,N) :-
-   (  var(A) ->
-      instantiation_error(call/14)
-   ;  A= '$call'(O) ->
-      '$prepare_call_clause'(P,Q,O,B,C,D,E,F,G,H,I,J,K,L,M,N),
-      '$call_with_inference_counting'('$call'(Q:P))
-   ;  '$prepare_call_clause'(P,Q,A,B,C,D,E,F,G,H,I,J,K,L,M,N),
-      expand_goal(call(Q:P),Q,call(R)),
-      '$call_with_inference_counting'('$call'(R))
-   ).
+   var(A),
+   instantiation_error(call/14).
+call(A,B,C,D,E,F,G,H,I,J,K,L,M,N) :-
+   '$call_inline'(A,B,C,D,E,F,G,H,I,J,K,L,M,N).
+call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N) :-
+   !,
+   '$prepare_call_clause'(O,P,A,B,C,D,E,F,G,H,I,J,K,L,M,N),
+   '$call_with_inference_counting'('$module_call'(P,O)).
+call(A,B,C,D,E,F,G,H,I,J,K,L,M,N) :-
+   '$prepare_call_clause'(O,P,A,B,C,D,E,F,G,H,I,J,K,L,M,N),
+   expand_goal(call(O),P,call(Q)),
+   strip_subst_module(Q,P,R,S),
+   '$call_with_inference_counting'('$module_call'(R,S)).
 
 :-non_counted_backtracking call/15.
 call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O) :-
-   (  var(A) ->
-      instantiation_error(call/15)
-   ;  A= '$call'(P) ->
-      '$prepare_call_clause'(Q,R,P,B,C,D,E,F,G,H,I,J,K,L,M,N,O),
-      '$call_with_inference_counting'('$call'(R:Q))
-   ;  '$prepare_call_clause'(Q,R,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O),
-      expand_goal(call(R:Q),R,call(S)),
-      '$call_with_inference_counting'('$call'(S))
-   ).
+   var(A),
+   instantiation_error(call/15).
+call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O) :-
+   '$call_inline'(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O).
+call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O) :-
+   !,
+   '$prepare_call_clause'(P,Q,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O),
+   '$call_with_inference_counting'('$module_call'(Q,P)).
+call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O) :-
+   '$prepare_call_clause'(P,Q,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O),
+   expand_goal(call(P),Q,call(R)),
+   strip_subst_module(R,Q,S,T),
+   '$call_with_inference_counting'('$module_call'(S,T)).
 
 :-non_counted_backtracking call/16.
 call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P) :-
-   (  var(A) ->
-      instantiation_error(call/16)
-   ;  A= '$call'(Q) ->
-      '$prepare_call_clause'(R,S,Q,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P),
-      '$call_with_inference_counting'('$call'(S:R))
-   ;  '$prepare_call_clause'(R,S,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P),
-      expand_goal(call(S:R),S,call(T)),
-      '$call_with_inference_counting'('$call'(T))
-   ).
+   var(A),
+   instantiation_error(call/16).
+call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P) :-
+   '$call_inline'(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P).
+call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P) :-
+   !,
+   '$prepare_call_clause'(Q,R,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P),
+   '$call_with_inference_counting'('$module_call'(R,Q)).
+call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P) :-
+   '$prepare_call_clause'(Q,R,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P),
+   expand_goal(call(Q),R,call(S)),
+   strip_subst_module(S,R,T,U),
+   '$call_with_inference_counting'('$module_call'(T,U)).
 
 :-non_counted_backtracking call/17.
 call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q) :-
-   (  var(A) ->
-      instantiation_error(call/17)
-   ;  A= '$call'(R) ->
-      '$prepare_call_clause'(S,T,R,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q),
-      '$call_with_inference_counting'('$call'(T:S))
-   ;  '$prepare_call_clause'(S,T,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q),
-      expand_goal(call(T:S),T,call(U)),
-      '$call_with_inference_counting'('$call'(U))
-   ).
+   var(A),
+   instantiation_error(call/17).
+call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q) :-
+   '$call_inline'(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q).
+call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q) :-
+   !,
+   '$prepare_call_clause'(R,S,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q),
+   '$call_with_inference_counting'('$module_call'(S,R)).
+call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q) :-
+   '$prepare_call_clause'(R,S,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q),
+   expand_goal(call(R),S,call(T)),
+   strip_subst_module(T,S,U,V),
+   '$call_with_inference_counting'('$module_call'(U,V)).
 
 :-non_counted_backtracking call/18.
 call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R) :-
-   (  var(A) ->
-      instantiation_error(call/18)
-   ;  A= '$call'(S) ->
-      '$prepare_call_clause'(T,U,S,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R),
-      '$call_with_inference_counting'('$call'(U:T))
-   ;  '$prepare_call_clause'(T,U,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R),
-      expand_goal(call(U:T),U,call(V)),
-      '$call_with_inference_counting'('$call'(V))
-   ).
+   var(A),
+   instantiation_error(call/18).
+call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R) :-
+   '$call_inline'(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R).
+call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R) :-
+   !,
+   '$prepare_call_clause'(S,T,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R),
+   '$call_with_inference_counting'('$module_call'(T,S)).
+call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R) :-
+   '$prepare_call_clause'(S,T,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R),
+   expand_goal(call(S),T,call(U)),
+   strip_subst_module(U,T,V,W),
+   '$call_with_inference_counting'('$module_call'(V,W)).
 
 :-non_counted_backtracking call/19.
 call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S) :-
-   (  var(A) ->
-      instantiation_error(call/19)
-   ;  A= '$call'(T) ->
-      '$prepare_call_clause'(U,V,T,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S),
-      '$call_with_inference_counting'('$call'(V:U))
-   ;  '$prepare_call_clause'(U,V,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S),
-      expand_goal(call(V:U),V,call(W)),
-      '$call_with_inference_counting'('$call'(W))
-   ).
+   var(A),
+   instantiation_error(call/19).
+call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S) :-
+   '$call_inline'(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S).
+call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S) :-
+   !,
+   '$prepare_call_clause'(T,U,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S),
+   '$call_with_inference_counting'('$module_call'(U,T)).
+call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S) :-
+   '$prepare_call_clause'(T,U,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S),
+   expand_goal(call(T),U,call(V)),
+   strip_subst_module(V,U,W,X),
+   '$call_with_inference_counting'('$module_call'(W,X)).
 
 :-non_counted_backtracking call/20.
 call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T) :-
-   (  var(A) ->
-      instantiation_error(call/20)
-   ;  A= '$call'(U) ->
-      '$prepare_call_clause'(V,W,U,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T),
-      '$call_with_inference_counting'('$call'(W:V))
-   ;  '$prepare_call_clause'(V,W,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T),
-      expand_goal(call(W:V),W,call(X)),
-      '$call_with_inference_counting'('$call'(X))
-   ).
+   var(A),
+   instantiation_error(call/20).
+call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T) :-
+   '$call_inline'(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T).
+call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T) :-
+   !,
+   '$prepare_call_clause'(U,V,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T),
+   '$call_with_inference_counting'('$module_call'(V,U)).
+call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T) :-
+   '$prepare_call_clause'(U,V,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T),
+   expand_goal(call(U),V,call(W)),
+   strip_subst_module(W,V,X,Y),
+   '$call_with_inference_counting'('$module_call'(X,Y)).
 
 :-non_counted_backtracking call/21.
 call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U) :-
-   (  var(A) ->
-      instantiation_error(call/21)
-   ;  A= '$call'(V) ->
-      '$prepare_call_clause'(W,X,V,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U),
-      '$call_with_inference_counting'('$call'(X:W))
-   ;  '$prepare_call_clause'(W,X,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U),
-      expand_goal(call(X:W),X,call(Y)),
-      '$call_with_inference_counting'('$call'(Y))
-   ).
+   var(A),
+   instantiation_error(call/21).
+call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U) :-
+   '$call_inline'(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U).
+call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U) :-
+   !,
+   '$prepare_call_clause'(V,W,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U),
+   '$call_with_inference_counting'('$module_call'(W,V)).
+call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U) :-
+   '$prepare_call_clause'(V,W,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U),
+   expand_goal(call(V),W,call(X)),
+   strip_subst_module(X,W,Y,Z),
+   '$call_with_inference_counting'('$module_call'(Y,Z)).
 
 :-non_counted_backtracking call/22.
 call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V) :-
-   (  var(A) ->
-      instantiation_error(call/22)
-   ;  A= '$call'(W) ->
-      '$prepare_call_clause'(X,Y,W,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V),
-      '$call_with_inference_counting'('$call'(Y:X))
-   ;  '$prepare_call_clause'(X,Y,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V),
-      expand_goal(call(Y:X),Y,call(Z)),
-      '$call_with_inference_counting'('$call'(Z))
-   ).
+   var(A),
+   instantiation_error(call/22).
+call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V) :-
+   '$call_inline'(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V).
+call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V) :-
+   !,
+   '$prepare_call_clause'(W,X,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V),
+   '$call_with_inference_counting'('$module_call'(X,W)).
+call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V) :-
+   '$prepare_call_clause'(W,X,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V),
+   expand_goal(call(W),X,call(Y)),
+   strip_subst_module(Y,X,Z,A1),
+   '$call_with_inference_counting'('$module_call'(Z,A1)).
 
 :-non_counted_backtracking call/23.
 call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W) :-
-   (  var(A) ->
-      instantiation_error(call/23)
-   ;  A= '$call'(X) ->
-      '$prepare_call_clause'(Y,Z,X,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W),
-      '$call_with_inference_counting'('$call'(Z:Y))
-   ;  '$prepare_call_clause'(Y,Z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W),
-      expand_goal(call(Z:Y),Z,call(A1)),
-      '$call_with_inference_counting'('$call'(A1))
-   ).
+   var(A),
+   instantiation_error(call/23).
+call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W) :-
+   '$call_inline'(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W).
+call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W) :-
+   !,
+   '$prepare_call_clause'(X,Y,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W),
+   '$call_with_inference_counting'('$module_call'(Y,X)).
+call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W) :-
+   '$prepare_call_clause'(X,Y,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W),
+   expand_goal(call(X),Y,call(Z)),
+   strip_subst_module(Z,Y,A1,B1),
+   '$call_with_inference_counting'('$module_call'(A1,B1)).
 
 :-non_counted_backtracking call/24.
 call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X) :-
-   (  var(A) ->
-      instantiation_error(call/24)
-   ;  A= '$call'(Y) ->
-      '$prepare_call_clause'(Z,A1,Y,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X),
-      '$call_with_inference_counting'('$call'(A1:Z))
-   ;  '$prepare_call_clause'(Z,A1,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X),
-      expand_goal(call(A1:Z),A1,call(B1)),
-      '$call_with_inference_counting'('$call'(B1))
-   ).
+   var(A),
+   instantiation_error(call/24).
+call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X) :-
+   '$call_inline'(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X).
+call('$call'(A),B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X) :-
+   !,
+   '$prepare_call_clause'(Y,Z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X),
+   '$call_with_inference_counting'('$module_call'(Z,Y)).
+call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X) :-
+   '$prepare_call_clause'(Y,Z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X),
+   expand_goal(call(Y),Z,call(A1)),
+   strip_subst_module(A1,Z,B1,C1),
+   '$call_with_inference_counting'('$module_call'(B1,C1)).
 
 :-non_counted_backtracking call/25.
 call(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) :-
-   (  var(A) ->
-      instantiation_error(call/25)
-   ;  A= '$call'(Z) ->
-      '$prepare_call_clause'(A1,B1,Z,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y),
-      '$call_with_inference_counting'('$call'(B1:A1))
-   ;  '$prepare_call_clause'(A1,B1,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),
-      expand_goal(call(B1:A1),B1,call(C1)),
-      '$call_with_inference_counting'('$call'(C1))
-   ).
+   var(A),
+   instantiation_error(call/25).
+call(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) :-
+   '$call_inline'(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).
+call('$call'(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) :-
+   !,
+   '$prepare_call_clause'(Z,A1,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),
+   '$call_with_inference_counting'('$module_call'(A1,Z)).
+call(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) :-
+   '$prepare_call_clause'(Z,A1,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),
+   expand_goal(call(Z),A1,call(B1)),
+   strip_subst_module(B1,A1,C1,D1),
+   '$call_with_inference_counting'('$module_call'(C1,D1)).
 
 :-non_counted_backtracking call/26.
 call(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) :-
-   (  var(A) ->
-      instantiation_error(call/26)
-   ;  A= '$call'(A1) ->
-      '$prepare_call_clause'(B1,C1,A1,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),
-      '$call_with_inference_counting'('$call'(C1:B1))
-   ;  '$prepare_call_clause'(B1,C1,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),
-      expand_goal(call(C1:B1),C1,call(D1)),
-      '$call_with_inference_counting'('$call'(D1))
-   ).
+   var(A),
+   instantiation_error(call/26).
+call(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) :-
+   '$call_inline'(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).
+call('$call'(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) :-
+   !,
+   '$prepare_call_clause'(A1,B1,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),
+   '$call_with_inference_counting'('$module_call'(B1,A1)).
+call(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) :-
+   '$prepare_call_clause'(A1,B1,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),
+   expand_goal(call(A1),B1,call(C1)),
+   strip_subst_module(C1,B1,D1,E1),
+   '$call_with_inference_counting'('$module_call'(D1,E1)).
 
 :-non_counted_backtracking call/27.
 call(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,A1) :-
-   (  var(A) ->
-      instantiation_error(call/27)
-   ;  A= '$call'(B1) ->
-      '$prepare_call_clause'(C1,D1,B1,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,A1),
-      '$call_with_inference_counting'('$call'(D1:C1))
-   ;  '$prepare_call_clause'(C1,D1,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,A1),
-      expand_goal(call(D1:C1),D1,call(E1)),
-      '$call_with_inference_counting'('$call'(E1))
-   ).
+   var(A),
+   instantiation_error(call/27).
+call(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,A1) :-
+   '$call_inline'(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,A1).
+call('$call'(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,A1) :-
+   !,
+   '$prepare_call_clause'(B1,C1,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,A1),
+   '$call_with_inference_counting'('$module_call'(C1,B1)).
+call(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,A1) :-
+   '$prepare_call_clause'(B1,C1,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,A1),
+   expand_goal(call(B1),C1,call(D1)),
+   strip_subst_module(D1,C1,E1,F1),
+   '$call_with_inference_counting'('$module_call'(E1,F1)).
 
 :-non_counted_backtracking call/28.
 call(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,A1,B1) :-
-   (  var(A) ->
-      instantiation_error(call/28)
-   ;  A= '$call'(C1) ->
-      '$prepare_call_clause'(D1,E1,C1,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,A1,B1),
-      '$call_with_inference_counting'('$call'(E1:D1))
-   ;  '$prepare_call_clause'(D1,E1,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,A1,B1),
-      expand_goal(call(E1:D1),E1,call(F1)),
-      '$call_with_inference_counting'('$call'(F1))
-   ).
+   var(A),
+   instantiation_error(call/28).
+call(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,A1,B1) :-
+   '$call_inline'(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,A1,B1).
+call('$call'(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,A1,B1) :-
+   !,
+   '$prepare_call_clause'(C1,D1,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,A1,B1),
+   '$call_with_inference_counting'('$module_call'(D1,C1)).
+call(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,A1,B1) :-
+   '$prepare_call_clause'(C1,D1,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,A1,B1),
+   expand_goal(call(C1),D1,call(E1)),
+   strip_subst_module(E1,D1,F1,G1),
+   '$call_with_inference_counting'('$module_call'(F1,G1)).
 
 :-non_counted_backtracking call/29.
 call(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,A1,B1,C1) :-
-   (  var(A) ->
-      instantiation_error(call/29)
-   ;  A= '$call'(D1) ->
-      '$prepare_call_clause'(E1,F1,D1,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,A1,B1,C1),
-      '$call_with_inference_counting'('$call'(F1:E1))
-   ;  '$prepare_call_clause'(E1,F1,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,A1,B1,C1),
-      expand_goal(call(F1:E1),F1,call(G1)),
-      '$call_with_inference_counting'('$call'(G1))
-   ).
+   var(A),
+   instantiation_error(call/29).
+call(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,A1,B1,C1) :-
+   '$call_inline'(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,A1,B1,C1).
+call('$call'(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,A1,B1,C1) :-
+   !,
+   '$prepare_call_clause'(D1,E1,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,A1,B1,C1),
+   '$call_with_inference_counting'('$module_call'(E1,D1)).
+call(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,A1,B1,C1) :-
+   '$prepare_call_clause'(D1,E1,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,A1,B1,C1),
+   expand_goal(call(D1),E1,call(F1)),
+   strip_subst_module(F1,E1,G1,H1),
+   '$call_with_inference_counting'('$module_call'(G1,H1)).
 
 :-non_counted_backtracking call/30.
 call(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,A1,B1,C1,D1) :-
-   (  var(A) ->
-      instantiation_error(call/30)
-   ;  A= '$call'(E1) ->
-      '$prepare_call_clause'(F1,G1,E1,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,A1,B1,C1,D1),
-      '$call_with_inference_counting'('$call'(G1:F1))
-   ;  '$prepare_call_clause'(F1,G1,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,A1,B1,C1,D1),
-      expand_goal(call(G1:F1),G1,call(H1)),
-      '$call_with_inference_counting'('$call'(H1))
-   ).
+   var(A),
+   instantiation_error(call/30).
+call(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,A1,B1,C1,D1) :-
+   '$call_inline'(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,A1,B1,C1,D1).
+call('$call'(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,A1,B1,C1,D1) :-
+   !,
+   '$prepare_call_clause'(E1,F1,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,A1,B1,C1,D1),
+   '$call_with_inference_counting'('$module_call'(F1,E1)).
+call(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,A1,B1,C1,D1) :-
+   '$prepare_call_clause'(E1,F1,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,A1,B1,C1,D1),
+   expand_goal(call(E1),F1,call(G1)),
+   strip_subst_module(G1,F1,H1,I1),
+   '$call_with_inference_counting'('$module_call'(H1,I1)).
 
 :-non_counted_backtracking call/31.
 call(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,A1,B1,C1,D1,E1) :-
-   (  var(A) ->
-      instantiation_error(call/31)
-   ;  A= '$call'(F1) ->
-      '$prepare_call_clause'(G1,H1,F1,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,A1,B1,C1,D1,E1),
-      '$call_with_inference_counting'('$call'(H1:G1))
-   ;  '$prepare_call_clause'(G1,H1,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,A1,B1,C1,D1,E1),
-      expand_goal(call(H1:G1),H1,call(I1)),
-      '$call_with_inference_counting'('$call'(I1))
-   ).
+   var(A),
+   instantiation_error(call/31).
+call(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,A1,B1,C1,D1,E1) :-
+   '$call_inline'(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,A1,B1,C1,D1,E1).
+call('$call'(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,A1,B1,C1,D1,E1) :-
+   !,
+   '$prepare_call_clause'(F1,G1,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,A1,B1,C1,D1,E1),
+   '$call_with_inference_counting'('$module_call'(G1,F1)).
+call(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,A1,B1,C1,D1,E1) :-
+   '$prepare_call_clause'(F1,G1,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,A1,B1,C1,D1,E1),
+   expand_goal(call(F1),G1,call(H1)),
+   strip_subst_module(H1,G1,I1,J1),
+   '$call_with_inference_counting'('$module_call'(I1,J1)).
 
 :-non_counted_backtracking call/32.
 call(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,A1,B1,C1,D1,E1,F1) :-
-   (  var(A) ->
-      instantiation_error(call/32)
-   ;  A= '$call'(G1) ->
-      '$prepare_call_clause'(H1,I1,G1,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,A1,B1,C1,D1,E1,F1),
-      '$call_with_inference_counting'('$call'(I1:H1))
-   ;  '$prepare_call_clause'(H1,I1,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,A1,B1,C1,D1,E1,F1),
-      expand_goal(call(I1:H1),I1,call(J1)),
-      '$call_with_inference_counting'('$call'(J1))
-   ).
+   var(A),
+   instantiation_error(call/32).
+call(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,A1,B1,C1,D1,E1,F1) :-
+   '$call_inline'(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,A1,B1,C1,D1,E1,F1).
+call('$call'(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,A1,B1,C1,D1,E1,F1) :-
+   !,
+   '$prepare_call_clause'(G1,H1,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,A1,B1,C1,D1,E1,F1),
+   '$call_with_inference_counting'('$module_call'(H1,G1)).
+call(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,A1,B1,C1,D1,E1,F1) :-
+   '$prepare_call_clause'(G1,H1,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,A1,B1,C1,D1,E1,F1),
+   expand_goal(call(G1),H1,call(I1)),
+   strip_subst_module(I1,H1,J1,K1),
+   '$call_with_inference_counting'('$module_call'(J1,K1)).
 
 :-non_counted_backtracking call/33.
 call(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,A1,B1,C1,D1,E1,F1,G1) :-
-   (  var(A) ->
-      instantiation_error(call/33)
-   ;  A= '$call'(H1) ->
-      '$prepare_call_clause'(I1,J1,H1,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,A1,B1,C1,D1,E1,F1,G1),
-      '$call_with_inference_counting'('$call'(J1:I1))
-   ;  '$prepare_call_clause'(I1,J1,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,A1,B1,C1,D1,E1,F1,G1),
-      expand_goal(call(J1:I1),J1,call(K1)),
-      '$call_with_inference_counting'('$call'(K1))
-   ).
+   var(A),
+   instantiation_error(call/33).
+call(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,A1,B1,C1,D1,E1,F1,G1) :-
+   '$call_inline'(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,A1,B1,C1,D1,E1,F1,G1).
+call('$call'(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,A1,B1,C1,D1,E1,F1,G1) :-
+   !,
+   '$prepare_call_clause'(H1,I1,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,A1,B1,C1,D1,E1,F1,G1),
+   '$call_with_inference_counting'('$module_call'(I1,H1)).
+call(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,A1,B1,C1,D1,E1,F1,G1) :-
+   '$prepare_call_clause'(H1,I1,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,A1,B1,C1,D1,E1,F1,G1),
+   expand_goal(call(H1),I1,call(J1)),
+   strip_subst_module(J1,I1,K1,L1),
+   '$call_with_inference_counting'('$module_call'(K1,L1)).
 
 :-non_counted_backtracking call/34.
 call(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,A1,B1,C1,D1,E1,F1,G1,H1) :-
-   (  var(A) ->
-      instantiation_error(call/34)
-   ;  A= '$call'(I1) ->
-      '$prepare_call_clause'(J1,K1,I1,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,A1,B1,C1,D1,E1,F1,G1,H1),
-      '$call_with_inference_counting'('$call'(K1:J1))
-   ;  '$prepare_call_clause'(J1,K1,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,A1,B1,C1,D1,E1,F1,G1,H1),
-      expand_goal(call(K1:J1),K1,call(L1)),
-      '$call_with_inference_counting'('$call'(L1))
-   ).
+   var(A),
+   instantiation_error(call/34).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1) :-
+   '$call_inline'(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,A1,B1,C1,D1,E1,F1,G1,H1).
+call('$call'(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,A1,B1,C1,D1,E1,F1,G1,H1) :-
+   !,
+   '$prepare_call_clause'(I1,J1,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,A1,B1,C1,D1,E1,F1,G1,H1),
+   '$call_with_inference_counting'('$module_call'(J1,I1)).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1) :-
+   '$prepare_call_clause'(I1,J1,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,A1,B1,C1,D1,E1,F1,G1,H1),
+   expand_goal(call(I1),J1,call(K1)),
+   strip_subst_module(K1,J1,L1,M1),
+   '$call_with_inference_counting'('$module_call'(L1,M1)).
 
 :-non_counted_backtracking call/35.
 call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1) :-
-   (  var(A) ->
-      instantiation_error(call/35)
-   ;  A= '$call'(J1) ->
-      '$prepare_call_clause'(K1,L1,J1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1),
-      '$call_with_inference_counting'('$call'(L1:K1))
-   ;  '$prepare_call_clause'(K1,L1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1),
-      expand_goal(call(L1:K1),L1,call(M1)),
-      '$call_with_inference_counting'('$call'(M1))
-   ).
+   var(A),
+   instantiation_error(call/35).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1) :-
+   '$call_inline'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1).
+call('$call'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1) :-
+   !,
+   '$prepare_call_clause'(J1,K1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1),
+   '$call_with_inference_counting'('$module_call'(K1,J1)).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1) :-
+   '$prepare_call_clause'(J1,K1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1),
+   expand_goal(call(J1),K1,call(L1)),
+   strip_subst_module(L1,K1,M1,N1),
+   '$call_with_inference_counting'('$module_call'(M1,N1)).
 
 :-non_counted_backtracking call/36.
 call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1) :-
-   (  var(A) ->
-      instantiation_error(call/36)
-   ;  A= '$call'(K1) ->
-      '$prepare_call_clause'(L1,M1,K1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1),
-      '$call_with_inference_counting'('$call'(M1:L1))
-   ;  '$prepare_call_clause'(L1,M1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1),
-      expand_goal(call(M1:L1),M1,call(N1)),
-      '$call_with_inference_counting'('$call'(N1))
-   ).
+   var(A),
+   instantiation_error(call/36).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1) :-
+   '$call_inline'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1).
+call('$call'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1) :-
+   !,
+   '$prepare_call_clause'(K1,L1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1),
+   '$call_with_inference_counting'('$module_call'(L1,K1)).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1) :-
+   '$prepare_call_clause'(K1,L1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1),
+   expand_goal(call(K1),L1,call(M1)),
+   strip_subst_module(M1,L1,N1,O1),
+   '$call_with_inference_counting'('$module_call'(N1,O1)).
 
 :-non_counted_backtracking call/37.
 call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1) :-
-   (  var(A) ->
-      instantiation_error(call/37)
-   ;  A= '$call'(L1) ->
-      '$prepare_call_clause'(M1,N1,L1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1),
-      '$call_with_inference_counting'('$call'(N1:M1))
-   ;  '$prepare_call_clause'(M1,N1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1),
-      expand_goal(call(N1:M1),N1,call(O1)),
-      '$call_with_inference_counting'('$call'(O1))
-   ).
+   var(A),
+   instantiation_error(call/37).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1) :-
+   '$call_inline'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1).
+call('$call'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1) :-
+   !,
+   '$prepare_call_clause'(L1,M1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1),
+   '$call_with_inference_counting'('$module_call'(M1,L1)).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1) :-
+   '$prepare_call_clause'(L1,M1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1),
+   expand_goal(call(L1),M1,call(N1)),
+   strip_subst_module(N1,M1,O1,P1),
+   '$call_with_inference_counting'('$module_call'(O1,P1)).
 
 :-non_counted_backtracking call/38.
 call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1) :-
-   (  var(A) ->
-      instantiation_error(call/38)
-   ;  A= '$call'(M1) ->
-      '$prepare_call_clause'(N1,O1,M1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1),
-      '$call_with_inference_counting'('$call'(O1:N1))
-   ;  '$prepare_call_clause'(N1,O1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1),
-      expand_goal(call(O1:N1),O1,call(P1)),
-      '$call_with_inference_counting'('$call'(P1))
-   ).
+   var(A),
+   instantiation_error(call/38).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1) :-
+   '$call_inline'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1).
+call('$call'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1) :-
+   !,
+   '$prepare_call_clause'(M1,N1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1),
+   '$call_with_inference_counting'('$module_call'(N1,M1)).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1) :-
+   '$prepare_call_clause'(M1,N1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1),
+   expand_goal(call(M1),N1,call(O1)),
+   strip_subst_module(O1,N1,P1,Q1),
+   '$call_with_inference_counting'('$module_call'(P1,Q1)).
 
 :-non_counted_backtracking call/39.
 call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1) :-
-   (  var(A) ->
-      instantiation_error(call/39)
-   ;  A= '$call'(N1) ->
-      '$prepare_call_clause'(O1,P1,N1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1),
-      '$call_with_inference_counting'('$call'(P1:O1))
-   ;  '$prepare_call_clause'(O1,P1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1),
-      expand_goal(call(P1:O1),P1,call(Q1)),
-      '$call_with_inference_counting'('$call'(Q1))
-   ).
+   var(A),
+   instantiation_error(call/39).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1) :-
+   '$call_inline'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1).
+call('$call'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1) :-
+   !,
+   '$prepare_call_clause'(N1,O1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1),
+   '$call_with_inference_counting'('$module_call'(O1,N1)).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1) :-
+   '$prepare_call_clause'(N1,O1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1),
+   expand_goal(call(N1),O1,call(P1)),
+   strip_subst_module(P1,O1,Q1,R1),
+   '$call_with_inference_counting'('$module_call'(Q1,R1)).
 
 :-non_counted_backtracking call/40.
 call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1) :-
-   (  var(A) ->
-      instantiation_error(call/40)
-   ;  A= '$call'(O1) ->
-      '$prepare_call_clause'(P1,Q1,O1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1),
-      '$call_with_inference_counting'('$call'(Q1:P1))
-   ;  '$prepare_call_clause'(P1,Q1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1),
-      expand_goal(call(Q1:P1),Q1,call(R1)),
-      '$call_with_inference_counting'('$call'(R1))
-   ).
+   var(A),
+   instantiation_error(call/40).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1) :-
+   '$call_inline'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1).
+call('$call'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1) :-
+   !,
+   '$prepare_call_clause'(O1,P1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1),
+   '$call_with_inference_counting'('$module_call'(P1,O1)).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1) :-
+   '$prepare_call_clause'(O1,P1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1),
+   expand_goal(call(O1),P1,call(Q1)),
+   strip_subst_module(Q1,P1,R1,S1),
+   '$call_with_inference_counting'('$module_call'(R1,S1)).
 
 :-non_counted_backtracking call/41.
 call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1) :-
-   (  var(A) ->
-      instantiation_error(call/41)
-   ;  A= '$call'(P1) ->
-      '$prepare_call_clause'(Q1,R1,P1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1),
-      '$call_with_inference_counting'('$call'(R1:Q1))
-   ;  '$prepare_call_clause'(Q1,R1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1),
-      expand_goal(call(R1:Q1),R1,call(S1)),
-      '$call_with_inference_counting'('$call'(S1))
-   ).
+   var(A),
+   instantiation_error(call/41).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1) :-
+   '$call_inline'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1).
+call('$call'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1) :-
+   !,
+   '$prepare_call_clause'(P1,Q1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1),
+   '$call_with_inference_counting'('$module_call'(Q1,P1)).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1) :-
+   '$prepare_call_clause'(P1,Q1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1),
+   expand_goal(call(P1),Q1,call(R1)),
+   strip_subst_module(R1,Q1,S1,T1),
+   '$call_with_inference_counting'('$module_call'(S1,T1)).
 
 :-non_counted_backtracking call/42.
 call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1) :-
-   (  var(A) ->
-      instantiation_error(call/42)
-   ;  A= '$call'(Q1) ->
-      '$prepare_call_clause'(R1,S1,Q1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1),
-      '$call_with_inference_counting'('$call'(S1:R1))
-   ;  '$prepare_call_clause'(R1,S1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1),
-      expand_goal(call(S1:R1),S1,call(T1)),
-      '$call_with_inference_counting'('$call'(T1))
-   ).
+   var(A),
+   instantiation_error(call/42).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1) :-
+   '$call_inline'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1).
+call('$call'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1) :-
+   !,
+   '$prepare_call_clause'(Q1,R1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1),
+   '$call_with_inference_counting'('$module_call'(R1,Q1)).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1) :-
+   '$prepare_call_clause'(Q1,R1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1),
+   expand_goal(call(Q1),R1,call(S1)),
+   strip_subst_module(S1,R1,T1,U1),
+   '$call_with_inference_counting'('$module_call'(T1,U1)).
 
 :-non_counted_backtracking call/43.
 call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1) :-
-   (  var(A) ->
-      instantiation_error(call/43)
-   ;  A= '$call'(R1) ->
-      '$prepare_call_clause'(S1,T1,R1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1),
-      '$call_with_inference_counting'('$call'(T1:S1))
-   ;  '$prepare_call_clause'(S1,T1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1),
-      expand_goal(call(T1:S1),T1,call(U1)),
-      '$call_with_inference_counting'('$call'(U1))
-   ).
+   var(A),
+   instantiation_error(call/43).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1) :-
+   '$call_inline'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1).
+call('$call'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1) :-
+   !,
+   '$prepare_call_clause'(R1,S1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1),
+   '$call_with_inference_counting'('$module_call'(S1,R1)).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1) :-
+   '$prepare_call_clause'(R1,S1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1),
+   expand_goal(call(R1),S1,call(T1)),
+   strip_subst_module(T1,S1,U1,V1),
+   '$call_with_inference_counting'('$module_call'(U1,V1)).
 
 :-non_counted_backtracking call/44.
 call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1) :-
-   (  var(A) ->
-      instantiation_error(call/44)
-   ;  A= '$call'(S1) ->
-      '$prepare_call_clause'(T1,U1,S1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1),
-      '$call_with_inference_counting'('$call'(U1:T1))
-   ;  '$prepare_call_clause'(T1,U1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1),
-      expand_goal(call(U1:T1),U1,call(V1)),
-      '$call_with_inference_counting'('$call'(V1))
-   ).
+   var(A),
+   instantiation_error(call/44).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1) :-
+   '$call_inline'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1).
+call('$call'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1) :-
+   !,
+   '$prepare_call_clause'(S1,T1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1),
+   '$call_with_inference_counting'('$module_call'(T1,S1)).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1) :-
+   '$prepare_call_clause'(S1,T1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1),
+   expand_goal(call(S1),T1,call(U1)),
+   strip_subst_module(U1,T1,V1,W1),
+   '$call_with_inference_counting'('$module_call'(V1,W1)).
 
 :-non_counted_backtracking call/45.
 call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1) :-
-   (  var(A) ->
-      instantiation_error(call/45)
-   ;  A= '$call'(T1) ->
-      '$prepare_call_clause'(U1,V1,T1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1),
-      '$call_with_inference_counting'('$call'(V1:U1))
-   ;  '$prepare_call_clause'(U1,V1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1),
-      expand_goal(call(V1:U1),V1,call(W1)),
-      '$call_with_inference_counting'('$call'(W1))
-   ).
+   var(A),
+   instantiation_error(call/45).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1) :-
+   '$call_inline'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1).
+call('$call'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1) :-
+   !,
+   '$prepare_call_clause'(T1,U1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1),
+   '$call_with_inference_counting'('$module_call'(U1,T1)).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1) :-
+   '$prepare_call_clause'(T1,U1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1),
+   expand_goal(call(T1),U1,call(V1)),
+   strip_subst_module(V1,U1,W1,X1),
+   '$call_with_inference_counting'('$module_call'(W1,X1)).
 
 :-non_counted_backtracking call/46.
 call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1) :-
-   (  var(A) ->
-      instantiation_error(call/46)
-   ;  A= '$call'(U1) ->
-      '$prepare_call_clause'(V1,W1,U1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1),
-      '$call_with_inference_counting'('$call'(W1:V1))
-   ;  '$prepare_call_clause'(V1,W1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1),
-      expand_goal(call(W1:V1),W1,call(X1)),
-      '$call_with_inference_counting'('$call'(X1))
-   ).
+   var(A),
+   instantiation_error(call/46).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1) :-
+   '$call_inline'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1).
+call('$call'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1) :-
+   !,
+   '$prepare_call_clause'(U1,V1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1),
+   '$call_with_inference_counting'('$module_call'(V1,U1)).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1) :-
+   '$prepare_call_clause'(U1,V1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1),
+   expand_goal(call(U1),V1,call(W1)),
+   strip_subst_module(W1,V1,X1,Y1),
+   '$call_with_inference_counting'('$module_call'(X1,Y1)).
 
 :-non_counted_backtracking call/47.
 call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1) :-
-   (  var(A) ->
-      instantiation_error(call/47)
-   ;  A= '$call'(V1) ->
-      '$prepare_call_clause'(W1,X1,V1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1),
-      '$call_with_inference_counting'('$call'(X1:W1))
-   ;  '$prepare_call_clause'(W1,X1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1),
-      expand_goal(call(X1:W1),X1,call(Y1)),
-      '$call_with_inference_counting'('$call'(Y1))
-   ).
+   var(A),
+   instantiation_error(call/47).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1) :-
+   '$call_inline'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1).
+call('$call'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1) :-
+   !,
+   '$prepare_call_clause'(V1,W1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1),
+   '$call_with_inference_counting'('$module_call'(W1,V1)).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1) :-
+   '$prepare_call_clause'(V1,W1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1),
+   expand_goal(call(V1),W1,call(X1)),
+   strip_subst_module(X1,W1,Y1,Z1),
+   '$call_with_inference_counting'('$module_call'(Y1,Z1)).
 
 :-non_counted_backtracking call/48.
 call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1) :-
-   (  var(A) ->
-      instantiation_error(call/48)
-   ;  A= '$call'(W1) ->
-      '$prepare_call_clause'(X1,Y1,W1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1),
-      '$call_with_inference_counting'('$call'(Y1:X1))
-   ;  '$prepare_call_clause'(X1,Y1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1),
-      expand_goal(call(Y1:X1),Y1,call(Z1)),
-      '$call_with_inference_counting'('$call'(Z1))
-   ).
+   var(A),
+   instantiation_error(call/48).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1) :-
+   '$call_inline'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1).
+call('$call'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1) :-
+   !,
+   '$prepare_call_clause'(W1,X1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1),
+   '$call_with_inference_counting'('$module_call'(X1,W1)).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1) :-
+   '$prepare_call_clause'(W1,X1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1),
+   expand_goal(call(W1),X1,call(Y1)),
+   strip_subst_module(Y1,X1,Z1,A2),
+   '$call_with_inference_counting'('$module_call'(Z1,A2)).
 
 :-non_counted_backtracking call/49.
 call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1) :-
-   (  var(A) ->
-      instantiation_error(call/49)
-   ;  A= '$call'(X1) ->
-      '$prepare_call_clause'(Y1,Z1,X1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1),
-      '$call_with_inference_counting'('$call'(Z1:Y1))
-   ;  '$prepare_call_clause'(Y1,Z1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1),
-      expand_goal(call(Z1:Y1),Z1,call(A2)),
-      '$call_with_inference_counting'('$call'(A2))
-   ).
+   var(A),
+   instantiation_error(call/49).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1) :-
+   '$call_inline'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1).
+call('$call'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1) :-
+   !,
+   '$prepare_call_clause'(X1,Y1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1),
+   '$call_with_inference_counting'('$module_call'(Y1,X1)).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1) :-
+   '$prepare_call_clause'(X1,Y1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1),
+   expand_goal(call(X1),Y1,call(Z1)),
+   strip_subst_module(Z1,Y1,A2,B2),
+   '$call_with_inference_counting'('$module_call'(A2,B2)).
 
 :-non_counted_backtracking call/50.
 call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1) :-
-   (  var(A) ->
-      instantiation_error(call/50)
-   ;  A= '$call'(Y1) ->
-      '$prepare_call_clause'(Z1,A2,Y1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1),
-      '$call_with_inference_counting'('$call'(A2:Z1))
-   ;  '$prepare_call_clause'(Z1,A2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1),
-      expand_goal(call(A2:Z1),A2,call(B2)),
-      '$call_with_inference_counting'('$call'(B2))
-   ).
+   var(A),
+   instantiation_error(call/50).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1) :-
+   '$call_inline'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1).
+call('$call'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1) :-
+   !,
+   '$prepare_call_clause'(Y1,Z1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1),
+   '$call_with_inference_counting'('$module_call'(Z1,Y1)).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1) :-
+   '$prepare_call_clause'(Y1,Z1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1),
+   expand_goal(call(Y1),Z1,call(A2)),
+   strip_subst_module(A2,Z1,B2,C2),
+   '$call_with_inference_counting'('$module_call'(B2,C2)).
 
 :-non_counted_backtracking call/51.
 call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1) :-
-   (  var(A) ->
-      instantiation_error(call/51)
-   ;  A= '$call'(Z1) ->
-      '$prepare_call_clause'(A2,B2,Z1,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1),
-      '$call_with_inference_counting'('$call'(B2:A2))
-   ;  '$prepare_call_clause'(A2,B2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1),
-      expand_goal(call(B2:A2),B2,call(C2)),
-      '$call_with_inference_counting'('$call'(C2))
-   ).
+   var(A),
+   instantiation_error(call/51).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1) :-
+   '$call_inline'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1).
+call('$call'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1) :-
+   !,
+   '$prepare_call_clause'(Z1,A2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1),
+   '$call_with_inference_counting'('$module_call'(A2,Z1)).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1) :-
+   '$prepare_call_clause'(Z1,A2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1),
+   expand_goal(call(Z1),A2,call(B2)),
+   strip_subst_module(B2,A2,C2,D2),
+   '$call_with_inference_counting'('$module_call'(C2,D2)).
 
 :-non_counted_backtracking call/52.
 call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1) :-
-   (  var(A) ->
-      instantiation_error(call/52)
-   ;  A= '$call'(A2) ->
-      '$prepare_call_clause'(B2,C2,A2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1),
-      '$call_with_inference_counting'('$call'(C2:B2))
-   ;  '$prepare_call_clause'(B2,C2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1),
-      expand_goal(call(C2:B2),C2,call(D2)),
-      '$call_with_inference_counting'('$call'(D2))
-   ).
+   var(A),
+   instantiation_error(call/52).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1) :-
+   '$call_inline'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1).
+call('$call'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1) :-
+   !,
+   '$prepare_call_clause'(A2,B2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1),
+   '$call_with_inference_counting'('$module_call'(B2,A2)).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1) :-
+   '$prepare_call_clause'(A2,B2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1),
+   expand_goal(call(A2),B2,call(C2)),
+   strip_subst_module(C2,B2,D2,E2),
+   '$call_with_inference_counting'('$module_call'(D2,E2)).
 
 :-non_counted_backtracking call/53.
 call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2) :-
-   (  var(A) ->
-      instantiation_error(call/53)
-   ;  A= '$call'(B2) ->
-      '$prepare_call_clause'(C2,D2,B2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2),
-      '$call_with_inference_counting'('$call'(D2:C2))
-   ;  '$prepare_call_clause'(C2,D2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2),
-      expand_goal(call(D2:C2),D2,call(E2)),
-      '$call_with_inference_counting'('$call'(E2))
-   ).
+   var(A),
+   instantiation_error(call/53).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2) :-
+   '$call_inline'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2).
+call('$call'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2) :-
+   !,
+   '$prepare_call_clause'(B2,C2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2),
+   '$call_with_inference_counting'('$module_call'(C2,B2)).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2) :-
+   '$prepare_call_clause'(B2,C2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2),
+   expand_goal(call(B2),C2,call(D2)),
+   strip_subst_module(D2,C2,E2,F2),
+   '$call_with_inference_counting'('$module_call'(E2,F2)).
 
 :-non_counted_backtracking call/54.
 call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2) :-
-   (  var(A) ->
-      instantiation_error(call/54)
-   ;  A= '$call'(C2) ->
-      '$prepare_call_clause'(D2,E2,C2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2),
-      '$call_with_inference_counting'('$call'(E2:D2))
-   ;  '$prepare_call_clause'(D2,E2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2),
-      expand_goal(call(E2:D2),E2,call(F2)),
-      '$call_with_inference_counting'('$call'(F2))
-   ).
+   var(A),
+   instantiation_error(call/54).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2) :-
+   '$call_inline'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2).
+call('$call'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2) :-
+   !,
+   '$prepare_call_clause'(C2,D2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2),
+   '$call_with_inference_counting'('$module_call'(D2,C2)).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2) :-
+   '$prepare_call_clause'(C2,D2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2),
+   expand_goal(call(C2),D2,call(E2)),
+   strip_subst_module(E2,D2,F2,G2),
+   '$call_with_inference_counting'('$module_call'(F2,G2)).
 
 :-non_counted_backtracking call/55.
 call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2) :-
-   (  var(A) ->
-      instantiation_error(call/55)
-   ;  A= '$call'(D2) ->
-      '$prepare_call_clause'(E2,F2,D2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2),
-      '$call_with_inference_counting'('$call'(F2:E2))
-   ;  '$prepare_call_clause'(E2,F2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2),
-      expand_goal(call(F2:E2),F2,call(G2)),
-      '$call_with_inference_counting'('$call'(G2))
-   ).
+   var(A),
+   instantiation_error(call/55).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2) :-
+   '$call_inline'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2).
+call('$call'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2) :-
+   !,
+   '$prepare_call_clause'(D2,E2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2),
+   '$call_with_inference_counting'('$module_call'(E2,D2)).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2) :-
+   '$prepare_call_clause'(D2,E2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2),
+   expand_goal(call(D2),E2,call(F2)),
+   strip_subst_module(F2,E2,G2,H2),
+   '$call_with_inference_counting'('$module_call'(G2,H2)).
 
 :-non_counted_backtracking call/56.
 call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2) :-
-   (  var(A) ->
-      instantiation_error(call/56)
-   ;  A= '$call'(E2) ->
-      '$prepare_call_clause'(F2,G2,E2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2),
-      '$call_with_inference_counting'('$call'(G2:F2))
-   ;  '$prepare_call_clause'(F2,G2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2),
-      expand_goal(call(G2:F2),G2,call(H2)),
-      '$call_with_inference_counting'('$call'(H2))
-   ).
+   var(A),
+   instantiation_error(call/56).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2) :-
+   '$call_inline'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2).
+call('$call'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2) :-
+   !,
+   '$prepare_call_clause'(E2,F2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2),
+   '$call_with_inference_counting'('$module_call'(F2,E2)).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2) :-
+   '$prepare_call_clause'(E2,F2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2),
+   expand_goal(call(E2),F2,call(G2)),
+   strip_subst_module(G2,F2,H2,I2),
+   '$call_with_inference_counting'('$module_call'(H2,I2)).
 
 :-non_counted_backtracking call/57.
 call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2) :-
-   (  var(A) ->
-      instantiation_error(call/57)
-   ;  A= '$call'(F2) ->
-      '$prepare_call_clause'(G2,H2,F2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2),
-      '$call_with_inference_counting'('$call'(H2:G2))
-   ;  '$prepare_call_clause'(G2,H2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2),
-      expand_goal(call(H2:G2),H2,call(I2)),
-      '$call_with_inference_counting'('$call'(I2))
-   ).
+   var(A),
+   instantiation_error(call/57).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2) :-
+   '$call_inline'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2).
+call('$call'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2) :-
+   !,
+   '$prepare_call_clause'(F2,G2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2),
+   '$call_with_inference_counting'('$module_call'(G2,F2)).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2) :-
+   '$prepare_call_clause'(F2,G2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2),
+   expand_goal(call(F2),G2,call(H2)),
+   strip_subst_module(H2,G2,I2,J2),
+   '$call_with_inference_counting'('$module_call'(I2,J2)).
 
 :-non_counted_backtracking call/58.
 call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2) :-
-   (  var(A) ->
-      instantiation_error(call/58)
-   ;  A= '$call'(G2) ->
-      '$prepare_call_clause'(H2,I2,G2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2),
-      '$call_with_inference_counting'('$call'(I2:H2))
-   ;  '$prepare_call_clause'(H2,I2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2),
-      expand_goal(call(I2:H2),I2,call(J2)),
-      '$call_with_inference_counting'('$call'(J2))
-   ).
+   var(A),
+   instantiation_error(call/58).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2) :-
+   '$call_inline'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2).
+call('$call'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2) :-
+   !,
+   '$prepare_call_clause'(G2,H2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2),
+   '$call_with_inference_counting'('$module_call'(H2,G2)).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2) :-
+   '$prepare_call_clause'(G2,H2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2),
+   expand_goal(call(G2),H2,call(I2)),
+   strip_subst_module(I2,H2,J2,K2),
+   '$call_with_inference_counting'('$module_call'(J2,K2)).
 
 :-non_counted_backtracking call/59.
 call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2) :-
-   (  var(A) ->
-      instantiation_error(call/59)
-   ;  A= '$call'(H2) ->
-      '$prepare_call_clause'(I2,J2,H2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2),
-      '$call_with_inference_counting'('$call'(J2:I2))
-   ;  '$prepare_call_clause'(I2,J2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2),
-      expand_goal(call(J2:I2),J2,call(K2)),
-      '$call_with_inference_counting'('$call'(K2))
-   ).
+   var(A),
+   instantiation_error(call/59).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2) :-
+   '$call_inline'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2).
+call('$call'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2) :-
+   !,
+   '$prepare_call_clause'(H2,I2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2),
+   '$call_with_inference_counting'('$module_call'(I2,H2)).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2) :-
+   '$prepare_call_clause'(H2,I2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2),
+   expand_goal(call(H2),I2,call(J2)),
+   strip_subst_module(J2,I2,K2,L2),
+   '$call_with_inference_counting'('$module_call'(K2,L2)).
 
 :-non_counted_backtracking call/60.
 call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2) :-
-   (  var(A) ->
-      instantiation_error(call/60)
-   ;  A= '$call'(I2) ->
-      '$prepare_call_clause'(J2,K2,I2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2),
-      '$call_with_inference_counting'('$call'(K2:J2))
-   ;  '$prepare_call_clause'(J2,K2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2),
-      expand_goal(call(K2:J2),K2,call(L2)),
-      '$call_with_inference_counting'('$call'(L2))
-   ).
+   var(A),
+   instantiation_error(call/60).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2) :-
+   '$call_inline'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2).
+call('$call'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2) :-
+   !,
+   '$prepare_call_clause'(I2,J2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2),
+   '$call_with_inference_counting'('$module_call'(J2,I2)).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2) :-
+   '$prepare_call_clause'(I2,J2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2),
+   expand_goal(call(I2),J2,call(K2)),
+   strip_subst_module(K2,J2,L2,M2),
+   '$call_with_inference_counting'('$module_call'(L2,M2)).
 
 :-non_counted_backtracking call/61.
 call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2) :-
-   (  var(A) ->
-      instantiation_error(call/61)
-   ;  A= '$call'(J2) ->
-      '$prepare_call_clause'(K2,L2,J2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2),
-      '$call_with_inference_counting'('$call'(L2:K2))
-   ;  '$prepare_call_clause'(K2,L2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2),
-      expand_goal(call(L2:K2),L2,call(M2)),
-      '$call_with_inference_counting'('$call'(M2))
-   ).
+   var(A),
+   instantiation_error(call/61).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2) :-
+   '$call_inline'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2).
+call('$call'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2) :-
+   !,
+   '$prepare_call_clause'(J2,K2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2),
+   '$call_with_inference_counting'('$module_call'(K2,J2)).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2) :-
+   '$prepare_call_clause'(J2,K2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2),
+   expand_goal(call(J2),K2,call(L2)),
+   strip_subst_module(L2,K2,M2,N2),
+   '$call_with_inference_counting'('$module_call'(M2,N2)).
 
 :-non_counted_backtracking call/62.
 call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2) :-
-   (  var(A) ->
-      instantiation_error(call/62)
-   ;  A= '$call'(K2) ->
-      '$prepare_call_clause'(L2,M2,K2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2),
-      '$call_with_inference_counting'('$call'(M2:L2))
-   ;  '$prepare_call_clause'(L2,M2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2),
-      expand_goal(call(M2:L2),M2,call(N2)),
-      '$call_with_inference_counting'('$call'(N2))
-   ).
+   var(A),
+   instantiation_error(call/62).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2) :-
+   '$call_inline'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2).
+call('$call'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2) :-
+   !,
+   '$prepare_call_clause'(K2,L2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2),
+   '$call_with_inference_counting'('$module_call'(L2,K2)).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2) :-
+   '$prepare_call_clause'(K2,L2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2),
+   expand_goal(call(K2),L2,call(M2)),
+   strip_subst_module(M2,L2,N2,O2),
+   '$call_with_inference_counting'('$module_call'(N2,O2)).
 
 :-non_counted_backtracking call/63.
 call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2) :-
-   (  var(A) ->
-      instantiation_error(call/63)
-   ;  A= '$call'(L2) ->
-      '$prepare_call_clause'(M2,N2,L2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2),
-      '$call_with_inference_counting'('$call'(N2:M2))
-   ;  '$prepare_call_clause'(M2,N2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2),
-      expand_goal(call(N2:M2),N2,call(O2)),
-      '$call_with_inference_counting'('$call'(O2))
-   ).
+   var(A),
+   instantiation_error(call/63).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2) :-
+   '$call_inline'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2).
+call('$call'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2) :-
+   !,
+   '$prepare_call_clause'(L2,M2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2),
+   '$call_with_inference_counting'('$module_call'(M2,L2)).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2) :-
+   '$prepare_call_clause'(L2,M2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2),
+   expand_goal(call(L2),M2,call(N2)),
+   strip_subst_module(N2,M2,O2,P2),
+   '$call_with_inference_counting'('$module_call'(O2,P2)).
 
 :-non_counted_backtracking call/64.
 call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2) :-
-   (  var(A) ->
-      instantiation_error(call/64)
-   ;  A= '$call'(M2) ->
-      '$prepare_call_clause'(N2,O2,M2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2),
-      '$call_with_inference_counting'('$call'(O2:N2))
-   ;  '$prepare_call_clause'(N2,O2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2),
-      expand_goal(call(O2:N2),O2,call(P2)),
-      '$call_with_inference_counting'('$call'(P2))
-   ).
+   var(A),
+   instantiation_error(call/64).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2) :-
+   '$call_inline'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2).
+call('$call'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2) :-
+   !,
+   '$prepare_call_clause'(M2,N2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2),
+   '$call_with_inference_counting'('$module_call'(N2,M2)).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2) :-
+   '$prepare_call_clause'(M2,N2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2),
+   expand_goal(call(M2),N2,call(O2)),
+   strip_subst_module(O2,N2,P2,Q2),
+   '$call_with_inference_counting'('$module_call'(P2,Q2)).
 
 :-non_counted_backtracking call/65.
 call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2,M2) :-
-   (  var(A) ->
-      instantiation_error(call/65)
-   ;  A= '$call'(N2) ->
-      '$prepare_call_clause'(O2,P2,N2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2,M2),
-      '$call_with_inference_counting'('$call'(P2:O2))
-   ;  '$prepare_call_clause'(O2,P2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2,M2),
-      expand_goal(call(P2:O2),P2,call(Q2)),
-      '$call_with_inference_counting'('$call'(Q2))
-   ).
+   var(A),
+   instantiation_error(call/65).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2,M2) :-
+   '$call_inline'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2,M2).
+call('$call'(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2,M2) :-
+   !,
+   '$prepare_call_clause'(N2,O2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2,M2),
+   '$call_with_inference_counting'('$module_call'(O2,N2)).
+call(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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2,M2) :-
+   '$prepare_call_clause'(N2,O2,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,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2,M2),
+   expand_goal(call(N2),O2,call(P2)),
+   strip_subst_module(P2,O2,Q2,R2),
+   '$call_with_inference_counting'('$module_call'(Q2,R2)).
index 0a4eb6f45ce9fad7ad59e5b2a8c8891193689298..6e12b8c6a3944ee8c38128ebb4d0bc3372c9c319 100644 (file)
@@ -390,7 +390,6 @@ pub(crate) fn int_pow(n1: Number, n2: Number, arena: &mut Arena) -> Result<Numbe
 pub(crate) fn pow(n1: Number, n2: Number, culprit: Atom) -> Result<Number, MachineStubGen> {
     if n2.is_negative() && n1.is_zero() {
         let stub_gen = move || functor_stub(culprit, 2);
-
         return Err(undefined_eval_error(stub_gen));
     }
 
@@ -1183,7 +1182,7 @@ impl MachineState {
 
                                 let result = arena_alloc!(
                                     drop_iter_on_err!(self, iter, rdiv(r1, r2)),
-                                    self.arena
+                                    &mut self.arena
                                 );
 
                                 self.interms.push(Number::Rational(result));
index 9756293e52afebfd30c6faa64d45d281e2d39dc2..8c656e310917b7b4bc749b335bd7ba1916df9510 100644 (file)
@@ -28,11 +28,13 @@ call_verify_attributes([Attr|Attrs], Var, Value, ListOfGoalLists) :-
     sort(Modules0, Modules),
     verify_attrs(Modules, Var, Value, ListOfGoalLists).
 
+error_handler(M, evaluation_error((M:verify_attributes)/3), []).
+% error_handler(_, existence_error(procedure, verify_attributes/3), []).
 
 verify_attrs([Module|Modules], Var, Value, [Module-Goals|ListOfGoalLists]) :-
     catch(Module:verify_attributes(Var, Value, Goals),
-          error(evaluation_error((Module:verify_attributes)/3), verify_attributes/3),
-          Goals = []),
+          error(E, verify_attributes/3),
+          error_handler(Module, E, Goals)),
     verify_attrs(Modules, Var, Value, ListOfGoalLists).
 verify_attrs([], _, _, []).
 
index f85a06e955d2dbb596aab44c559c788e9cd6ce9a..7684755fb27937d5809be28aee332f76d93045b9 100644 (file)
@@ -406,7 +406,7 @@ fn merge_indexed_subsequences(
 
                 *o = 0;
 
-                return Some(IndexPtr::Index(outer_threaded_choice_instr_loc + 1));
+                return Some(IndexPtr::index(outer_threaded_choice_instr_loc + 1));
             }
             _ => {}
         },
@@ -785,7 +785,7 @@ fn remove_non_leading_clause(
 
                     *o = 0;
 
-                    Some(IndexPtr::Index(preceding_choice_instr_loc + 1))
+                    Some(IndexPtr::index(preceding_choice_instr_loc + 1))
                 }
                 _ => {
                     unreachable!();
@@ -820,7 +820,7 @@ fn finalize_retract(
             retraction_info,
             &compilation_target,
             key,
-            &code_index,
+            code_index,
             index_ptr,
         );
     }
@@ -849,9 +849,9 @@ fn remove_leading_unindexed_clause(
                     retraction_info,
                 );
 
-                Some(IndexPtr::Index(index_ptr))
+                Some(IndexPtr::index(index_ptr))
             } else {
-                Some(IndexPtr::DynamicUndefined)
+                Some(IndexPtr::dynamic_undefined())
             }
         }
         _ => {
@@ -1131,9 +1131,9 @@ fn prepend_compiled_clause(
     };
 
     if skeleton.core.is_dynamic {
-        IndexPtr::DynamicIndex(clause_loc)
+        IndexPtr::dynamic_index(clause_loc)
     } else {
-        IndexPtr::Index(clause_loc)
+        IndexPtr::index(clause_loc)
     }
 }
 
@@ -1268,9 +1268,9 @@ fn append_compiled_clause(
 
     code_ptr_opt.map(|p| {
         if skeleton.core.is_dynamic {
-            IndexPtr::DynamicIndex(p)
+            IndexPtr::dynamic_index(p)
         } else {
-            IndexPtr::Index(p)
+            IndexPtr::index(p)
         }
     })
 }
@@ -1306,8 +1306,8 @@ fn print_overwrite_warning(
         }
     }
 
-    match code_ptr {
-        IndexPtr::DynamicUndefined | IndexPtr::Undefined => return,
+    match code_ptr.tag() {
+        IndexPtrTag::DynamicUndefined | IndexPtrTag::Undefined => return,
         _ if is_dynamic => return,
         _ => {}
     }
@@ -1471,16 +1471,16 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
         );
 
         let index_ptr = if settings.is_dynamic() {
-            IndexPtr::DynamicIndex(code_ptr)
+            IndexPtr::dynamic_index(code_ptr)
         } else {
-            IndexPtr::Index(code_ptr)
+            IndexPtr::index(code_ptr)
         };
 
         set_code_index(
             &mut self.payload.retraction_info,
             &predicates.compilation_target,
             key,
-            &code_index,
+            code_index,
             index_ptr,
         );
 
@@ -1704,7 +1704,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
                         &mut self.payload.retraction_info,
                         &compilation_target,
                         key,
-                        &code_index,
+                        code_index,
                         new_code_ptr,
                     );
                 }
@@ -1745,7 +1745,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
                     &mut self.payload.retraction_info,
                     &compilation_target,
                     key,
-                    &code_index,
+                    code_index,
                     new_code_ptr,
                 );
 
@@ -1870,7 +1870,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
                                 skeleton.clauses[target_pos].clause_start;
 
                             let index_ptr_opt = if target_pos == 0 {
-                                Some(IndexPtr::Index(clause_loc))
+                                Some(IndexPtr::index(clause_loc))
                             } else {
                                 None
                             };
@@ -2384,13 +2384,15 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
                 match self.wam_prelude.indices.modules.get_mut(&filename) {
                     Some(ref mut module) => {
                         let index_ptr = code_index.get();
-                        let code_index = module.code_dir.entry(key).or_insert(code_index);
+                        let code_index = module.code_dir.entry(key)
+                            .or_insert(code_index)
+                            .clone();
 
                         set_code_index(
                             &mut self.payload.retraction_info,
                             &CompilationTarget::Module(filename),
                             key,
-                            &code_index,
+                            code_index,
                             index_ptr,
                         );
                     }
@@ -2418,3 +2420,54 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
         Ok(())
     }
 }
+
+// standalone functions for compiling auxiliary goals used by expand_goal.
+impl Machine {
+    pub(crate) fn get_or_insert_qualified_code_index(
+        &mut self,
+        module_name: HeapCellValue,
+        key: PredicateKey,
+    ) -> CodeIndex {
+        let mut loader: Loader<'_, LiveLoadAndMachineState<'_>> = Loader::new(
+            self,
+            LiveTermStream::new(ListingSource::User),
+        );
+
+        let module_name = if module_name.get_tag() == HeapCellValueTag::Atom {
+            cell_as_atom!(module_name)
+        } else {
+            atom!("user")
+        };
+
+        loader.get_or_insert_qualified_code_index(module_name, key)
+    }
+
+    pub(crate) fn compile_standalone_clause(
+        &mut self,
+        term_loc: RegType,
+        vars: &[Term],
+    ) -> Result<(), SessionError> {
+        let mut compile = || {
+            let mut loader: Loader<'_, LiveLoadAndMachineState<'_>> = Loader::new(
+                self,
+                LiveTermStream::new(ListingSource::User),
+            );
+
+            let term = loader.read_term_from_heap(term_loc)?;
+            let clause = build_rule_body(vars, term);
+
+            let settings = CodeGenSettings {
+                global_clock_tick: None,
+                is_extensible: false,
+                non_counted_bt: true,
+            };
+
+            loader.compile_standalone_clause(clause, settings)
+        };
+
+        let StandaloneCompileResult { clause_code, .. } = compile()?;
+        self.code.extend(clause_code.into_iter());
+
+        Ok(())
+    }
+}
index fd016fd6b8691ae9e5817205a95786c7693e4c9f..5332533296a28a3942d8de8ca5748970fe717bfd 100644 (file)
@@ -1,4 +1,5 @@
 use crate::atom_table::*;
+use crate::machine::get_structure_index;
 use crate::machine::stack::*;
 use crate::types::*;
 
@@ -248,6 +249,14 @@ impl<T: CopierTarget> CopyTermState<T> {
                     let hcv = self.target[addr + 1 + i];
                     self.target.push(hcv);
                 }
+
+                let index_cell = self.target[addr + 1 + arity];
+
+                if get_structure_index(index_cell).is_some() {
+                    // copy the index pointer trailing this
+                    // inlined or expanded goal.
+                    self.target.push(index_cell);
+                }
             }
             (HeapCellValueTag::Str, h) => {
                 *self.value_at_scan() = str_loc_as_cell!(h);
index 47f67da0b0bb16540af7e924514d661afa2d769e..3793ac0b4df632f8675ce5c4b49cf686195f430a 100644 (file)
@@ -57,18 +57,28 @@ impl MachineState {
         let a2 = self.registers[2];
         let a3 = self.registers[3];
 
+        let check_atom = |machine_st: &mut MachineState, name: Atom, arity: usize| -> Result<(), MachineStub> {
+            match name {
+                atom!(">") | atom!("<") | atom!("=") if arity == 0 => {
+                    Ok(())
+                }
+                _ => {
+                    let err = machine_st.domain_error(DomainErrorType::Order, a1);
+                    Err(machine_st.error_form(err, stub_gen()))
+                }
+            }
+        };
+
         read_heap_cell!(a1,
             (HeapCellValueTag::Atom, (name, arity)) => {
                 debug_assert_eq!(arity, 0);
+                check_atom(self, name, arity)?;
+            }
+            (HeapCellValueTag::Str, s) => {
+                let (name, arity) = cell_as_atom_cell!(self.heap[s])
+                    .get_name_and_arity();
 
-                match name {
-                    atom!(">") | atom!("<") | atom!("=") => {
-                    }
-                    _ => {
-                        let err = self.domain_error(DomainErrorType::Order, a1);
-                        return Err(self.error_form(err, stub_gen()));
-                    }
-                }
+                check_atom(self, name, arity)?;
             }
             (HeapCellValueTag::AttrVar | HeapCellValueTag::Var | HeapCellValueTag::StackVar) => {
             }
@@ -360,8 +370,9 @@ impl Machine {
                             debug_assert!(arity == 0);
                             c
                         }
-                        (HeapCellValueTag::Str) => {
-                            s
+                        (HeapCellValueTag::Str, st) => {
+                            let arity = cell_as_atom_cell!(self.machine_st.heap[st]).get_arity();
+                            if arity == 0 { c } else { s }
                         }
                         (HeapCellValueTag::Cons, ptr) => {
                             match ptr.get_tag() {
@@ -421,6 +432,9 @@ impl Machine {
                             debug_assert_eq!(arity, 0);
                             Literal::Atom(atom)
                         }
+                        (HeapCellValueTag::Str, s) => {
+                            Literal::Atom(cell_as_atom_cell!(self.machine_st.heap[s]).get_name())
+                        }
                         (HeapCellValueTag::Cons, cons_ptr) => {
                             match_untyped_arena_ptr!(cons_ptr,
                                 (ArenaHeaderTag::Rational, r) => {
@@ -597,6 +611,7 @@ impl Machine {
                         &mut self.machine_st,
                         try_numeric_result!(sub(n1, n2, &mut self.machine_st.arena), stub_gen)
                     );
+
                     self.machine_st.p += 1;
                 }
                 &Instruction::Mul(ref a1, ref a2, t) => {
@@ -675,7 +690,7 @@ impl Machine {
 
                     self.machine_st.interms[t - 1] = Number::Rational(arena_alloc!(
                         try_or_throw_gen!(&mut self.machine_st, rdiv(r1, r2)),
-                        self.machine_st.arena
+                        &mut self.machine_st.arena
                     ));
 
                     self.machine_st.p += 1;
@@ -688,6 +703,7 @@ impl Machine {
                         &mut self.machine_st,
                         int_floor_div(n1, n2, &mut self.machine_st.arena)
                     );
+
                     self.machine_st.p += 1;
                 }
                 &Instruction::IDiv(ref a1, ref a2, t) => {
@@ -698,6 +714,7 @@ impl Machine {
                         &mut self.machine_st,
                         idiv(n1, n2, &mut self.machine_st.arena)
                     );
+
                     self.machine_st.p += 1;
                 }
                 &Instruction::Abs(ref a1, t) => {
@@ -1122,17 +1139,7 @@ impl Machine {
                     );
                 }
                 &Instruction::NeckCut => {
-                    let b = self.machine_st.b;
-                    let b0 = self.machine_st.b0;
-
-                    if b > b0 {
-                        self.machine_st.b = b0;
-
-                        if b > self.machine_st.e {
-                            self.machine_st.stack.truncate(b);
-                        }
-                    }
-
+                    self.machine_st.neck_cut();
                     self.machine_st.p += 1;
                 }
                 &Instruction::GetLevel(r) => {
@@ -1298,7 +1305,6 @@ impl Machine {
                 }
                 &Instruction::DefaultCallRead(_) => {
                     try_or_throw!(self.machine_st, self.read());
-
                     step_or_fail!(self, self.machine_st.p += 1);
                 }
                 &Instruction::DefaultExecuteRead(_) => {
@@ -2354,6 +2360,16 @@ impl Machine {
                                 self.machine_st.backtrack();
                             }
                         }
+                        (HeapCellValueTag::Str, s) => {
+                            let arity = cell_as_atom_cell!(self.machine_st.heap[s])
+                                .get_arity();
+
+                            if arity == 0 {
+                                self.machine_st.p += 1;
+                            } else {
+                                self.machine_st.backtrack();
+                            }
+                        }
                         (HeapCellValueTag::Char) => {
                             self.machine_st.p += 1;
                         }
@@ -2373,6 +2389,16 @@ impl Machine {
                                 self.machine_st.backtrack();
                             }
                         }
+                        (HeapCellValueTag::Str, s) => {
+                            let arity = cell_as_atom_cell!(self.machine_st.heap[s])
+                                .get_arity();
+
+                            if arity == 0 {
+                                self.machine_st.p = self.machine_st.cp;
+                            } else {
+                                self.machine_st.backtrack();
+                            }
+                        }
                         (HeapCellValueTag::Char) => {
                             self.machine_st.p = self.machine_st.cp;
                         }
@@ -2396,6 +2422,16 @@ impl Machine {
                                 self.machine_st.backtrack();
                             }
                         }
+                        (HeapCellValueTag::Str, s) => {
+                            let arity = cell_as_atom_cell!(self.machine_st.heap[s])
+                                .get_arity();
+
+                            if arity == 0 {
+                                self.machine_st.p += 1;
+                            } else {
+                                self.machine_st.backtrack();
+                            }
+                        }
                         _ => {
                             self.machine_st.backtrack();
                         }
@@ -2416,6 +2452,16 @@ impl Machine {
                                 self.machine_st.backtrack();
                             }
                         }
+                        (HeapCellValueTag::Str, s) => {
+                            let arity = cell_as_atom_cell!(self.machine_st.heap[s])
+                                .get_arity();
+
+                            if arity == 0 {
+                                self.machine_st.p = self.machine_st.cp;
+                            } else {
+                                self.machine_st.backtrack();
+                            }
+                        }
                         _ => {
                             self.machine_st.backtrack();
                         }
@@ -2425,10 +2471,21 @@ impl Machine {
                     let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r]));
 
                     read_heap_cell!(d,
-                        (HeapCellValueTag::Str | HeapCellValueTag::Lis |
-                         HeapCellValueTag::PStrLoc | HeapCellValueTag::CStr) => {
+                        (HeapCellValueTag::Lis |
+                         HeapCellValueTag::PStrLoc |
+                         HeapCellValueTag::CStr) => {
                             self.machine_st.p += 1;
                         }
+                        (HeapCellValueTag::Str, s) => {
+                            let arity = cell_as_atom_cell!(self.machine_st.heap[s])
+                                .get_arity();
+
+                            if arity > 0 {
+                                self.machine_st.p += 1;
+                            } else {
+                                self.machine_st.backtrack();
+                            }
+                        }
                         (HeapCellValueTag::Atom, (_name, arity)) => {
                             if arity > 0 {
                                 self.machine_st.p += 1;
@@ -2445,10 +2502,21 @@ impl Machine {
                     let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r]));
 
                     read_heap_cell!(d,
-                        (HeapCellValueTag::Str | HeapCellValueTag::Lis |
-                         HeapCellValueTag::PStrLoc | HeapCellValueTag::CStr) => {
+                        (HeapCellValueTag::Lis |
+                         HeapCellValueTag::PStrLoc |
+                         HeapCellValueTag::CStr) => {
                             self.machine_st.p = self.machine_st.cp;
                         }
+                        (HeapCellValueTag::Str, s) => {
+                            let arity = cell_as_atom_cell!(self.machine_st.heap[s])
+                                .get_arity();
+
+                            if arity > 0 {
+                                self.machine_st.p = self.machine_st.cp;
+                            } else {
+                                self.machine_st.backtrack();
+                            }
+                        }
                         (HeapCellValueTag::Atom, (_name, arity)) => {
                             if arity > 0 {
                                 self.machine_st.p = self.machine_st.cp;
@@ -3500,7 +3568,10 @@ impl Machine {
                         self.dynamic_module_resolution(arity - 2)
                     );
 
-                    try_or_throw!(self.machine_st, self.call_clause(module_name, key));
+                    try_or_throw!(
+                        self.machine_st,
+                        self.call_clause(module_name, key)
+                    );
 
                     if self.machine_st.fail {
                         self.machine_st.backtrack();
@@ -3512,7 +3583,10 @@ impl Machine {
                         self.dynamic_module_resolution(arity - 2)
                     );
 
-                    try_or_throw!(self.machine_st, self.execute_clause(module_name, key));
+                    try_or_throw!(
+                        self.machine_st,
+                        self.execute_clause(module_name, key)
+                    );
 
                     if self.machine_st.fail {
                         self.machine_st.backtrack();
@@ -4886,7 +4960,7 @@ impl Machine {
                 &Instruction::ExecuteStripModule(_) => {
                     let (module_loc, qualified_goal) = self.machine_st.strip_module(
                         self.machine_st.registers[1],
-                        self.machine_st.registers[2]
+                        self.machine_st.registers[2],
                     );
 
                     let target_module_loc = self.machine_st.registers[2];
@@ -4915,6 +4989,44 @@ impl Machine {
                     try_or_throw!(self.machine_st, self.prepare_call_clause(arity));
                     step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
                 }
+                &Instruction::CallCompileInlineOrExpandedGoal(_) => {
+                    try_or_throw!(self.machine_st, self.compile_inline_or_expanded_goal());
+                    step_or_fail!(self, self.machine_st.p += 1);
+                }
+                &Instruction::ExecuteCompileInlineOrExpandedGoal(_) => {
+                    try_or_throw!(self.machine_st, self.compile_inline_or_expanded_goal());
+                    step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+                }
+                &Instruction::CallIsExpandedOrInlined(_) => {
+                    self.is_expanded_or_inlined();
+                    step_or_fail!(self, self.machine_st.p += 1);
+                }
+                &Instruction::ExecuteIsExpandedOrInlined(_) => {
+                    self.is_expanded_or_inlined();
+                    step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+                }
+                &Instruction::CallInlineCallN(arity, _) => {
+                    let call_at_index = |wam: &mut Machine, name, arity, ptr| {
+                        wam.try_call(name, arity, ptr)
+                    };
+
+                    try_or_throw!(self.machine_st, self.call_inline(arity, call_at_index));
+
+                    if self.machine_st.fail {
+                        self.machine_st.backtrack();
+                    }
+                }
+                &Instruction::ExecuteInlineCallN(arity, _) => {
+                    let call_at_index = |wam: &mut Machine, name, arity, ptr| {
+                        wam.try_execute(name, arity, ptr)
+                    };
+
+                    try_or_throw!(self.machine_st, self.call_inline(arity, call_at_index));
+
+                    if self.machine_st.fail {
+                        self.machine_st.backtrack();
+                    }
+                }
             }
         }
 
index 05bd70d612507d523bd8c3dd9ef9fbeab49fcbb0..8a884950cabe133896a2be1c7b89130a6c222846 100644 (file)
@@ -2,6 +2,9 @@ use crate::atom_table::*;
 use crate::machine::heap::*;
 use crate::types::*;
 
+#[cfg(test)]
+use crate::heap_iter::FocusedHeapIter;
+
 use core::marker::PhantomData;
 
 pub(crate) trait UnmarkPolicy {
@@ -69,6 +72,14 @@ pub(crate) struct StacklessPreOrderHeapIter<'a, UMP: UnmarkPolicy> {
     _marker: PhantomData<UMP>,
 }
 
+#[cfg(test)]
+impl<'a> FocusedHeapIter for StacklessPreOrderHeapIter<'a, IteratorUMP> {
+    #[inline]
+    fn focus(&self) -> usize {
+        self.current
+    }
+}
+
 impl<'a, UMP: UnmarkPolicy> Drop for StacklessPreOrderHeapIter<'a, UMP> {
     fn drop(&mut self) {
         if self.current == self.start {
index 830a7cce7d9172468aba4d292ab579062dbf841e..59e630094038867bebc073ac890fd04ab7935b5c 100644 (file)
@@ -1,6 +1,7 @@
 use crate::arena::*;
 use crate::atom_table::*;
 use crate::forms::*;
+use crate::machine::machine_indices::*;
 use crate::machine::partial_string::*;
 use crate::parser::ast::*;
 use crate::types::*;
@@ -17,6 +18,9 @@ impl From<Literal> for HeapCellValue {
         match literal {
             Literal::Atom(name) => atom_as_cell!(name),
             Literal::Char(c) => char_as_cell!(c),
+            Literal::CodeIndex(ptr) => {
+                untyped_arena_ptr_as_cell!(UntypedArenaPtr::from(ptr))
+            }
             Literal::Fixnum(n) => fixnum_as_cell!(n),
             Literal::Integer(bigint_ptr) => {
                 typed_arena_ptr_as_cell!(bigint_ptr)
@@ -65,6 +69,9 @@ impl TryFrom<HeapCellValue> for Literal {
                      (ArenaHeaderTag::Rational, n) => {
                          Ok(Literal::Rational(n))
                      }
+                     (ArenaHeaderTag::IndexPtr, _ip) => {
+                         Ok(Literal::CodeIndex(CodeIndex::from(cons_ptr)))
+                     }
                      _ => {
                          Err(())
                      }
index e7f88095d09434ec8fbf3087868612331491afbb..802d51ebb36262db670ffc190b7e188460bfdd25 100644 (file)
@@ -21,12 +21,12 @@ pub(super) fn set_code_index(
     retraction_info: &mut RetractionInfo,
     compilation_target: &CompilationTarget,
     key: PredicateKey,
-    code_index: &CodeIndex,
+    mut code_index: CodeIndex,
     code_ptr: IndexPtr,
 ) {
     let record = match compilation_target {
         CompilationTarget::User => {
-            if IndexPtr::Undefined == code_index.get() {
+            if IndexPtrTag::Undefined == code_index.get().tag() {
                 code_index.set(code_ptr);
                 RetractionRecord::AddedUserPredicate(key)
             } else {
@@ -35,7 +35,7 @@ pub(super) fn set_code_index(
             }
         }
         CompilationTarget::Module(ref module_name) => {
-            if IndexPtr::Undefined == code_index.get() {
+            if IndexPtrTag::Undefined == code_index.get().tag() {
                 code_index.set(code_ptr);
                 RetractionRecord::AddedModulePredicate(*module_name, key)
             } else {
@@ -48,12 +48,10 @@ pub(super) fn set_code_index(
     retraction_info.push_record(record);
 }
 
-fn add_op_decl_as_module_export(
+fn add_op_decl_as_module_export<'a, LS: LoadState<'a>>(
+    payload: &mut LS::LoaderFieldType,
     module_op_dir: &mut OpDir,
-    compilation_target: &CompilationTarget,
-    retraction_info: &mut RetractionInfo,
     wam_op_dir: &mut OpDir,
-    module_op_exports: &mut ModuleOpExports,
     op_decl: &OpDecl,
 ) {
     /*
@@ -65,20 +63,21 @@ fn add_op_decl_as_module_export(
 
     match op_decl.insert_into_op_dir(wam_op_dir) {
         Some(op_desc) => {
-            retraction_info.push_record(RetractionRecord::ReplacedUserOp(
+            payload.retraction_info.push_record(RetractionRecord::ReplacedUserOp(
                 *op_decl,
                 op_desc,
             ));
 
-            module_op_exports.push((*op_decl, Some(op_desc)));
+            payload.module_op_exports.push((*op_decl, Some(op_desc)));
         }
         None => {
-            retraction_info.push_record(RetractionRecord::AddedUserOp(*op_decl));
-            module_op_exports.push((*op_decl, None));
+            payload.retraction_info.push_record(RetractionRecord::AddedUserOp(*op_decl));
+            payload.module_op_exports.push((*op_decl, None));
         }
     }
 
-    add_op_decl(retraction_info, compilation_target, module_op_dir, op_decl);
+    let compilation_target = payload.compilation_target;
+    add_op_decl(&mut payload.retraction_info, &compilation_target, module_op_dir, op_decl);
 }
 
 pub(super) fn add_op_decl(
@@ -117,8 +116,8 @@ pub(super) fn add_op_decl(
     }
 }
 
-pub(super) fn import_module_exports(
-    retraction_info: &mut RetractionInfo,
+pub(super) fn import_module_exports<'a, LS: LoadState<'a>>(
+    payload: &mut LS::LoaderFieldType,
     compilation_target: &CompilationTarget,
     imported_module: &Module,
     code_dir: &mut CodeDir,
@@ -135,16 +134,18 @@ pub(super) fn import_module_exports(
                 }
 
                 if let Some(src_code_index) = imported_module.code_dir.get(&key) {
+                    let arena = &mut LS::machine_st(payload).arena;
+
                     let target_code_index = code_dir
                         .entry(key)
-                        .or_insert_with(|| CodeIndex::new(IndexPtr::Undefined))
+                        .or_insert_with(|| CodeIndex::default(arena))
                         .clone();
 
                     set_code_index(
-                        retraction_info,
+                        &mut payload.retraction_info,
                         compilation_target,
                         key,
-                        &target_code_index,
+                        target_code_index,
                         src_code_index.get(),
                     );
                 } else {
@@ -155,7 +156,7 @@ pub(super) fn import_module_exports(
                 }
             }
             ModuleExport::OpDecl(ref op_decl) => {
-                add_op_decl(retraction_info, compilation_target, op_dir, op_decl);
+                add_op_decl(&mut payload.retraction_info, compilation_target, op_dir, op_decl);
             }
         }
     }
@@ -163,15 +164,14 @@ pub(super) fn import_module_exports(
     Ok(())
 }
 
-fn import_module_exports_into_module(
-    retraction_info: &mut RetractionInfo,
+fn import_module_exports_into_module<'a, LS: LoadState<'a>>(
+    payload: &mut LS::LoaderFieldType,
     compilation_target: &CompilationTarget,
     imported_module: &Module,
     code_dir: &mut CodeDir,
     op_dir: &mut OpDir,
     meta_predicates: &mut MetaPredicateDir,
     wam_op_dir: &mut OpDir,
-    module_op_exports: &mut ModuleOpExports,
 ) -> Result<(), SessionError> {
     for export in imported_module.module_decl.exports.iter() {
         match export {
@@ -183,16 +183,18 @@ fn import_module_exports_into_module(
                 }
 
                 if let Some(src_code_index) = imported_module.code_dir.get(&key) {
+                    let arena = &mut LS::machine_st(payload).arena;
+
                     let target_code_index = code_dir
                         .entry(key)
-                        .or_insert_with(|| CodeIndex::new(IndexPtr::Undefined))
+                        .or_insert_with(|| CodeIndex::default(arena))
                         .clone();
 
                     set_code_index(
-                        retraction_info,
+                        &mut payload.retraction_info,
                         compilation_target,
                         key,
-                        &target_code_index,
+                        target_code_index,
                         src_code_index.get(),
                     );
                 } else {
@@ -203,12 +205,10 @@ fn import_module_exports_into_module(
                 }
             }
             ModuleExport::OpDecl(ref op_decl) => {
-                add_op_decl_as_module_export(
+                add_op_decl_as_module_export::<LS>(
+                    payload,
                     op_dir,
-                    compilation_target,
-                    retraction_info,
                     wam_op_dir,
-                    module_op_exports,
                     op_decl,
                 );
             }
@@ -218,14 +218,12 @@ fn import_module_exports_into_module(
     Ok(())
 }
 
-fn import_qualified_module_exports(
-    retraction_info: &mut RetractionInfo,
+fn import_qualified_module_exports<'a, LS: LoadState<'a>>(
+    payload: &mut LS::LoaderFieldType,
     compilation_target: &CompilationTarget,
     imported_module: &Module,
     exports: &IndexSet<ModuleExport>,
-    code_dir: &mut CodeDir,
-    op_dir: &mut OpDir,
-    meta_predicates: &mut MetaPredicateDir,
+    wam_prelude: &mut MachinePreludeView,
 ) -> Result<(), SessionError> {
     for export in imported_module.module_decl.exports.iter() {
         if !exports.contains(export) {
@@ -237,20 +235,22 @@ fn import_qualified_module_exports(
                 let key = (*name, *arity);
 
                 if let Some(meta_specs) = imported_module.meta_predicates.get(&key) {
-                    meta_predicates.insert(key.clone(), meta_specs.clone());
+                    wam_prelude.indices.meta_predicates.insert(key.clone(), meta_specs.clone());
                 }
 
                 if let Some(src_code_index) = imported_module.code_dir.get(&key) {
-                    let target_code_index = code_dir
+                    let arena = &mut LS::machine_st(payload).arena;
+
+                    let target_code_index = wam_prelude.indices.code_dir
                         .entry(key.clone())
-                        .or_insert_with(|| CodeIndex::new(IndexPtr::Undefined))
+                        .or_insert_with(|| CodeIndex::new(IndexPtr::undefined(), arena))
                         .clone();
 
                     set_code_index(
-                        retraction_info,
+                        &mut payload.retraction_info,
                         compilation_target,
                         key,
-                        &target_code_index,
+                        target_code_index,
                         src_code_index.get(),
                     );
                 } else {
@@ -261,7 +261,12 @@ fn import_qualified_module_exports(
                 }
             }
             ModuleExport::OpDecl(ref op_decl) => {
-                add_op_decl(retraction_info, compilation_target, op_dir, op_decl);
+                add_op_decl(
+                    &mut payload.retraction_info,
+                    compilation_target,
+                    &mut wam_prelude.indices.op_dir,
+                    op_decl,
+                );
             }
         }
     }
@@ -269,17 +274,17 @@ fn import_qualified_module_exports(
     Ok(())
 }
 
-fn import_qualified_module_exports_into_module(
-    retraction_info: &mut RetractionInfo,
-    compilation_target: &CompilationTarget,
+fn import_qualified_module_exports_into_module<'a, LS: LoadState<'a>>(
+    payload: &mut LS::LoaderFieldType,
     imported_module: &Module,
     exports: &IndexSet<ModuleExport>,
     code_dir: &mut CodeDir,
     op_dir: &mut OpDir,
     meta_predicates: &mut MetaPredicateDir,
     wam_op_dir: &mut OpDir,
-    module_op_exports: &mut ModuleOpExports,
 ) -> Result<(), SessionError> {
+    let payload_compilation_target = payload.compilation_target;
+
     for export in imported_module.module_decl.exports.iter() {
         if !exports.contains(export) {
             continue;
@@ -294,16 +299,18 @@ fn import_qualified_module_exports_into_module(
                 }
 
                 if let Some(src_code_index) = imported_module.code_dir.get(&key) {
+                    let arena = &mut LS::machine_st(payload).arena;
+
                     let target_code_index = code_dir
                         .entry(key)
-                        .or_insert_with(|| CodeIndex::new(IndexPtr::Undefined))
+                        .or_insert_with(|| CodeIndex::new(IndexPtr::undefined(), arena))
                         .clone();
 
                     set_code_index(
-                        retraction_info,
-                        compilation_target,
+                        &mut payload.retraction_info,
+                        &payload_compilation_target,
                         key,
-                        &target_code_index,
+                        target_code_index,
                         src_code_index.get(),
                     );
                 } else {
@@ -314,12 +321,10 @@ fn import_qualified_module_exports_into_module(
                 }
             }
             ModuleExport::OpDecl(ref op_decl) => {
-                add_op_decl_as_module_export(
+                add_op_decl_as_module_export::<LS>(
+                    payload,
                     op_dir,
-                    compilation_target,
-                    retraction_info,
                     wam_op_dir,
-                    module_op_exports,
                     op_decl,
                 );
             }
@@ -464,7 +469,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
             None => return,
         };
 
-        for (key, code_index) in &removed_module.code_dir {
+        for (key, code_index) in removed_module.code_dir.iter_mut() {
             match removed_module
                 .local_extensible_predicates
                 .get(&(CompilationTarget::User, *key))
@@ -473,7 +478,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
                 _ => {}
             }
 
-            let old_index_ptr = code_index.replace(IndexPtr::Undefined);
+            let old_index_ptr = code_index.replace(IndexPtr::undefined());
 
             self.payload.retraction_info
                 .push_record(RetractionRecord::ReplacedModulePredicate(
@@ -512,11 +517,11 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
             for export in removed_module.module_decl.exports.iter() {
                 match export {
                     ModuleExport::PredicateKey(ref key) => {
-                        match (removed_module.code_dir.get(key), code_dir.get(key)) {
+                        match (removed_module.code_dir.get(key), code_dir.get_mut(key)) {
                             (Some(module_code_index), Some(target_code_index))
                                 if module_code_index.get() == target_code_index.get() =>
                             {
-                                let old_index_ptr = target_code_index.replace(IndexPtr::Undefined);
+                                let old_index_ptr = target_code_index.replace(IndexPtr::undefined());
                                 retraction_info.push_record(predicate_retractor(*key, old_index_ptr));
                             }
                             _ => {}
@@ -584,7 +589,10 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
             Some(ref mut module) => module
                 .code_dir
                 .entry(key)
-                .or_insert_with(|| CodeIndex::new(IndexPtr::Undefined))
+                .or_insert_with(|| CodeIndex::new(
+                    IndexPtr::undefined(),
+                    &mut LS::machine_st(&mut self.payload).arena,
+                ))
                 .clone(),
             None => {
                 self.add_dynamically_generated_module(module_name);
@@ -593,7 +601,10 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
                     Some(ref mut module) => module
                         .code_dir
                         .entry(key)
-                        .or_insert_with(|| CodeIndex::new(IndexPtr::Undefined))
+                        .or_insert_with(|| CodeIndex::new(
+                            IndexPtr::undefined(),
+                            &mut LS::machine_st(&mut self.payload).arena,
+                        ))
                         .clone(),
                     None => {
                         unreachable!()
@@ -608,13 +619,15 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
         key: PredicateKey,
         compilation_target: CompilationTarget,
     ) -> CodeIndex {
+        let arena = &mut LS::machine_st(&mut self.payload).arena;
+
         match compilation_target {
             CompilationTarget::User => self
                 .wam_prelude
                 .indices
                 .code_dir
                 .entry(key)
-                .or_insert_with(|| CodeIndex::new(IndexPtr::Undefined))
+                .or_insert_with(|| CodeIndex::new(IndexPtr::undefined(), arena))
                 .clone(),
             CompilationTarget::Module(module_name) => {
                 self.get_or_insert_local_code_index(module_name, key)
@@ -627,13 +640,15 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
         module_name: Atom,
         key: PredicateKey,
     ) -> CodeIndex {
+        let arena = &mut LS::machine_st(&mut self.payload).arena;
+
         if module_name == atom!("user") {
             return self
                 .wam_prelude
                 .indices
                 .code_dir
                 .entry(key)
-                .or_insert_with(|| CodeIndex::new(IndexPtr::Undefined))
+                .or_insert_with(|| CodeIndex::new(IndexPtr::undefined(), arena))
                 .clone();
         } else {
             self.get_or_insert_local_code_index(module_name, key)
@@ -732,14 +747,10 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
             CompilationTarget::Module(ref module_name) => {
                 match self.wam_prelude.indices.modules.get_mut(module_name) {
                     Some(ref mut module) => {
-                        let payload: &mut LoadStatePayload<_> = &mut self.payload;
-
-                        add_op_decl_as_module_export(
+                        add_op_decl_as_module_export::<LS>(
+                            &mut self.payload,
                             &mut module.op_dir,
-                            &payload.compilation_target,
-                            &mut payload.retraction_info,
                             &mut self.wam_prelude.indices.op_dir,
-                            &mut payload.module_op_exports,
                             op_decl,
                         );
                     }
@@ -752,7 +763,9 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
     }
 
     pub(super) fn get_clause_type(&mut self, name: Atom, arity: usize) -> ClauseType {
-        match ClauseType::from(name, arity) {
+        let arena = &mut LS::machine_st(&mut self.payload).arena;
+
+        match ClauseType::from(name, arity, arena) {
             ClauseType::Named(arity, name, _) => {
                 let payload_compilation_target = self.payload.compilation_target;
 
@@ -773,7 +786,9 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
         name: Atom,
         arity: usize,
     ) -> ClauseType {
-        match ClauseType::from(name, arity) {
+        let arena = &mut LS::machine_st(&mut self.payload).arena;
+
+        match ClauseType::from(name, arity, arena) {
             ClauseType::Named(arity, name, _) => {
                 let key = (name, arity);
                 let idx = self.get_or_insert_qualified_code_index(module_name, key);
@@ -784,6 +799,16 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
         }
     }
 
+    pub(super) fn get_meta_specs(&self, name: Atom, arity: usize) -> Option<&Vec<MetaSpec>> {
+        self.wam_prelude
+            .indices
+            .get_meta_predicate_spec(
+                name,
+                arity,
+                &self.payload.compilation_target,
+            )
+    }
+
     pub(super) fn add_meta_predicate_record(
         &mut self,
         module_name: Atom,
@@ -894,8 +919,8 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
                 return;
             }
 
-            import_module_exports(
-                &mut self.payload.retraction_info,
+            import_module_exports::<LS>(
+                &mut self.payload,
                 &module_compilation_target,
                 builtins,
                 code_dir,
@@ -992,14 +1017,10 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
 
         for export in &module.module_decl.exports {
             if let ModuleExport::OpDecl(ref op_decl) = export {
-                let payload: &mut LoadStatePayload<_> = &mut self.payload;
-
-                add_op_decl_as_module_export(
+                add_op_decl_as_module_export::<LS>(
+                    &mut self.payload,
                     &mut module.op_dir,
-                    &payload.compilation_target, // this is a Module.
-                    &mut payload.retraction_info,
                     &mut self.wam_prelude.indices.op_dir,
-                    &mut payload.module_op_exports,
                     op_decl,
                 );
             }
@@ -1018,8 +1039,8 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
 
             match &payload_compilation_target {
                 CompilationTarget::User => {
-                    import_module_exports(
-                        &mut self.payload.retraction_info,
+                    import_module_exports::<LS>(
+                        &mut self.payload,
                         &payload_compilation_target,
                         &module,
                         &mut self.wam_prelude.indices.code_dir,
@@ -1030,17 +1051,14 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
                 CompilationTarget::Module(ref defining_module_name) => {
                     match self.wam_prelude.indices.modules.get_mut(defining_module_name) {
                         Some(ref mut target_module) => {
-                            let payload: &mut LoadStatePayload<_> = &mut self.payload;
-
-                            import_module_exports_into_module(
-                                &mut payload.retraction_info,
+                            import_module_exports_into_module::<LS>(
+                                &mut self.payload,
                                 &payload_compilation_target,
                                 &module,
                                 &mut target_module.code_dir,
                                 &mut target_module.op_dir,
                                 &mut target_module.meta_predicates,
                                 &mut self.wam_prelude.indices.op_dir,
-                                &mut payload.module_op_exports,
                             )?;
                         }
                         None => {
@@ -1070,47 +1088,38 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
         if let Some(module) = self.wam_prelude.indices.modules.remove(&module_name) {
             let payload_compilation_target = self.payload.compilation_target;
 
-            match &payload_compilation_target {
+            let result = match &payload_compilation_target {
                 CompilationTarget::User => {
-                    import_qualified_module_exports(
-                        &mut self.payload.retraction_info,
+                    import_qualified_module_exports::<LS>(
+                        &mut self.payload,
                         &payload_compilation_target,
                         &module,
                         &exports,
-                        &mut self.wam_prelude.indices.code_dir,
-                        &mut self.wam_prelude.indices.op_dir,
-                        &mut self.wam_prelude.indices.meta_predicates,
-                    )?;
+                        &mut self.wam_prelude,
+                    )
                 }
                 CompilationTarget::Module(ref defining_module_name) => {
                     match self.wam_prelude.indices.modules.get_mut(defining_module_name) {
                         Some(ref mut target_module) => {
-                            let payload: &mut LoadStatePayload<_> = &mut self.payload;
-
-                            import_qualified_module_exports_into_module(
-                                &mut payload.retraction_info,
-                                &payload_compilation_target,
+                            import_qualified_module_exports_into_module::<LS>(
+                                &mut self.payload,
                                 &module,
                                 &exports,
                                 &mut target_module.code_dir,
                                 &mut target_module.op_dir,
                                 &mut target_module.meta_predicates,
                                 &mut self.wam_prelude.indices.op_dir,
-                                &mut payload.module_op_exports,
-                            )?;
+                            )
                         }
                         None => {
-                            // we find ourselves here because we're trying to import
-                            // a module into itself as it is being defined.
-                            self.wam_prelude.indices.modules.insert(module_name, module);
-                            return Err(SessionError::ModuleCannotImportSelf(module_name));
+                            Err(SessionError::ModuleCannotImportSelf(module_name))
                         }
                     }
                 }
-            }
+            };
 
             self.wam_prelude.indices.modules.insert(module_name, module);
-            Ok(())
+            result
         } else {
             Err(SessionError::ExistenceError(ExistenceError::Module(module_name)))
         }
@@ -1168,7 +1177,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
                     indices: self.wam_prelude.indices,
                     code: self.wam_prelude.code,
                     load_contexts: self.wam_prelude.load_contexts,
-                }
+                },
             };
 
             subloader.load()?
@@ -1231,7 +1240,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
                     indices: self.wam_prelude.indices,
                     code: self.wam_prelude.code,
                     load_contexts: self.wam_prelude.load_contexts,
-                }
+                },
             };
 
             subloader.load()?
index c974540f09d9629efab330113f59b1328fedbda4..77d73bd628767fb1f535a2f06f6b1b2fd8d174a2 100644 (file)
@@ -510,6 +510,21 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
                     term_stack.push(Term::Literal(Cell::default(), Literal::try_from(addr).unwrap()));
                 }
                 (HeapCellValueTag::Atom, (name, arity)) => {
+                    let h = iter.focus();
+                    let mut arity = arity;
+
+                    if iter.heap.len() > h + arity + 1 {
+                        let value = iter.heap[h + arity + 1];
+
+                        if let Some(idx) = get_structure_index(value) {
+                            term_stack.push(
+                                Term::Literal(Cell::default(), Literal::CodeIndex(idx))
+                            );
+
+                            arity += 1;
+                        }
+                    }
+
                     if arity == 0 {
                         term_stack.push(Term::Literal(Cell::default(), Literal::Atom(name)));
                     } else {
@@ -708,7 +723,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
                             module
                                 .code_dir
                                 .get_mut(&key)
-                                .map(|code_idx| code_idx.replace(old_code_idx));
+                                .map(|code_idx| code_idx.set(old_code_idx));
                         }
                         None => {}
                     }
@@ -733,7 +748,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
                         .indices
                         .code_dir
                         .get_mut(&key)
-                        .map(|code_idx| code_idx.replace(old_code_idx));
+                        .map(|code_idx| code_idx.set(old_code_idx));
                 }
                 RetractionRecord::AddedIndex(index_key, clause_loc) => {
                     // WAS: inner_index_locs) => {
@@ -1271,13 +1286,13 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
 
         let code_index = self.get_or_insert_code_index(key, compilation_target);
 
-        if let IndexPtr::Undefined = code_index.get() {
+        if code_index.is_undefined() {
             set_code_index(
                 &mut self.payload.retraction_info,
                 &compilation_target,
                 key,
-                &code_index,
-                IndexPtr::DynamicUndefined,
+                code_index,
+                IndexPtr::dynamic_undefined(),
             );
         }
     }
@@ -1491,7 +1506,6 @@ impl Machine {
         let mut loader = self.loader_from_heap_evacuable(temp_v!(3));
 
         let declare_module = || {
-            // let export_list = export_list?;
             let exports = loader.extract_module_export_list_from_heap(temp_v!(2))?;
 
             let module_decl = ModuleDecl {
@@ -2019,10 +2033,10 @@ impl Machine {
                 .indices
                 .remove_predicate_skeleton(&compilation_target, &key);
 
-            let code_index = loader
+            let mut code_index = loader
                 .get_or_insert_code_index(key, compilation_target);
 
-            code_index.set(IndexPtr::Undefined);
+            code_index.set(IndexPtr::undefined());
 
             loader.payload.compilation_target = clause_clause_compilation_target;
 
@@ -2187,7 +2201,7 @@ impl Machine {
 
         let (predicate_name, arity) = self
             .machine_st
-            .read_predicate_key(self.machine_st[temp_v!(2)], self.machine_st[temp_v!(3)]);
+            .read_predicate_key(self.machine_st.registers[2], self.machine_st.registers[3]);
 
         let compilation_target = match module_name {
             atom!("user") => CompilationTarget::User,
@@ -2313,7 +2327,7 @@ impl Machine {
             .machine_st
             .read_predicate_key(self.machine_st.registers[1], self.machine_st.registers[2]);
 
-        match ClauseType::from(key.0, key.1) {
+        match ClauseType::from(key.0, key.1, &mut self.machine_st.arena) {
             ClauseType::BuiltIn(_) | ClauseType::Inlined(..) | ClauseType::CallN(_) => {
                 return;
             }
@@ -2355,14 +2369,19 @@ impl<'a> Loader<'a, LiveLoadAndMachineState<'a>> {
 
 #[inline]
 pub(super) fn load_module(
+    machine_st: &mut MachineState,
     code_dir: &mut CodeDir,
     op_dir: &mut OpDir,
     meta_predicate_dir: &mut MetaPredicateDir,
     compilation_target: &CompilationTarget,
     module: &Module,
 ) {
-    import_module_exports(
-        &mut RetractionInfo::new(0),
+    let ts = LiveTermStream::new(ListingSource::User);
+    let payload = LoadStatePayload::new(0, ts);
+    let mut payload = LiveLoadAndMachineState::new(machine_st, payload);
+
+    import_module_exports::<LiveLoadAndMachineState>(
+        &mut payload,
         &compilation_target,
         module,
         code_dir,
index 794b09b11f8b8d5301ec5d41e597c01a198544b1..c949fb909f377b04ddba24abf82d16a435070192 100644 (file)
@@ -4,18 +4,18 @@ use crate::arena::*;
 use crate::atom_table::*;
 use crate::fixtures::*;
 use crate::forms::*;
-use crate::instructions::*;
 use crate::machine::loader::*;
 use crate::machine::machine_state::*;
 use crate::machine::streams::Stream;
 
 use fxhash::FxBuildHasher;
 use indexmap::IndexMap;
+use modular_bitfield::{BitfieldSpecifier, bitfield};
+use modular_bitfield::specifiers::*;
 
-use std::cell::Cell;
 use std::cmp::Ordering;
 use std::collections::BTreeSet;
-use std::ops::Deref;
+use std::ops::{Deref, DerefMut};
 use std::rc::Rc;
 
 use crate::types::*;
@@ -59,9 +59,6 @@ impl PartialOrd<Ref> for HeapCellValue {
                 }
             }
             (HeapCellValueTag::AttrVar | HeapCellValueTag::Var, h1) => {
-            // _ if self.is_ref() => {
-            //     let h1 = self.get_value();
-
                 match r.get_tag() {
                     RefTag::StackCell => Some(Ordering::Less),
                     _ => {
@@ -77,52 +74,133 @@ impl PartialOrd<Ref> for HeapCellValue {
     }
 }
 
+#[derive(BitfieldSpecifier, Copy, Clone, Debug, PartialEq)]
+#[bits = 7]
+pub enum IndexPtrTag {
+    DynamicUndefined = 0b1000101, // a predicate, declared as dynamic, whose location in code is as yet undefined.
+    DynamicIndex = 0b1000110,
+    Index = 0b1000111,
+    Undefined = 0b1001000,
+}
+
+#[bitfield]
 #[derive(Debug, Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
-pub enum IndexPtr {
-    DynamicUndefined, // a predicate, declared as dynamic, whose location in code is as yet undefined.
-    DynamicIndex(usize),
-    Index(usize),
-    Undefined,
+pub struct IndexPtr {
+    pub p: B56,
+    #[allow(unused)] m: bool,
+    pub tag: IndexPtrTag,
 }
 
-#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq)]
-pub struct CodeIndex(pub(crate) Rc<Cell<IndexPtr>>);
+impl IndexPtr {
+    pub(crate) fn dynamic_undefined() -> Self {
+        IndexPtr::new()
+            .with_p(0)
+            .with_m(false)
+            .with_tag(IndexPtrTag::DynamicUndefined)
+    }
 
-impl Deref for CodeIndex {
-    type Target = Cell<IndexPtr>;
+    pub(crate) fn undefined() -> Self {
+        IndexPtr::new()
+            .with_p(0)
+            .with_m(false)
+            .with_tag(IndexPtrTag::Undefined)
+    }
 
-    #[inline]
-    fn deref(&self) -> &Self::Target {
-        self.0.deref()
+    pub(crate) fn dynamic_index(p: usize) -> Self {
+        IndexPtr::new()
+            .with_p(p as u64)
+            .with_m(false)
+            .with_tag(IndexPtrTag::DynamicIndex)
+    }
+
+    pub(crate) fn index(p: usize) -> Self {
+        IndexPtr::new()
+            .with_p(p as u64)
+            .with_m(false)
+            .with_tag(IndexPtrTag::Index)
+    }
+}
+
+#[derive(Debug, Clone, Copy, Ord, Hash, PartialOrd, Eq, PartialEq)]
+pub struct CodeIndex(TypedArenaPtr<IndexPtr>);
+
+const_assert!(std::mem::align_of::<CodeIndex>() == 8);
+
+impl From<CodeIndex> for UntypedArenaPtr {
+    #[inline(always)]
+    fn from(ptr: CodeIndex) -> UntypedArenaPtr {
+        unsafe { std::mem::transmute(ptr.0.as_ptr()) }
+    }
+}
+
+impl From<UntypedArenaPtr> for CodeIndex {
+    #[inline(always)]
+    fn from(ptr: UntypedArenaPtr) -> CodeIndex {
+        CodeIndex(TypedArenaPtr::new(ptr.get_ptr() as *mut IndexPtr))
+    }
+}
+
+impl From<TypedArenaPtr<IndexPtr>> for CodeIndex {
+    #[inline(always)]
+    fn from(ptr: TypedArenaPtr<IndexPtr>) -> CodeIndex {
+        CodeIndex(ptr)
     }
 }
 
 impl CodeIndex {
     #[inline]
-    pub(super) fn new(ptr: IndexPtr) -> Self {
-        CodeIndex(Rc::new(Cell::new(ptr)))
+    pub(crate) fn new(ptr: IndexPtr, arena: &mut Arena) -> Self {
+        CodeIndex(arena_alloc!(ptr, arena))
     }
 
-    #[inline]
+    #[inline(always)]
+    pub(crate) fn default(arena: &mut Arena) -> Self {
+        CodeIndex::new(IndexPtr::undefined(), arena)
+    }
+
+    #[inline(always)]
     pub(crate) fn is_undefined(&self) -> bool {
-        match self.0.get() {
-            IndexPtr::Undefined => true, // | &IndexPtr::DynamicUndefined => true,
+        match self.0.tag() {
+            IndexPtrTag::Undefined => true, // | &IndexPtr::DynamicUndefined => true,
+            _ => false,
+        }
+    }
+
+
+    #[inline(always)]
+    pub(crate) fn is_dynamic_undefined(&self) -> bool {
+        match self.0.tag() {
+            IndexPtrTag::DynamicUndefined => true,
             _ => false,
         }
     }
 
     pub(crate) fn local(&self) -> Option<usize> {
-        match self.0.get() {
-            IndexPtr::Index(i) => Some(i),
-            IndexPtr::DynamicIndex(i) => Some(i),
+        match self.0.tag() {
+            IndexPtrTag::Index => Some(self.0.p() as usize),
+            IndexPtrTag::DynamicIndex => Some(self.0.p() as usize),
             _ => None,
         }
     }
-}
 
-impl Default for CodeIndex {
-    fn default() -> Self {
-        CodeIndex(Rc::new(Cell::new(IndexPtr::Undefined)))
+    #[inline(always)]
+    pub(crate) fn get(&self) -> IndexPtr {
+        *self.0.deref()
+    }
+
+    #[inline(always)]
+    pub(crate) fn set(&mut self, value: IndexPtr) {
+        *self.0.deref_mut() = value;
+    }
+
+    #[inline(always)]
+    pub(crate) fn replace(&mut self, value: IndexPtr) -> IndexPtr {
+        std::mem::replace(self.0.deref_mut(), value)
+    }
+
+    #[inline(always)]
+    pub(crate) fn as_ptr(&self) -> *const IndexPtr {
+        self.0.as_ptr()
     }
 }
 
@@ -269,19 +347,22 @@ impl IndexStore {
         module: Atom,
     ) -> Option<CodeIndex> {
         if module == atom!("user") {
-            match ClauseType::from(name, arity) {
-                ClauseType::Named(arity, name, _) => self.code_dir.get(&(name, arity)).cloned(),
-                _ => None,
-            }
+            /*match ClauseType::from(name, arity) {
+                ClauseType::Named(arity, name, _) => */
+            self.code_dir.get(&(name, arity)).cloned()
+            /*    _ => None,
+            }*/
         } else {
             self.modules
                 .get(&module)
-                .and_then(|module| match ClauseType::from(name, arity) {
-                    ClauseType::Named(arity, name, _) => {
+                .and_then(|module|/* |module| match ClauseType::from(name, arity) {
+                    ClauseType::Named(arity, name, _) => { */
                         module.code_dir.get(&(name, arity)).cloned()
+                    /*
                     }
                     _ => None,
-                })
+                } */
+                )
         }
     }
 
index 17b8eec5781124370a739a4bf9ebf32a06112c50..05ff14c80cc48c4ba262d69370e8fc6b730689a1 100644 (file)
@@ -418,6 +418,17 @@ impl MachineState {
                         }
                     }
                 }
+                (HeapCellValueTag::Str, s) => {
+                    let (name, arity) = cell_as_atom_cell!(self.heap[s])
+                        .get_name_and_arity();
+
+                    if arity == 0 {
+                        if let Some(c) = name.as_char() {
+                            chars.push(c);
+                            continue;
+                        }
+                    }
+                }
                 _ => {
                 }
             );
@@ -454,6 +465,20 @@ impl MachineState {
         self.b0 = self.b;
     }
 
+    #[inline(always)]
+    pub fn neck_cut(&mut self) {
+        let b = self.b;
+        let b0 = self.b0;
+
+        if b > b0 {
+            self.b = b0;
+
+            if b > self.e {
+                self.stack.truncate(b);
+            }
+        }
+    }
+
     // Safety: the atom_tbl lives for the lifetime of the machine, as does the helper, so the ptr
     // will always be valid.
     pub fn read_term_from_user_input(&mut self, stream: Stream, indices: &mut IndexStore) -> CallResult {
@@ -666,6 +691,13 @@ impl MachineState {
                                         debug_assert_eq!(_arity, 0);
                                         var_names.insert(var, Rc::new(name.as_str().to_owned()));
                                     }
+                                    (HeapCellValueTag::Str, s) => {
+                                        let (name, arity) = cell_as_atom_cell!(self.heap[s])
+                                            .get_name_and_arity();
+
+                                        debug_assert_eq!(arity, 0);
+                                        var_names.insert(var, Rc::new(name.as_str().to_owned()));
+                                    }
                                     _ => {
                                         unreachable!();
                                     }
@@ -677,34 +709,64 @@ impl MachineState {
                     );
                 }
 
+                let ignore_ops = read_heap_cell!(ignore_ops,
+                    (HeapCellValueTag::Atom, (name, _arity)) => {
+                        name == atom!("true")
+                    }
+                    (HeapCellValueTag::Str, s) => {
+                        let (name, arity) = cell_as_atom_cell!(self.heap[s])
+                            .get_name_and_arity();
+
+                        debug_assert_eq!(arity, 0);
+                        name == atom!("true")
+                    }
+                    _ => {
+                        unreachable!()
+                    }
+                );
+
+                let numbervars = read_heap_cell!(numbervars,
+                    (HeapCellValueTag::Atom, (name, _arity)) => {
+                        name == atom!("true")
+                    }
+                    (HeapCellValueTag::Str, s) => {
+                        let (name, arity) = cell_as_atom_cell!(self.heap[s])
+                            .get_name_and_arity();
+
+                        debug_assert_eq!(arity, 0);
+                        name == atom!("true")
+                    }
+                    _ => {
+                        unreachable!()
+                    }
+                );
+
+                let quoted = read_heap_cell!(quoted,
+                    (HeapCellValueTag::Atom, (name, _arity)) => {
+                        name == atom!("true")
+                    }
+                    (HeapCellValueTag::Str, s) => {
+                        let (name, arity) = cell_as_atom_cell!(self.heap[s])
+                            .get_name_and_arity();
+
+                        debug_assert_eq!(arity, 0);
+                        name == atom!("true")
+                    }
+                    _ => {
+                        unreachable!()
+                    }
+                );
+
                 let mut printer = HCPrinter::new(
                     &mut self.heap,
-                    &mut self.arena,
                     op_dir,
                     PrinterOutputter::new(),
                     term_to_be_printed,
                 );
 
-                if let HeapCellValueTag::Atom = ignore_ops.get_tag() {
-                    let name = cell_as_atom!(ignore_ops);
-                    printer.ignore_ops = name == atom!("true");
-                } else {
-                    unreachable!();
-                }
-
-                if let HeapCellValueTag::Atom = numbervars.get_tag() {
-                    let name = cell_as_atom!(numbervars);
-                    printer.numbervars = name == atom!("true");
-                } else {
-                    unreachable!();
-                }
-
-                if let HeapCellValueTag::Atom = quoted.get_tag() {
-                    let name = cell_as_atom!(quoted);
-                    printer.quoted = name == atom!("true");
-                } else {
-                    unreachable!();
-                }
+                printer.ignore_ops = ignore_ops;
+                printer.numbervars = numbervars;
+                printer.quoted = quoted;
 
                 match Number::try_from(max_depth) {
                     Ok(Number::Fixnum(n)) => {
index 012c7d1917f530fecd04076734a601341b812113..b72b9cfed0440954deb86778a7cff870b0698277 100644 (file)
@@ -347,10 +347,27 @@ impl MachineState {
                 debug_assert_eq!(arity, 0);
                 self.fail = cstr_atom != atom!("[]");
             }
+            (HeapCellValueTag::Str, s) => {
+                let (name, arity) = cell_as_atom_cell!(self.heap[s])
+                    .get_name_and_arity();
+
+                if arity == 0 {
+                    self.fail = atom == atom!("") && name != atom!("[]");
+                } else {
+                    // this is intentionally the same policy for
+                    // value.tag() == Lis and PStrLoc. they're not
+                    // grouped together to allow for arity == 0.
+                    self.unify_partial_string(atom_as_cstr_cell!(atom), value);
+
+                    if !self.pdl.is_empty() {
+                        self.unify();
+                    }
+                }
+            }
             (HeapCellValueTag::CStr, cstr_atom) => {
                 self.fail = atom != cstr_atom;
             }
-            (HeapCellValueTag::Str | HeapCellValueTag::Lis | HeapCellValueTag::PStrLoc) => {
+            (HeapCellValueTag::Lis | HeapCellValueTag::PStrLoc) => {
                 self.unify_partial_string(atom_as_cstr_cell!(atom), value);
 
                 if !self.pdl.is_empty() {
@@ -553,6 +570,12 @@ impl MachineState {
             (HeapCellValueTag::Atom, (name, arity)) => {
                 self.fail = !(arity == 0 && name == atom);
             }
+            (HeapCellValueTag::Str, s) => {
+                let (name, arity) = cell_as_atom_cell!(self.heap[s])
+                    .get_name_and_arity();
+
+                self.fail = !(arity == 0 && name == atom);
+            }
             (HeapCellValueTag::CStr, cstr_atom) if atom == atom!("[]") => {
                 self.fail = cstr_atom != atom!("");
             }
@@ -587,6 +610,16 @@ impl MachineState {
                     self.fail = true;
                 }
             }
+            (HeapCellValueTag::Str, s) => {
+                let (name, arity) = cell_as_atom_cell!(self.heap[s])
+                    .get_name_and_arity();
+
+                if let Some(c2) = name.as_char() {
+                    self.fail = !(c == c2 && arity == 0);
+                } else {
+                    self.fail = true;
+                }
+            }
             (HeapCellValueTag::Char, c2) => {
                 if c != c2 {
                     self.fail = true;
@@ -739,11 +772,6 @@ impl MachineState {
                         self.unify_atom(name, d2);
                     }
                     (HeapCellValueTag::Str, s1) => {
-                        if d2.is_constant() {
-                            self.fail = true;
-                            break;
-                        }
-
                         if tabu_list.contains(&(d1, d2)) {
                             continue;
                         }
@@ -969,9 +997,7 @@ impl MachineState {
                 }
             }
             (HeapCellValueTag::Atom, (n2, a2)) => {
-                if !(a1 == 0 && a2 == 0 && n1 == n2) {
-                    self.fail = true;
-                }
+                self.fail = !(a1 == 0 && a2 == 0 && n1 == n2);
             }
             (HeapCellValueTag::AttrVar, h) => {
                 if self.bind_with_occurs_check(Ref::attr_var(h), str_loc_as_cell!(s1)) {
@@ -1285,11 +1311,6 @@ impl MachineState {
                         self.unify_atom(name, d2);
                     }
                     (HeapCellValueTag::Str, s1) => {
-                        if d2.is_constant() {
-                            self.fail = true;
-                            break;
-                        }
-
                         if tabu_list.contains(&(d1, d2)) {
                             continue;
                         }
@@ -1492,8 +1513,8 @@ impl MachineState {
             let v1 = self.store(s1);
             let v2 = self.store(s2);
 
-            let order_cat_v1 = v1.order_category();
-            let order_cat_v2 = v2.order_category();
+            let order_cat_v1 = v1.order_category(&self.heap);
+            let order_cat_v2 = v2.order_category(&self.heap);
 
             if order_cat_v1 != order_cat_v2 {
                 self.pdl.clear();
@@ -1552,6 +1573,15 @@ impl MachineState {
                                         );
                                     }
                                 }
+                                (HeapCellValueTag::Str, s) => {
+                                    let n2 = cell_as_atom_cell!(self.heap[s])
+                                        .get_name();
+
+                                    if n1 != n2 {
+                                        self.pdl.clear();
+                                        return Some(n1.cmp(&n2));
+                                    }
+                                }
                                 _ => {
                                     unreachable!();
                                 }
@@ -1579,11 +1609,67 @@ impl MachineState {
                                         return Some(c1.cmp(&c2));
                                     }
                                 }
+                                (HeapCellValueTag::Str, s) => {
+                                    let n2 = cell_as_atom_cell!(self.heap[s])
+                                        .get_name();
+
+                                    if let Some(c2) = n2.as_char() {
+                                        if c1 != c2 {
+                                            self.pdl.clear();
+                                            return Some(c1.cmp(&c2));
+                                        }
+                                    } else {
+                                        self.pdl.clear();
+                                        return Some(
+                                            Some(c1).cmp(&n2.chars().next())
+                                                    .then(Ordering::Less)
+                                        );
+                                    }
+                                }
                                 _ => {
                                     unreachable!()
                                 }
                             )
                         }
+                        (HeapCellValueTag::Str, s) => {
+                            let n1 = cell_as_atom_cell!(self.heap[s])
+                                .get_name();
+
+                            read_heap_cell!(v2,
+                                (HeapCellValueTag::Atom, (n2, _a2)) => {
+                                    if n1 != n2 {
+                                        self.pdl.clear();
+                                        return Some(n1.cmp(&n2));
+                                    }
+                                }
+                                (HeapCellValueTag::Char, c2) => {
+                                    if let Some(c1) = n1.as_char() {
+                                        if c1 != c2 {
+                                            self.pdl.clear();
+                                            return Some(c1.cmp(&c2));
+                                        }
+                                    } else {
+                                        self.pdl.clear();
+                                        return Some(
+                                            n1.chars().next().cmp(&Some(c2))
+                                              .then(Ordering::Greater)
+                                        );
+                                    }
+                                }
+                                (HeapCellValueTag::Str, s) => {
+                                    let n2 = cell_as_atom_cell!(self.heap[s])
+                                        .get_name();
+
+                                    if n1 != n2 {
+                                        self.pdl.clear();
+                                        return Some(n1.cmp(&n2));
+                                    }
+                                }
+                                _ => {
+                                    unreachable!();
+                                }
+                            )
+                        }
                         _ => {
                             unreachable!()
                         }
@@ -1597,8 +1683,8 @@ impl MachineState {
                     ) -> Option<Ordering> {
                         let compound = Some(TermOrderCategory::Compound);
 
-                        if iter2.focus.order_category() != compound {
-                            Some(compound.cmp(&iter2.focus.order_category()))
+                        if iter2.focus.order_category(iter2.heap) != compound {
+                            Some(compound.cmp(&iter2.focus.order_category(iter2.heap)))
                         } else {
                             let c1 = match iteratee {
                                 PStrIteratee::Char(_, c) => c,
@@ -2116,7 +2202,7 @@ impl MachineState {
                     heap_bound_deref(iter.heap, value),
                 ));
 
-                if value.is_compound() {
+                if value.is_compound(iter.heap) {
                     return true;
                 }
             }
@@ -2403,6 +2489,21 @@ impl MachineState {
                             a1.as_var().unwrap(),
                         );
                     }
+                    (HeapCellValueTag::Str, s) => {
+                        let (name, atom_arity) = cell_as_atom_cell!(self.heap[s])
+                            .get_name_and_arity();
+
+                        if atom_arity == 0 {
+                            self.try_functor_fabricate_struct(
+                                name,
+                                arity as usize,
+                                a1.as_var().unwrap(),
+                            );
+                        } else {
+                            let err = self.type_error(ValidType::Atomic, store_name);
+                            return Err(self.error_form(err, stub_gen()));
+                        }
+                    }
                     (HeapCellValueTag::Char, c) => {
                         let c = self.atom_tbl.build_with(&c.to_string());
 
@@ -2444,6 +2545,17 @@ impl MachineState {
                 let err = self.instantiation_error();
                 Err(self.error_form(err, stub_gen()))
             }
+            (HeapCellValueTag::Str, s) => {
+                let (name, arity) = cell_as_atom_cell!(self.heap[s])
+                    .get_name_and_arity();
+
+                if name == atom!("[]") && arity == 0 {
+                    Ok(vec![])
+                } else {
+                    let err = self.type_error(ValidType::List, value);
+                    Err(self.error_form(err, stub_gen()))
+                }
+            }
             (HeapCellValueTag::Atom, (name, arity)) => {
                 if name == atom!("[]") && arity == 0 {
                     Ok(vec![])
@@ -2484,6 +2596,17 @@ impl MachineState {
                 (HeapCellValueTag::PStrLoc, l) => {
                     return self.try_from_partial_string(result, l, stub_gen, a1);
                 }
+                (HeapCellValueTag::Str, s) => {
+                    let (name, arity) = cell_as_atom_cell!(self.heap[s])
+                        .get_name_and_arity();
+
+                    if name == atom!("[]") && arity == 0 {
+                        break;
+                    } else {
+                        let err = self.type_error(ValidType::List, a1);
+                        return Err(self.error_form(err, stub_gen()));
+                    }
+                }
                 (HeapCellValueTag::Atom, (name, arity)) => {
                     if name == atom!("[]") && arity == 0 {
                         break;
index d647f75671841b3f0ee26b86ff9cdf419a380ced..f18d957589f34aea98b511090a7ecfaed242d251 100644 (file)
@@ -61,7 +61,6 @@ impl MockWAM {
 
         let mut printer = HCPrinter::new(
             &mut self.machine_st.heap,
-            &mut self.machine_st.arena,
             &self.op_dir,
             PrinterOutputter::new(),
             heap_loc_as_cell!(term_write_result.heap_loc),
@@ -272,6 +271,7 @@ impl Machine {
 
         if let Some(ref mut builtins) = wam.indices.modules.get_mut(&atom!("builtins")) {
             load_module(
+                &mut wam.machine_st,
                 &mut wam.indices.code_dir,
                 &mut wam.indices.op_dir,
                 &mut wam.indices.meta_predicates,
@@ -297,6 +297,7 @@ impl Machine {
 
         if let Some(loader) = wam.indices.modules.get(&atom!("loader")) {
             load_module(
+                &mut wam.machine_st,
                 &mut wam.indices.code_dir,
                 &mut wam.indices.op_dir,
                 &mut wam.indices.meta_predicates,
index 074e8f42e2f0a2bc0815190f58b27327d13da024..f34f38fbe70df737cbb361315eb29f2928bbf16f 100644 (file)
@@ -22,6 +22,7 @@ pub mod streams;
 pub mod system_calls;
 pub mod term_stream;
 
+use crate::arena::*;
 use crate::arithmetic::*;
 use crate::atom_table::*;
 use crate::forms::*;
@@ -160,6 +161,24 @@ pub(crate) fn import_builtin_impls(code_dir: &CodeDir, builtins: &mut Module) {
     }
 }
 
+#[inline]
+pub(crate) fn get_structure_index(value: HeapCellValue) -> Option<CodeIndex> {
+    read_heap_cell!(value,
+        (HeapCellValueTag::Cons, cons_ptr) => {
+             match_untyped_arena_ptr!(cons_ptr,
+                 (ArenaHeaderTag::IndexPtr, ip) => {
+                     return Some(CodeIndex::from(ip));
+                 }
+                 _ => {}
+             );
+        }
+        _ => {
+        }
+    );
+
+    None
+}
+
 impl Machine {
     #[inline]
     pub fn prelude_view_and_machine_st(&mut self) -> (MachinePreludeView, &mut MachineState) {
@@ -220,6 +239,7 @@ impl Machine {
 
         if let Some(toplevel) = self.indices.modules.get(&atom!("$toplevel")) {
             load_module(
+                &mut self.machine_st,
                 &mut self.indices.code_dir,
                 &mut self.indices.op_dir,
                 &mut self.indices.meta_predicates,
@@ -287,7 +307,7 @@ impl Machine {
     }
 
     pub(crate) fn configure_modules(&mut self) {
-        fn update_call_n_indices(loader: &Module, target_code_dir: &mut CodeDir) {
+        fn update_call_n_indices(loader: &Module, target_code_dir: &mut CodeDir, arena: &mut Arena) {
             for arity in 1..66 {
                 let key = (atom!("call"), arity);
 
@@ -295,7 +315,7 @@ impl Machine {
                     Some(src_code_index) => {
                         let target_code_index = target_code_dir
                             .entry(key)
-                            .or_insert_with(|| CodeIndex::new(IndexPtr::Undefined));
+                            .or_insert_with(|| CodeIndex::new(IndexPtr::undefined(), arena));
 
                         target_code_index.set(src_code_index.get());
                     }
@@ -311,6 +331,7 @@ impl Machine {
                 // Import loader's exports into the builtins module so they will be
                 // implicitly included in every further module.
                 load_module(
+                    &mut self.machine_st,
                     &mut builtins.code_dir,
                     &mut builtins.op_dir,
                     &mut builtins.meta_predicates,
@@ -331,10 +352,10 @@ impl Machine {
             }
 
             for (_, target_module) in self.indices.modules.iter_mut() {
-                update_call_n_indices(&loader, &mut target_module.code_dir);
+                update_call_n_indices(&loader, &mut target_module.code_dir, &mut self.machine_st.arena);
             }
 
-            update_call_n_indices(&loader, &mut self.indices.code_dir);
+            update_call_n_indices(&loader, &mut self.indices.code_dir, &mut self.machine_st.arena);
 
             self.indices.modules.insert(atom!("loader"), loader);
         } else {
@@ -393,7 +414,10 @@ impl Machine {
 
         for (p, instr) in self.code[impls_offset ..].iter().enumerate() {
             let key = instr.to_name_and_arity();
-            self.indices.code_dir.insert(key, CodeIndex::new(IndexPtr::Index(p + impls_offset)));
+            self.indices.code_dir.insert(
+                key,
+                CodeIndex::new(IndexPtr::index(p + impls_offset), &mut self.machine_st.arena),
+            );
         }
     }
 
@@ -455,6 +479,7 @@ impl Machine {
 
         if let Some(builtins) = wam.indices.modules.get_mut(&atom!("builtins")) {
             load_module(
+                &mut wam.machine_st,
                 &mut wam.indices.code_dir,
                 &mut wam.indices.op_dir,
                 &mut wam.indices.meta_predicates,
@@ -480,6 +505,7 @@ impl Machine {
 
         if let Some(loader) = wam.indices.modules.get(&atom!("loader")) {
             load_module(
+                &mut wam.machine_st,
                 &mut wam.indices.code_dir,
                 &mut wam.indices.op_dir,
                 &mut wam.indices.meta_predicates,
@@ -666,18 +692,20 @@ impl Machine {
 
     #[inline(always)]
     fn try_call(&mut self, name: Atom, arity: usize, idx: IndexPtr) -> CallResult {
-        match idx {
-            IndexPtr::DynamicUndefined => {
+        let compiled_tl_index = idx.p() as usize;
+
+        match idx.tag() {
+            IndexPtrTag::DynamicUndefined => {
                 self.machine_st.fail = true;
             }
-            IndexPtr::Undefined => {
+            IndexPtrTag::Undefined => {
                 return Err(self.machine_st.throw_undefined_error(name, arity));
             }
-            IndexPtr::DynamicIndex(compiled_tl_index) => {
+            IndexPtrTag::DynamicIndex => {
                 self.machine_st.dynamic_mode = FirstOrNext::First;
                 self.machine_st.call_at_index(arity, compiled_tl_index);
             }
-            IndexPtr::Index(compiled_tl_index) => {
+            IndexPtrTag::Index => {
                 self.machine_st.call_at_index(arity, compiled_tl_index);
             }
         }
@@ -687,18 +715,20 @@ impl Machine {
 
     #[inline(always)]
     fn try_execute(&mut self, name: Atom, arity: usize, idx: IndexPtr) -> CallResult {
-        match idx {
-            IndexPtr::DynamicUndefined => {
+        let compiled_tl_index = idx.p() as usize;
+
+        match idx.tag() {
+            IndexPtrTag::DynamicUndefined => {
                 self.machine_st.fail = true;
             }
-            IndexPtr::Undefined => {
+            IndexPtrTag::Undefined => {
                 return Err(self.machine_st.throw_undefined_error(name, arity));
             }
-            IndexPtr::DynamicIndex(compiled_tl_index) => {
+            IndexPtrTag::DynamicIndex => {
                 self.machine_st.dynamic_mode = FirstOrNext::First;
                 self.machine_st.execute_at_index(arity, compiled_tl_index);
             }
-            IndexPtr::Index(compiled_tl_index) => {
+            IndexPtrTag::Index => {
                 self.machine_st.execute_at_index(arity, compiled_tl_index)
             }
         }
index 6b925522e52590be997dc54522c207972b09ea60..70a61f1d970e798d78f4b5578c9375eae1885d14 100644 (file)
@@ -470,14 +470,133 @@ pub(super) fn setup_declaration<'a, LS: LoadState<'a>>(
     }
 }
 
+fn build_meta_predicate_clause<'a, LS: LoadState<'a>>(
+    loader: &mut Loader<'a, LS>,
+    module_name: Atom,
+    terms: Vec<Term>,
+    meta_specs: Vec<MetaSpec>,
+) -> Vec<Term> {
+    let mut arg_terms = Vec::with_capacity(terms.len());
+
+    for (term, meta_spec) in terms.into_iter().zip(meta_specs.iter()) {
+        if let MetaSpec::RequiresExpansionWithArgument(supp_args) = meta_spec {
+            if let Some(name) = term.name() {
+                if name == atom!("$call") {
+                    arg_terms.push(term);
+                    continue;
+                }
+
+                let arity = term.arity();
+
+                if let Term::Clause(_, _, ref terms) = &term {
+                    if let Some(Term::Literal(_, Literal::CodeIndex(_))) = terms.last() {
+                        arg_terms.push(term);
+                        continue;
+                    }
+                }
+
+                fn get_qualified_name(
+                    module_term: &Term,
+                    qualified_term: &Term,
+                ) -> Option<(Atom, Atom)> {
+                    if let Term::Literal(_, Literal::Atom(module_name)) = module_term {
+                        if let Some(name) = qualified_term.name() {
+                            return Some((*module_name, name));
+                        }
+                    }
+
+                    None
+                }
+
+                let (idx, term) = match term {
+                    Term::Clause(cell, atom!(":"), mut terms) if terms.len() == 2 => {
+                        if let Some((module_name, name)) = get_qualified_name(&terms[0], &terms[1])
+                        {
+                            (
+                                loader.get_or_insert_qualified_code_index(
+                                    module_name,
+                                    (name, terms[1].arity() + supp_args),
+                                ),
+                                terms.pop().unwrap(),
+                            )
+                        } else {
+                            arg_terms.push(Term::Clause(cell, atom!(":"), terms));
+                            continue;
+                        }
+                    }
+                    term => {
+                        (
+                            loader.get_or_insert_qualified_code_index(
+                                module_name,
+                                (name, arity + supp_args),
+                            ),
+                            term,
+                        )
+                    }
+                };
+
+                let term = match term {
+                    Term::Clause(cell, name, mut terms) => {
+                        terms.push(Term::Literal(Cell::default(), Literal::CodeIndex(idx)));
+                        Term::Clause(cell, name, terms)
+                    }
+                    Term::Literal(cell, Literal::Atom(name)) => {
+                        Term::Clause(
+                            cell,
+                            name,
+                            vec![Term::Literal(Cell::default(), Literal::CodeIndex(idx))],
+                        )
+                    }
+                    term => term,
+                };
+
+                arg_terms.push(term);
+                continue;
+            }
+        }
+
+        arg_terms.push(term);
+    }
+
+    arg_terms
+}
+
 #[inline]
 fn clause_to_query_term<'a, LS: LoadState<'a>>(
     loader: &mut Loader<'a, LS>,
     name: Atom,
-    terms: Vec<Term>,
+    mut terms: Vec<Term>,
     call_policy: CallPolicy,
 ) -> QueryTerm {
-    let ct = loader.get_clause_type(name, terms.len());
+    if let Some(Term::Literal(_, Literal::CodeIndex(_))) = terms.last() {
+        // supplementary code vector indices are unnecessary for
+        // root-level clauses.
+        terms.pop();
+    }
+
+    let mut ct = loader.get_clause_type(name, terms.len());
+
+    if let ClauseType::Named(arity, name, idx) = ct {
+        if let Some(meta_specs) = loader.get_meta_specs(name, arity).cloned() {
+            let module_name = loader.payload.compilation_target.module_name();
+            let terms = build_meta_predicate_clause(
+                loader,
+                module_name,
+                terms,
+                meta_specs,
+            );
+
+            return QueryTerm::Clause(
+                Cell::default(),
+                ClauseType::Named(arity, name, idx),
+                terms,
+                call_policy,
+            );
+        }
+
+        ct = ClauseType::Named(arity, name, idx);
+    }
+
     QueryTerm::Clause(Cell::default(), ct, terms, call_policy)
 }
 
@@ -486,112 +605,139 @@ fn qualified_clause_to_query_term<'a, LS: LoadState<'a>>(
     loader: &mut Loader<'a, LS>,
     module_name: Atom,
     name: Atom,
-    terms: Vec<Term>,
+    mut terms: Vec<Term>,
     call_policy: CallPolicy,
 ) -> QueryTerm {
-    let ct = loader.get_qualified_clause_type(module_name, name, terms.len());
-    QueryTerm::Clause(Cell::default(), ct, terms, call_policy)
-}
+    if let Some(Term::Literal(_, Literal::CodeIndex(_))) = terms.last() {
+        // supplementary code vector indices are unnecessary for
+        // root-level clauses.
+        terms.pop();
+    }
 
-#[derive(Debug)]
-pub(crate) struct Preprocessor {
-    queue: VecDeque<VecDeque<Term>>,
-    settings: CodeGenSettings,
-}
+    let mut ct = loader.get_qualified_clause_type(module_name, name, terms.len());
 
-impl Preprocessor {
-    pub(super) fn new(settings: CodeGenSettings) -> Self {
-        Preprocessor {
-            queue: VecDeque::new(),
-            settings,
+    if let ClauseType::Named(arity, name, idx) = ct {
+        if let Some(meta_specs) = loader.get_meta_specs(name, arity).cloned() {
+            let terms = build_meta_predicate_clause(
+                loader,
+                module_name,
+                terms,
+                meta_specs,
+            );
+
+            return QueryTerm::Clause(
+                Cell::default(),
+                ClauseType::Named(arity, name, idx),
+                terms,
+                call_policy,
+            );
         }
+
+        ct = ClauseType::Named(arity, name, idx);
     }
 
-    fn setup_fact(&mut self, term: Term) -> Result<Term, CompilationError> {
-        match term {
-            Term::Clause(..) | Term::Literal(_, Literal::Atom(..)) => Ok(term),
-            _ => Err(CompilationError::InadmissibleFact),
+    QueryTerm::Clause(Cell::default(), ct, terms, call_policy)
+}
+
+fn compute_head(term: &Term) -> Vec<Term> {
+    let mut vars = IndexSet::new();
+
+    for term in post_order_iter(term) {
+        if let TermRef::Var(_, _, v) = term {
+            vars.insert(v.clone());
         }
     }
 
-    fn compute_head(&self, term: &Term) -> Vec<Term> {
-        let mut vars = IndexSet::new();
+    vars.insert(Rc::new(String::from("!")));
+    vars.into_iter()
+        .map(|v| Term::Var(Cell::default(), v))
+        .collect()
+}
 
-        for term in post_order_iter(term) {
-            if let TermRef::Var(_, _, v) = term {
-                vars.insert(v.clone());
-            }
-        }
+pub(crate) fn build_rule_body(vars: &[Term], body_term: Term) -> Term {
+    let head_term = Term::Clause(Cell::default(), atom!(""), vars.iter().cloned().collect());
+    let rule = vec![head_term, body_term];
 
-        vars.insert(Rc::new(String::from("!")));
-        vars.into_iter()
-            .map(|v| Term::Var(Cell::default(), v))
-            .collect()
-    }
+    Term::Clause(Cell::default(), atom!(":-"), rule)
+}
 
-    fn fabricate_rule_body(&self, vars: &Vec<Term>, body_term: Term) -> Term {
-        let head_term = Term::Clause(Cell::default(), atom!(""), vars.clone());
-        let rule = vec![head_term, body_term];
+// 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 build_rule(body_term: Term) -> (JumpStub, VecDeque<Term>) {
+    // collect the vars of body_term into a head, return the num_vars
+    // (the arity) as well.
+    let vars = compute_head(&body_term);
+    let rule = build_rule_body(&vars, body_term);
 
-        Term::Clause(Cell::default(), atom!(":-"), rule)
-    }
+    (vars, VecDeque::from(vec![rule]))
+}
 
-    // 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<Term>) {
-        // collect the vars of body_term into a head, return the num_vars
-        // (the arity) as well.
-        let vars = self.compute_head(&body_term);
-        let rule = self.fabricate_rule_body(&vars, body_term);
+fn build_disjunct(body_term: Term) -> (JumpStub, VecDeque<Term>) {
+    let vars = compute_head(&body_term);
+    let results = unfold_by_str(body_term, atom!(";"))
+        .into_iter()
+        .map(|term| {
+            let mut subterms = unfold_by_str(term, atom!(","));
+            mark_cut_variables(&mut subterms);
 
-        (vars, VecDeque::from(vec![rule]))
-    }
+            check_for_internal_if_then(&mut subterms);
 
-    fn fabricate_disjunct(&self, body_term: Term) -> (JumpStub, VecDeque<Term>) {
-        let vars = self.compute_head(&body_term);
-        let results = unfold_by_str(body_term, atom!(";"))
-            .into_iter()
-            .map(|term| {
-                let mut subterms = unfold_by_str(term, atom!(","));
-                mark_cut_variables(&mut subterms);
+            let term = subterms.pop().unwrap();
+            let clause = fold_by_str(subterms.into_iter(), term, atom!(","));
 
-                check_for_internal_if_then(&mut subterms);
+            build_rule_body(&vars, clause)
+        })
+        .collect();
 
-                let term = subterms.pop().unwrap();
-                let clause = fold_by_str(subterms.into_iter(), term, atom!(","));
+    (vars, results)
+}
 
-                self.fabricate_rule_body(&vars, clause)
-            })
-            .collect();
+fn build_if_then(prec: Term, conq: Term) -> (JumpStub, VecDeque<Term>) {
+    let mut prec_seq = unfold_by_str(prec, atom!(","));
+    let comma_sym = atom!(",");
+    let cut_sym = Literal::Atom(atom!("!"));
 
-        (vars, results)
-    }
+    prec_seq.push(Term::Literal(Cell::default(), cut_sym));
 
-    fn fabricate_if_then(&self, prec: Term, conq: Term) -> (JumpStub, VecDeque<Term>) {
-        let mut prec_seq = unfold_by_str(prec, atom!(","));
-        let comma_sym = atom!(",");
-        let cut_sym = Literal::Atom(atom!("!"));
+    mark_cut_variables_as(&mut prec_seq, atom!("blocked_!"));
 
-        prec_seq.push(Term::Literal(Cell::default(), cut_sym));
+    let mut conq_seq = unfold_by_str(conq, atom!(","));
 
-        mark_cut_variables_as(&mut prec_seq, atom!("blocked_!"));
+    mark_cut_variables(&mut conq_seq);
+    prec_seq.extend(conq_seq.into_iter());
 
-        let mut conq_seq = unfold_by_str(conq, atom!(","));
+    let back_term = prec_seq.pop().unwrap();
+    let front_term = prec_seq.pop().unwrap();
 
-        mark_cut_variables(&mut conq_seq);
-        prec_seq.extend(conq_seq.into_iter());
+    let body_term = Term::Clause(
+        Cell::default(),
+        comma_sym,
+        vec![front_term, back_term],
+    );
 
-        let back_term = prec_seq.pop().unwrap();
-        let front_term = prec_seq.pop().unwrap();
+    build_rule(fold_by_str(prec_seq.into_iter(), body_term, comma_sym))
+}
 
-        let body_term = Term::Clause(
-            Cell::default(),
-            comma_sym,
-            vec![front_term, back_term],
-        );
+#[derive(Debug)]
+pub(crate) struct Preprocessor {
+    queue: VecDeque<VecDeque<Term>>,
+    settings: CodeGenSettings,
+}
 
-        self.fabricate_rule(fold_by_str(prec_seq.into_iter(), body_term, comma_sym))
+impl Preprocessor {
+    pub(super) fn new(settings: CodeGenSettings) -> Self {
+        Preprocessor {
+            queue: VecDeque::new(),
+            settings,
+        }
+    }
+
+    fn setup_fact(&mut self, term: Term) -> Result<Term, CompilationError> {
+        match term {
+            Term::Clause(..) | Term::Literal(_, Literal::Atom(..)) => Ok(term),
+            _ => Err(CompilationError::InadmissibleFact),
+        }
     }
 
     fn to_query_term<'a, LS: LoadState<'a>>(
@@ -605,7 +751,9 @@ impl Preprocessor {
                     Ok(QueryTerm::BlockedCut)
                 } else {
                     Ok(clause_to_query_term(
-                        loader, name, vec![],
+                        loader,
+                        name,
+                        vec![],
                         self.settings.default_call_policy(),
                     ))
                 }
@@ -618,7 +766,7 @@ impl Preprocessor {
                 (atom!(";"), 2) => {
                     let term = Term::Clause(r, name, terms);
 
-                    let (stub, clauses) = self.fabricate_disjunct(term);
+                    let (stub, clauses) = build_disjunct(term);
                     self.queue.push_back(clauses);
 
                     Ok(QueryTerm::Jump(stub))
@@ -627,7 +775,7 @@ impl Preprocessor {
                     let conq = terms.pop().unwrap();
                     let prec = terms.pop().unwrap();
 
-                    let (stub, clauses) = self.fabricate_if_then(prec, conq);
+                    let (stub, clauses) = build_if_then(prec, conq);
                     self.queue.push_back(clauses);
 
                     Ok(QueryTerm::Jump(stub))
@@ -644,7 +792,7 @@ impl Preprocessor {
                     let terms = vec![prec, conq];
 
                     let term = Term::Clause(Cell::default(), atom!(";"), terms);
-                    let (stub, clauses) = self.fabricate_disjunct(term);
+                    let (stub, clauses) = build_disjunct(term);
 
                     debug_assert!(clauses.len() > 0);
                     self.queue.push_back(clauses);
@@ -689,8 +837,8 @@ impl Preprocessor {
 
                             Ok(clause_to_query_term(
                                 loader,
-                                name,
-                                terms,
+                                atom!("call"),
+                                vec![Term::Clause(r, name, terms)],
                                 self.settings.default_call_policy(),
                             ))
                         }
index 7383908770c74d11557ccbe32760de8fd48a28b3..548cf6ac377cc4ed83eb2e604266f0e27c96e952 100644 (file)
@@ -1254,6 +1254,18 @@ impl MachineState {
                     None
                 }
             }
+            (HeapCellValueTag::Str, s) => {
+                let (name, arity) = cell_as_atom_cell!(self.heap[s])
+                    .get_name_and_arity();
+
+                debug_assert_eq!(arity, 0);
+
+                if name != atom!("[]") {
+                    Some(name)
+                } else {
+                    None
+                }
+            }
             _ => {
                 None
             }
@@ -1270,6 +1282,19 @@ impl MachineState {
                     _ => unreachable!(),
                 }
             }
+            (HeapCellValueTag::Str, s) => {
+                let (name, arity) = cell_as_atom_cell!(self.heap[s])
+                    .get_name_and_arity();
+
+                debug_assert_eq!(arity, 0);
+
+                match name  {
+                    atom!("eof_code") => EOFAction::EOFCode,
+                    atom!("error") => EOFAction::Error,
+                    atom!("reset") => EOFAction::Reset,
+                    _ => unreachable!(),
+                }
+            }
             _ => {
                 unreachable!()
             }
@@ -1280,6 +1305,13 @@ impl MachineState {
                 debug_assert_eq!(arity, 0);
                 name == atom!("true")
             }
+            (HeapCellValueTag::Str, s) => {
+                let (name, arity) = cell_as_atom_cell!(self.heap[s])
+                    .get_name_and_arity();
+
+                debug_assert_eq!(arity, 0);
+                name == atom!("true")
+            }
             _ => {
                 unreachable!()
             }
@@ -1294,6 +1326,17 @@ impl MachineState {
                     _ => unreachable!(),
                 }
             }
+            (HeapCellValueTag::Str, s) => {
+                let (name, arity) = cell_as_atom_cell!(self.heap[s])
+                    .get_name_and_arity();
+
+                debug_assert_eq!(arity, 0);
+                match name {
+                    atom!("text") => StreamType::Text,
+                    atom!("binary") => StreamType::Binary,
+                    _ => unreachable!(),
+                }
+            }
             _ => {
                 unreachable!()
             }
@@ -1334,6 +1377,24 @@ impl MachineState {
                     }
                 };
             }
+            (HeapCellValueTag::Str, s) => {
+                let (name, arity) = cell_as_atom_cell!(self.heap[s])
+                    .get_name_and_arity();
+
+                debug_assert_eq!(arity, 0);
+
+                return match stream_aliases.get(&name) {
+                    Some(stream) if !stream.is_null_stream() => Ok(*stream),
+                    _ => {
+                        let stub = functor_stub(caller, arity);
+                        let addr = atom_as_cell!(name);
+
+                        let existence_error = self.existence_error(ExistenceError::Stream(addr));
+
+                        Err(self.error_form(existence_error, stub))
+                    }
+                };
+            }
             (HeapCellValueTag::Cons, ptr) => {
                 match_untyped_arena_ptr!(ptr,
                      (ArenaHeaderTag::Stream, stream) => {
@@ -1402,9 +1463,9 @@ impl MachineState {
         arity: usize,
     ) -> MachineStub {
         let stub = functor_stub(caller, arity);
-        let err = self.permission_error(perm, err_atom, stream_as_cell!(stream));
+        let err  = self.permission_error(perm, err_atom, stream_as_cell!(stream));
 
-        return self.error_form(err, stub);
+        self.error_form(err, stub)
     }
 
     #[inline]
@@ -1430,9 +1491,9 @@ impl MachineState {
         stub_arity: usize,
     ) -> MachineStub {
         let stub = functor_stub(stub_name, stub_arity);
-        let err = self.permission_error(Permission::Open, atom!("source_sink"), culprit);
+        let err  = self.permission_error(Permission::Open, atom!("source_sink"), culprit);
 
-        return self.error_form(err, stub);
+        self.error_form(err, stub)
     }
 
     pub(crate) fn occupied_alias_permission_error(
@@ -1442,24 +1503,22 @@ impl MachineState {
         stub_arity: usize,
     ) -> MachineStub {
         let stub = functor_stub(stub_name, stub_arity);
-        let alias_name = atom!("alias");
 
         let err = self.permission_error(
             Permission::Open,
             atom!("source_sink"),
-            functor!(alias_name, [atom(alias)]),
+            functor!(atom!("alias"), [atom(alias)]),
         );
 
-        return self.error_form(err, stub);
+        self.error_form(err, stub)
     }
 
     pub(crate) fn reposition_error(&mut self, stub_name: Atom, stub_arity: usize) -> MachineStub {
         let stub = functor_stub(stub_name, stub_arity);
-
         let rep_stub = functor!(atom!("reposition"), [atom(atom!("true"))]);
         let err = self.permission_error(Permission::Open, atom!("source_sink"), rep_stub);
 
-        return self.error_form(err, stub);
+        self.error_form(err, stub)
     }
 
     pub(crate) fn check_stream_properties(
index 7e3f5568cd11152d218fe8b1b4b04cff9cfcff43..a7b4ad0ba8838abcf90b630e34a84d8595ec97a9 100644 (file)
@@ -10,7 +10,7 @@ use crate::heap_iter::*;
 use crate::heap_print::*;
 use crate::instructions::*;
 use crate::machine;
-use crate::machine::{Machine, VERIFY_ATTR_INTERRUPT_LOC};
+use crate::machine::{Machine, VERIFY_ATTR_INTERRUPT_LOC, get_structure_index};
 use crate::machine::code_walker::*;
 use crate::machine::copier::*;
 use crate::machine::heap::*;
@@ -29,22 +29,27 @@ use crate::types::*;
 
 use ordered_float::OrderedFloat;
 
+use fxhash::{FxBuildHasher, FxHasher};
 use indexmap::IndexSet;
 
 use ref_thread_local::{RefThreadLocal, ref_thread_local};
 
+use std::cell::Cell;
+use std::cmp::Ordering;
 use std::collections::BTreeSet;
 use std::convert::TryFrom;
 use std::env;
 use std::fs;
+use std::hash::{BuildHasher, BuildHasherDefault};
 use std::io::{ErrorKind, Read, Write};
 use std::iter::{once, FromIterator};
 use std::mem;
 use std::net::{TcpListener, TcpStream};
 use std::num::NonZeroU32;
 use std::ops::Sub;
-use std::str::FromStr;
 use std::process;
+use std::rc::Rc;
+use std::str::FromStr;
 
 use chrono::{offset::Local, DateTime};
 use cpu_time::ProcessTime;
@@ -173,6 +178,16 @@ impl BrentAlgState {
                     CycleSearchResult::NotList(self.num_steps(), heap[self.hare])
                 };
             }
+            (HeapCellValueTag::Str, s) => {
+                let (name, arity) = cell_as_atom_cell!(heap[s])
+                    .get_name_and_arity();
+
+                return if name == atom!("[]") && arity == 0 {
+                    CycleSearchResult::ProperList(self.num_steps())
+                } else {
+                    CycleSearchResult::NotList(self.num_steps(), heap[self.hare])
+                };
+            }
             (HeapCellValueTag::Lis, l) => {
                 return CycleSearchResult::UntouchedList(self.num_steps(), l);
             }
@@ -439,6 +454,30 @@ impl BrentAlgState {
 }
 
 impl MachineState {
+    #[inline]
+    pub(crate) fn variable_set<S: BuildHasher>(
+        &mut self,
+        seen_set: &mut IndexSet<HeapCellValue, S>,
+        value: HeapCellValue,
+    ) {
+        let mut iter = stackful_preorder_iter(&mut self.heap, value);
+
+        while let Some(value) = iter.next() {
+            let value = unmark_cell_bits!(value);
+
+            if value.is_var() {
+                let value = unmark_cell_bits!(heap_bound_store(
+                    iter.heap,
+                    heap_bound_deref(iter.heap, value)
+                ));
+
+                if value.is_var() {
+                    seen_set.insert(value);
+                }
+            }
+        }
+    }
+
     fn skip_max_list_cycle(&mut self, lam: usize) {
         fn step(heap: &[HeapCellValue], mut value: HeapCellValue) -> usize {
             loop {
@@ -820,6 +859,16 @@ impl MachineState {
                     None
                 }
             }
+            (HeapCellValueTag::Str, s) => {
+                let (name, arity) = cell_as_atom_cell!(self.heap[s])
+                    .get_name_and_arity();
+
+                if arity == 0 {
+                    Some(AtomOrString::Atom(name))
+                } else {
+                    None
+                }
+            }
             (HeapCellValueTag::Char, c) => {
                 Some(AtomOrString::String(c.to_string()))
             }
@@ -924,6 +973,289 @@ impl MachineState {
 }
 
 impl Machine {
+    #[inline(always)]
+    pub(crate) fn call_inline(
+        &mut self,
+        arity: usize,
+        call_at_index: impl Fn(&mut Machine, Atom, usize, IndexPtr) -> CallResult,
+    ) -> CallResult {
+        let arity = arity - 1;
+        let goal = self.machine_st.store(self.machine_st.deref(self.machine_st.registers[1]));
+
+        let load_registers = |machine_st: &mut MachineState, goal: HeapCellValue| -> Option<PredicateKey> {
+            read_heap_cell!(goal,
+                (HeapCellValueTag::Str, s) => {
+                    let (name, goal_arity) = cell_as_atom_cell!(machine_st.heap[s])
+                        .get_name_and_arity();
+
+                    if goal_arity > 0 {
+                        for idx in (1 .. arity + 1).rev() {
+                            machine_st.registers[idx + goal_arity] = machine_st.registers[idx + 1];
+                        }
+                    } else {
+                        for idx in 1 .. arity + 1 {
+                            machine_st.registers[idx] = machine_st.registers[idx + 1];
+                        }
+                    }
+
+                    for idx in 1 .. goal_arity + 1 {
+                        machine_st.registers[idx] = machine_st.heap[s+idx];
+                    }
+
+                    Some((name, goal_arity))
+                }
+                _ => {
+                    unreachable!()
+                }
+            )
+        };
+
+        read_heap_cell!(goal,
+            (HeapCellValueTag::Str, s) => {
+                let goal_arity = cell_as_atom_cell!(self.machine_st.heap[s]).get_arity();
+
+                if self.machine_st.heap.len() > s + goal_arity + 1 {
+                    let index_cell = self.machine_st.heap[s+goal_arity+1];
+
+                    if let Some(code_index) = get_structure_index(index_cell) {
+                        if code_index.is_undefined() || code_index.is_dynamic_undefined() {
+                            self.machine_st.fail = true;
+                            return Ok(());
+                        }
+
+                        match load_registers(&mut self.machine_st, goal) {
+                            Some((name, goal_arity)) => {
+                                let arity = goal_arity + arity;
+                                self.machine_st.neck_cut();
+                                return call_at_index(self, name, arity, code_index.get());
+                            }
+                            None => {
+                            }
+                        }
+                    }
+                }
+            }
+            _ => {
+            }
+        );
+
+        self.machine_st.fail = true;
+        Ok(())
+    }
+
+    #[inline(always)]
+    pub(crate) fn compile_inline_or_expanded_goal(&mut self) -> CallResult {
+        let goal = self.machine_st.store(self.machine_st.deref(self.machine_st.registers[1]));
+        let module_name = self.machine_st.store(self.machine_st.deref(self.machine_st.registers[4]));
+
+        // supp_vars are the supplementary variables generated by
+        // complete_partial_goal prior to goal_expansion.
+        let mut supp_vars = IndexSet::with_hasher(FxBuildHasher::default());
+
+        self.machine_st.variable_set(&mut supp_vars, self.machine_st.registers[2]);
+
+        struct GoalAnalysisResult {
+            is_simple_goal: bool,
+            goal: HeapCellValue,
+            key: PredicateKey,
+            expanded_vars: IndexSet<HeapCellValue, BuildHasherDefault<FxHasher>>,
+            supp_vars: IndexSet<HeapCellValue, BuildHasherDefault<FxHasher>>,
+        }
+
+        let result = read_heap_cell!(goal,
+            (HeapCellValueTag::Str, s) => {
+                let (name, arity) = cell_as_atom_cell!(self.machine_st.heap[s])
+                    .get_name_and_arity();
+
+                let mut expanded_vars = IndexSet::with_hasher(FxBuildHasher::default());
+
+                // fill expanded_vars with variables of the partial
+                // goal pre-completion by complete_partial_goal.
+                for idx in s + 1 .. s + arity - supp_vars.len() + 1 {
+                    self.machine_st.variable_set(&mut expanded_vars, self.machine_st.heap[idx]);
+                }
+
+                let is_simple_goal = if arity >= supp_vars.len() {
+                    // post_supp_args are the arguments to the
+                    // post-expansion complete goal gathered from the
+                    // final supp_vars.len() arguments. they must
+                    // agree in supp_vars in order of entry of
+                    // insertion as well as the previous
+                    // supp_vars.len() argument's variables being
+                    // disjoint from them. if they are not, the
+                    // expanded goal are not simple.
+
+                    let post_supp_args = self.machine_st.heap[s+arity-supp_vars.len()+1 .. s+arity+1]
+                        .iter()
+                        .cloned();
+
+                    post_supp_args
+                        .zip(supp_vars.iter())
+                        .all(|(arg_term, supp_var)| {
+                            let arg_term = self.machine_st.store(self.machine_st.deref(arg_term));
+
+                            if arg_term.is_var() && supp_var.is_var() {
+                                return arg_term == *supp_var;
+                            }
+
+                            false
+                        }) && expanded_vars.intersection(&supp_vars).next().is_none()
+                } else {
+                    false
+                };
+
+                let goal = if is_simple_goal {
+                    let h = self.machine_st.heap.len();
+                    let arity = arity - supp_vars.len();
+
+                    for idx in 0 .. arity + 1 {
+                        let value = self.machine_st.heap[s + idx];
+                        self.machine_st.heap.push(value);
+                    }
+
+                    self.machine_st.heap[h] = atom_as_cell!(name, arity);
+
+                    str_loc_as_cell!(h)
+                } else {
+                    goal
+                };
+
+                GoalAnalysisResult {
+                    is_simple_goal,
+                    goal,
+                    key: (name, arity),
+                    expanded_vars,
+                    supp_vars
+                }
+            }
+            (HeapCellValueTag::Atom, (name, arity)) => {
+                debug_assert_eq!(arity, 0);
+
+                let h = self.machine_st.heap.len();
+                self.machine_st.heap.push(goal);
+
+                GoalAnalysisResult {
+                    is_simple_goal: true,
+                    goal: str_loc_as_cell!(h),
+                    key: (name, 0),
+                    expanded_vars: IndexSet::with_hasher(FxBuildHasher::default()),
+                    supp_vars,
+                }
+            }
+            (HeapCellValueTag::Char, c) => {
+                let name = self.machine_st.atom_tbl.build_with(&c.to_string());
+
+                let h = self.machine_st.heap.len();
+                self.machine_st.heap.push(atom_as_cell!(name));
+
+                GoalAnalysisResult {
+                    is_simple_goal: true,
+                    goal: str_loc_as_cell!(h),
+                    key: (name, 0),
+                    expanded_vars: IndexSet::with_hasher(FxBuildHasher::default()),
+                    supp_vars,
+                }
+            }
+            _ => {
+                self.machine_st.fail = true;
+                return Ok(());
+            }
+        );
+
+        if result.key.0 == atom!(":") {
+            self.machine_st.fail = true;
+            return Ok(());
+        }
+
+        let expanded_term = if result.is_simple_goal {
+            let idx = self.get_or_insert_qualified_code_index(module_name, result.key);
+            self.machine_st.heap.push(untyped_arena_ptr_as_cell!(UntypedArenaPtr::from(idx)));
+            result.goal
+        } else {
+            // all supp_vars must appear later!
+            let vars = IndexSet::<HeapCellValue, BuildHasherDefault<FxHasher>>::from_iter(
+                result.expanded_vars.difference(&result.supp_vars).cloned()
+            );
+
+            let vars: Vec<_> = vars
+                .union(&result.supp_vars) // difference + union does not cancel.
+                .map(|v| Term::Var(Cell::default(), Rc::new(format!("_{}", v.get_value()))))
+                .collect();
+
+            let helper_clause_loc = self.code.len();
+
+            match self.compile_standalone_clause(temp_v!(1), &vars) {
+                Err(e) => {
+                    let err = self.machine_st.session_error(e);
+                    let stub = functor_stub(atom!("call"), result.key.1);
+
+                    return Err(self.machine_st.error_form(err, stub));
+                }
+                Ok(()) => {
+                    let h = self.machine_st.heap.len();
+
+                    self.machine_st.heap.push(atom_as_cell!(atom!("$aux"), 0));
+
+                    for value in result.expanded_vars.difference(&result.supp_vars).cloned() {
+                        self.machine_st.heap.push(value);
+                    }
+
+                    let anon_str_arity = self.machine_st.heap.len() - h - 1;
+
+                    self.machine_st.heap[h] = atom_as_cell!(atom!("$aux"), anon_str_arity);
+
+                    let idx = CodeIndex::new(
+                        IndexPtr::index(helper_clause_loc),
+                        &mut self.machine_st.arena,
+                    );
+
+                    self.machine_st.heap.push(untyped_arena_ptr_as_cell!(UntypedArenaPtr::from(idx)));
+
+                    str_loc_as_cell!(h)
+                }
+            }
+        };
+
+        let truncated_goal = self.machine_st.registers[3];
+        unify!(&mut self.machine_st, expanded_term, truncated_goal);
+
+        Ok(())
+    }
+
+    #[inline(always)]
+    pub(crate) fn is_expanded_or_inlined(&mut self) {
+        let (_module_loc, qualified_goal) = self.machine_st.strip_module(
+            self.machine_st.registers[1],
+            empty_list_as_cell!(),
+        );
+
+        if HeapCellValueTag::Str == qualified_goal.get_tag() {
+            let s = qualified_goal.get_value();
+            let (name, arity) = cell_as_atom_cell!(self.machine_st.heap[s])
+                .get_name_and_arity();
+
+            if name == atom!("$call") {
+                return;
+            }
+
+            if self.machine_st.heap.len() > s + 1 + arity {
+                let idx_cell = self.machine_st.heap[s + 1 + arity];
+
+                if HeapCellValueTag::Cons == idx_cell.get_tag() {
+                    match_untyped_arena_ptr!(cell_as_untyped_arena_ptr!(idx_cell),
+                        (ArenaHeaderTag::IndexPtr, _ip) => {
+                            return;
+                        }
+                        _ => {
+                        }
+                    );
+                }
+            }
+        }
+
+        self.machine_st.fail = true;
+    }
+
     #[inline(always)]
     pub(crate) fn prepare_call_clause(&mut self, arity: usize) -> CallResult {
         let (module_loc, qualified_goal) = self.machine_st.strip_module(
@@ -1391,6 +1723,19 @@ impl Machine {
 
                 unify!(self.machine_st, self.machine_st.registers[2], list_loc_as_cell!(h));
             }
+            (HeapCellValueTag::Str, s) => {
+                let (name, arity) = cell_as_atom_cell!(self.machine_st.heap[s])
+                    .get_name_and_arity();
+
+                if arity == 0 {
+                    self.machine_st.unify_complete_string(
+                        name,
+                        self.machine_st.store(self.machine_st.deref(self.machine_st.registers[2])),
+                    );
+                } else {
+                    self.machine_st.fail = true;
+                }
+            }
             (HeapCellValueTag::Atom, (name, arity)) => {
                 if arity == 0 {
                     self.machine_st.unify_complete_string(
@@ -1454,6 +1799,20 @@ impl Machine {
                     self.machine_st.fail = true;
                 }
             }
+            (HeapCellValueTag::Str, s) => {
+                let (name, arity) = cell_as_atom_cell!(self.machine_st.heap[s])
+                    .get_name_and_arity();
+
+                if arity == 0 {
+                    let iter = name.chars()
+                        .map(|c| fixnum_as_cell!(Fixnum::build_with(c as i64)));
+
+                    let h = iter_to_heap_list(&mut self.machine_st.heap, iter);
+                    unify!(self.machine_st, heap_loc_as_cell!(h), self.machine_st.registers[2]);
+                } else {
+                    self.machine_st.fail = true;
+                }
+            }
             (HeapCellValueTag::Var | HeapCellValueTag::AttrVar | HeapCellValueTag::StackVar) => {
                 let stub_gen = || functor_stub(atom!("atom_codes"), 2);
 
@@ -1482,6 +1841,17 @@ impl Machine {
         let a1 = self.machine_st.store(self.machine_st.deref(self.machine_st.registers[1]));
 
         let len: i64 = read_heap_cell!(a1,
+            (HeapCellValueTag::Str, s) => {
+                let (name, arity) = cell_as_atom_cell!(self.machine_st.heap[s])
+                    .get_name_and_arity();
+
+                if arity == 0 {
+                    name.chars().count() as i64
+                } else {
+                    self.machine_st.fail = true;
+                    return;
+                }
+            }
             (HeapCellValueTag::Atom, (name, arity)) => {
                 if arity == 0 {
                     name.chars().count() as i64
@@ -2019,6 +2389,13 @@ impl Machine {
             (HeapCellValueTag::Atom, (name, _arity)) => {
                 name.as_char().unwrap()
             }
+            (HeapCellValueTag::Str, s) => {
+                let (name, arity) = cell_as_atom_cell!(self.machine_st.heap[s])
+                    .get_name_and_arity();
+
+                debug_assert_eq!(arity, 0);
+                name.as_char().unwrap()
+            }
             (HeapCellValueTag::Char, c) => {
                 c
             }
@@ -2080,6 +2457,13 @@ impl Machine {
             (HeapCellValueTag::Atom, (name, _arity)) => {
                 name.as_char().unwrap()
             }
+            (HeapCellValueTag::Str, s) => {
+                let (name, arity) = cell_as_atom_cell!(self.machine_st.heap[s])
+                    .get_name_and_arity();
+
+                debug_assert_eq!(arity, 0);
+                name.as_char().unwrap()
+            }
             _ => {
                 unreachable!()
             }
@@ -2985,7 +3369,7 @@ impl Machine {
     }
 
     #[inline(always)]
-    pub(crate) fn delete_head_attribute(&mut self) {
+     pub(crate) fn delete_head_attribute(&mut self) {
         let addr = self.machine_st.store(self.machine_st.deref(self.machine_st.registers[1]));
 
         debug_assert_eq!(addr.get_tag(), HeapCellValueTag::AttrVar);
@@ -3016,18 +3400,48 @@ impl Machine {
         &mut self,
         narity: usize,
     ) -> Result<(Atom, PredicateKey), MachineStub> {
-        let module_name = cell_as_atom!(self.machine_st.store(self.machine_st.deref(
-            self.machine_st.registers[1 + narity]
-        )));
+        let module_name = self.machine_st.store(self.machine_st.deref(
+            self.machine_st.registers[1]
+        ));
+
+        let module_name = read_heap_cell!(module_name,
+            (HeapCellValueTag::Atom, (name, _arity)) => {
+                debug_assert_eq!(_arity, 0);
+                name
+            }
+            (HeapCellValueTag::Str, s) => {
+                let (module_name, _arity) = cell_as_atom_cell!(self.machine_st.heap[s])
+                    .get_name_and_arity();
+
+                debug_assert_eq!(_arity, 0);
+                module_name
+            }
+            _ if module_name.is_var() => {
+                atom!("user")
+            }
+            _ => {
+                unreachable!()
+            }
+        );
 
         let goal = self.machine_st.store(self.machine_st.deref(
-            self.machine_st.registers[2 + narity]
+            self.machine_st.registers[2]
         ));
 
         let (name, arity, s) = self.machine_st.setup_call_n_init_goal_info(goal, narity)?;
 
-        for i in (arity + 1..arity + narity + 1).rev() {
-            self.machine_st.registers[i] = self.machine_st.registers[i - arity];
+        match arity.cmp(&2) {
+            Ordering::Less => {
+                for i in arity + 1..arity + narity + 1 {
+                    self.machine_st.registers[i] = self.machine_st.registers[i + 2 - arity];
+                }
+            }
+            Ordering::Greater => {
+                for i in (arity + 1..arity + narity + 1).rev() {
+                    self.machine_st.registers[i] = self.machine_st.registers[i + 2 - arity];
+                }
+            }
+            Ordering::Equal => {}
         }
 
         for i in 1..arity + 1 {
@@ -3122,6 +3536,9 @@ impl Machine {
                     (HeapCellValueTag::Atom, (name, _arity)) => {
                         name
                     }
+                    (HeapCellValueTag::Str, s) => {
+                        cell_as_atom!(self.machine_st.heap[s])
+                    }
                     (HeapCellValueTag::Char, c) => {
                         self.machine_st.atom_tbl.build_with(&c.to_string())
                     }
@@ -3544,6 +3961,9 @@ impl Machine {
             (HeapCellValueTag::Atom, (name, _arity)) => {
                 name
             }
+            (HeapCellValueTag::Str, s) => {
+                cell_as_atom!(self.machine_st.heap[s])
+            }
             _ => {
                 unreachable!()
             }
@@ -3906,7 +4326,7 @@ impl Machine {
                 let (name, arity) = cell_as_atom_cell!(self.machine_st.heap[s])
                     .get_name_and_arity();
 
-                let ct = ClauseType::from(name, arity);
+                let ct = ClauseType::from(name, arity, &mut self.machine_st.arena);
 
                 if ct.is_inlined() || ct.is_builtin() {
                     true
@@ -3917,10 +4337,10 @@ impl Machine {
                         module_name,
                     )
                         .map(|index| index.get())
-                        .unwrap_or(IndexPtr::DynamicUndefined);
+                        .unwrap_or(IndexPtr::dynamic_undefined());
 
-                    match index {
-                        IndexPtr::DynamicUndefined | IndexPtr::Undefined => false,
+                    match index.tag() {
+                        IndexPtrTag::DynamicUndefined | IndexPtrTag::Undefined => false,
                         _ => true,
                     }
                 }
@@ -3928,7 +4348,7 @@ impl Machine {
             (HeapCellValueTag::Atom, (name, arity)) => {
                 debug_assert_eq!(arity, 0);
 
-                let ct = ClauseType::from(name, 0);
+                let ct = ClauseType::from(name, 0, &mut self.machine_st.arena);
 
                 if ct.is_inlined() || ct.is_builtin() {
                     true
@@ -3939,10 +4359,10 @@ impl Machine {
                         module_name,
                     )
                         .map(|index| index.get())
-                        .unwrap_or(IndexPtr::DynamicUndefined);
+                        .unwrap_or(IndexPtr::dynamic_undefined());
 
-                    match index {
-                        IndexPtr::DynamicUndefined => false,
+                    match index.tag() {
+                        IndexPtrTag::DynamicUndefined => false,
                         _ => true,
                     }
                 }
@@ -4208,7 +4628,9 @@ impl Machine {
             LOC_INIT.call_once(|| {
                 if let Some(builtins) = self.indices.modules.get(&atom!("builtins")) {
                     match builtins.code_dir.get(&(atom!("staggered_sc"), 2)).map(|cell| cell.get()) {
-                        Some(IndexPtr::Index(p)) => {
+                        Some(ip) if ip.tag() == IndexPtrTag::Index => {
+                            let p = ip.p() as usize;
+
                             match &self.code[p] {
                                 &Instruction::TryMeElse(o) => {
                                     SEMICOLON_SECOND_BRANCH_LOC = p + o;
@@ -4253,30 +4675,40 @@ impl Machine {
     pub(crate) fn next_ep(&mut self) {
         let first_arg = self.machine_st.store(self.machine_st.deref(self.machine_st.registers[1]));
 
-        read_heap_cell!(first_arg,
-            (HeapCellValueTag::Atom, (name, arity)) => {
-                debug_assert_eq!(name, atom!("first"));
-                debug_assert_eq!(arity, 0);
+        let next_ep_atom = |machine_st: &mut MachineState, name, arity| {
+            debug_assert_eq!(name, atom!("first"));
+            debug_assert_eq!(arity, 0);
 
-                if self.machine_st.e == 0 {
-                    self.machine_st.fail = true;
-                    return;
-                }
+            if machine_st.e == 0 {
+                machine_st.fail = true;
+                return;
+            }
 
-                let and_frame = self.machine_st.stack.index_and_frame(self.machine_st.e);
-                let cp = and_frame.prelude.cp - 1;
+            let and_frame = machine_st.stack.index_and_frame(machine_st.e);
+            let cp = and_frame.prelude.cp - 1;
 
-                let e = and_frame.prelude.e;
-                let e = Fixnum::build_with(i64::try_from(e).unwrap());
+            let e = and_frame.prelude.e;
+            let e = Fixnum::build_with(i64::try_from(e).unwrap());
 
-                let p = str_loc_as_cell!(self.machine_st.heap.len());
+            let p = str_loc_as_cell!(machine_st.heap.len());
 
-                self.machine_st.heap.extend(functor!(atom!("dir_entry"), [fixnum(cp)]));
-                self.machine_st.unify_fixnum(e, self.machine_st.registers[2]);
+            machine_st.heap.extend(functor!(atom!("dir_entry"), [fixnum(cp)]));
+            machine_st.unify_fixnum(e, machine_st.registers[2]);
 
-                if !self.machine_st.fail {
-                    unify!(self.machine_st, p, self.machine_st.registers[3]);
-                }
+            if !machine_st.fail {
+                unify!(machine_st, p, machine_st.registers[3]);
+            }
+        };
+
+        read_heap_cell!(first_arg,
+            (HeapCellValueTag::Atom, (name, arity)) => {
+                next_ep_atom(&mut self.machine_st, name, arity);
+            }
+            (HeapCellValueTag::Str, s) => {
+                let (name, arity) = cell_as_atom_cell!(self.machine_st.heap[s])
+                    .get_name_and_arity();
+
+                next_ep_atom(&mut self.machine_st, name, arity);
             }
             (HeapCellValueTag::Fixnum, n) => {
                 let e = n.get_num() as usize;
@@ -4346,6 +4778,13 @@ impl Machine {
                 debug_assert_eq!(arity, 0);
                 self.machine_st.fail = non_quoted_token(name.as_str().chars());
             }
+            (HeapCellValueTag::Str, s) => {
+                let (name, arity) = cell_as_atom_cell!(self.machine_st.heap[s])
+                    .get_name_and_arity();
+
+                debug_assert_eq!(arity, 0);
+                self.machine_st.fail = non_quoted_token(name.as_str().chars());
+            }
             _ => {
                 self.machine_st.fail = true;
             }
@@ -4480,6 +4919,13 @@ impl Machine {
                 debug_assert_eq!(arity, 0);
                 name
             }
+            (HeapCellValueTag::Str, s) => {
+                let (name, arity) = cell_as_atom_cell!(self.machine_st.heap[s])
+                    .get_name_and_arity();
+
+                debug_assert_eq!(arity, 0);
+                name
+            }
             _ => {
                 self.machine_st.atom_tbl.build_with(&match Number::try_from(port) {
                     Ok(Number::Fixnum(n)) => n.get_num().to_string(),
@@ -5011,26 +5457,9 @@ impl Machine {
             return;
         }
 
-        let mut seen_set = IndexSet::new();
-
-        {
-            let mut iter = stackful_preorder_iter(&mut self.machine_st.heap, stored_v);
+        let mut seen_set = IndexSet::with_hasher(FxBuildHasher::default());
 
-            while let Some(value) = iter.next() {
-                let value = unmark_cell_bits!(value);
-
-                if value.is_var() {
-                    let value = unmark_cell_bits!(heap_bound_store(
-                        iter.heap,
-                        heap_bound_deref(iter.heap, value)
-                    ));
-
-                    if value.is_var() {
-                        seen_set.insert(value);
-                    }
-                }
-            }
-        }
+        self.machine_st.variable_set(&mut seen_set, stored_v);
 
         let outcome = heap_loc_as_cell!(
             iter_to_heap_list(&mut self.machine_st.heap, seen_set.into_iter())
@@ -5271,9 +5700,15 @@ impl Machine {
         };
 
         let result = printer.print().result();
-        let chars = put_complete_string(&mut self.machine_st.heap, &result, &mut self.machine_st.atom_tbl);
+        let chars = put_complete_string(
+            &mut self.machine_st.heap,
+            &result,
+            &mut self.machine_st.atom_tbl,
+        );
 
-        let result_addr = self.machine_st.store(self.machine_st.deref(self.machine_st.registers[1]));
+        let result_addr = self.machine_st.store(self.machine_st.deref(
+            self.machine_st.registers[1]
+        ));
 
         if let Some(var) = result_addr.as_var() {
             self.machine_st.bind(var, chars);
index e341647bff7743eab981eb6e6672b1f3e1660d3b..8a000b8213b3c6d9576ba7017f151ed3e91ad6fa 100644 (file)
@@ -272,6 +272,12 @@ macro_rules! match_untyped_arena_ptr_pat_body {
         #[allow(unused_braces)]
         $code
     }};
+    ($ptr:ident, IndexPtr, $ip:ident, $code:expr) => {{
+        #[allow(unused_mut)]
+        let mut $ip = TypedArenaPtr::new(unsafe { std::mem::transmute::<_, *mut IndexPtr>($ptr.get_ptr()) });
+        #[allow(unused_braces)]
+        $code
+    }};
     ($ptr:ident, $($tags:tt)|+, $s:ident, $code:expr) => {{
         let $s = Stream::from_tag($ptr.get_tag(), $ptr.payload_offset());
         #[allow(unused_braces)]
@@ -292,6 +298,12 @@ macro_rules! match_untyped_arena_ptr_pat {
             | ArenaHeaderTag::StandardOutputStream
             | ArenaHeaderTag::StandardErrorStream
     };
+    (IndexPtr) => {
+        ArenaHeaderTag::IndexPtrUndefined |
+        ArenaHeaderTag::IndexPtrDynamicUndefined |
+        ArenaHeaderTag::IndexPtrDynamicIndex |
+        ArenaHeaderTag::IndexPtrIndex
+    };
     ($tag:ident) => {
         ArenaHeaderTag::$tag
     };
index 6c70df8ba2a3b08cf06fc86b0ccde4e379f92608..b1c0f5d9e51dc7ab9f5c480713b1cae0dd2b75f1 100644 (file)
@@ -1,5 +1,6 @@
 use crate::arena::*;
 use crate::atom_table::*;
+use crate::machine::machine_indices::*;
 use crate::parser::char_reader::*;
 use crate::types::HeapCellValueTag;
 
@@ -530,6 +531,7 @@ impl Neg for Fixnum {
 pub enum Literal {
     Atom(Atom),
     Char(char),
+    CodeIndex(CodeIndex),
     Fixnum(Fixnum),
     Integer(TypedArenaPtr<Integer>),
     Rational(TypedArenaPtr<Rational>),
@@ -551,6 +553,7 @@ impl fmt::Display for Literal {
                 write!(f, "{}", atom.flat_index())
             }
             Literal::Char(c) => write!(f, "'{}'", *c as u32),
+            Literal::CodeIndex(i) => write!(f, "{:x}", i.as_ptr() as u64),
             Literal::Fixnum(n) => write!(f, "{}", n.get_num()),
             Literal::Integer(ref n) => write!(f, "{}", n),
             Literal::Rational(ref n) => write!(f, "{}", n),
index 887a3562aea0f335b6fdf0626a76a4bf116b1a79..9aeacd82c5fce839b3ae4632b143e73cdda16601 100644 (file)
@@ -1,5 +1,6 @@
 use lexical::parse_lossy;
 
+use crate::arena::ArenaAllocated;
 use crate::atom_table::*;
 pub use crate::machine::machine_state::*;
 use crate::parser::ast::*;
index 3f8282c02a026be2232467947b785adc34be6de9..b4176c55826748ecbacbbd7915c20fe6ad4c2ca2 100644 (file)
@@ -336,7 +336,7 @@ impl<'a, 'b> TermWriter<'a, 'b> {
                     self.push_stub_addr();
                     self.push_stub_addr();
                 }
-                &TermRef::Clause(Level::Root, _, ref ct, subterms) => {
+                &TermRef::Clause(Level::Root, _, name, subterms) => {
                     if subterms.len() > MAX_ARITY {
                         return Err(CompilationError::ExceededMaxArity);
                     }
@@ -348,7 +348,7 @@ impl<'a, 'b> TermWriter<'a, 'b> {
                     });
 
                     self.queue.push_back((subterms.len(), h + 2));
-                    let named = atom_as_cell!(ct.name(), subterms.len());
+                    let named = atom_as_cell!(name, subterms.len());
 
                     self.heap.push(named);
 
@@ -358,9 +358,9 @@ impl<'a, 'b> TermWriter<'a, 'b> {
 
                     continue;
                 }
-                &TermRef::Clause(_, _, ref ct, subterms) => {
+                &TermRef::Clause(_, _, name, subterms) => {
                     self.queue.push_back((subterms.len(), h + 1));
-                    let named = atom_as_cell!(ct.name(), subterms.len());
+                    let named = atom_as_cell!(name, subterms.len());
 
                     self.heap.push(named);
 
index cbb469f9d26446890283c0fd9775e841988d9bd9..ef1d94a89372c2d09de1994b55cbca13db303c16 100644 (file)
@@ -36,6 +36,8 @@ pub(crate) trait CompilationTarget<'a> {
     fn subterm_to_value(r: RegType) -> Instruction;
 
     fn clause_arg_to_instr(r: RegType) -> Instruction;
+
+    fn trim_structure_by_last_arg(instr: &mut Instruction, last_arg: &Term);
 }
 
 impl<'a> CompilationTarget<'a> for FactInstruction {
@@ -106,6 +108,10 @@ impl<'a> CompilationTarget<'a> for FactInstruction {
     fn clause_arg_to_instr(val: RegType) -> Instruction {
         Instruction::UnifyVariable(val)
     }
+
+    fn trim_structure_by_last_arg(_instr: &mut Instruction, _last_arg: &Term) {
+        // a no-op for facts.
+    }
 }
 
 impl<'a> CompilationTarget<'a> for QueryInstruction {
@@ -176,4 +182,21 @@ impl<'a> CompilationTarget<'a> for QueryInstruction {
     fn clause_arg_to_instr(val: RegType) -> Instruction {
         Instruction::SetValue(val)
     }
+
+    // if the final argument of the structure is a Literal::Index,
+    // decrement the arity of the PutStructure instruction by 1.
+    fn trim_structure_by_last_arg(instr: &mut Instruction, last_arg: &Term) {
+        if let Instruction::PutStructure(_, ref mut arity, _) = instr {
+            if let Term::Literal(_, Literal::CodeIndex(_)) = last_arg {
+                // it is acceptable if arity == 0 is the result of
+                // this decrement. call/N will have to read the index
+                // constant for '$call_inline' to succeed. to find it,
+                // it must know the heap location of the index.
+                // self.store must stop before reading the atom into a
+                // register.
+
+                *arity -= 1;
+            }
+        }
+    }
 }
index 4b3e0b34c88ea080be3d8c958d89ebc51649e41e..8caea7ba87d8a1c5e1957097e97c364bcb917175 100644 (file)
@@ -172,7 +172,7 @@ instruction_match(Term, VarList) :-
     ;  Term = end_of_file ->
        halt
     ;
-    submit_query_and_print_results(Term, VarList)
+       submit_query_and_print_results(Term, VarList)
     ).
 
 
@@ -180,7 +180,7 @@ submit_query_and_print_results_(Term, VarList) :-
     '$get_b_value'(B),
     bb_put('$report_all', false),
     bb_put('$report_n_more', 0),
-    '$call'(Term),
+    call(user:Term),
     write_eqs_and_read_input(B, VarList),
     !.
 submit_query_and_print_results_(_, _) :-
@@ -192,12 +192,12 @@ submit_query_and_print_results_(_, _) :-
     nl.
 
 
-submit_query_and_print_results(Term0, VarList) :-
-    (  functor(Term0, call, _) ->
-       Term = Term0 % prevent pre-mature expansion of incomplete goal
-                    % in the first argument, which is done by call/N
-    ;  expand_goal(Term0, user, Term)
-    ),
+submit_query_and_print_results(Term, VarList) :-
+    (  functor(Term0, call, _) ->
+       Term = Term0 % prevent pre-mature expansion of incomplete goal
+                    % in the first argument, which is done by call/N
+    ;  expand_goal(Term0, user, Term)
+    ),
     bb_put('$answer_count', 0),
     submit_query_and_print_results_(Term, VarList).
 
@@ -301,6 +301,7 @@ write_eqs_and_read_input(B, VarList) :-
     append(Equations, AttrGoals, Goals),
     % one layer of depth added for (=/2) functor
     maplist(\Term^Vs^term_variables_under_max_depth(Term, 22, Vs), Equations, EquationVars),
+    % maplist(term_variables_under_max_depth(22), Equations, EquationVars),
     append([AttrGoalVars | EquationVars], Vars1),
     term_variables(Vars1, Vars2), % deduplicate vars of Vars1 but preserve their order.
     charsio:extend_var_list(Vars2, VarList, NewVarList0, fabricated),
index be940a54949e2d7a3c31dd9199ea12201b893c25..168f0e8466b6ad4c02886f3b5042b52d113f320d 100644 (file)
@@ -301,7 +301,7 @@ impl fmt::Debug for HeapCellValue {
     }
 }
 
-impl<T> From<TypedArenaPtr<T>> for HeapCellValue {
+impl<T: ArenaAllocated> From<TypedArenaPtr<T>> for HeapCellValue {
     #[inline]
     fn from(arena_ptr: TypedArenaPtr<T>) -> HeapCellValue {
         HeapCellValue::from(arena_ptr.header_ptr() as u64)
@@ -441,20 +441,22 @@ impl HeapCellValue {
     }
 
     #[inline]
-    pub fn is_compound(self) -> bool {
+    pub fn is_compound(self, heap: &[HeapCellValue]) -> bool {
         match self.get_tag() {
-           HeapCellValueTag::Str
-            | HeapCellValueTag::Lis
-            | HeapCellValueTag::CStr
-            | HeapCellValueTag::PStr
-            | HeapCellValueTag::PStrLoc
-            | HeapCellValueTag::PStrOffset => {
+            HeapCellValueTag::Str => {
+                cell_as_atom_cell!(heap[self.get_value()]).get_arity() > 0
+            }
+            HeapCellValueTag::Lis |
+            HeapCellValueTag::CStr |
+            HeapCellValueTag::PStr |
+            HeapCellValueTag::PStrLoc |
+            HeapCellValueTag::PStrOffset => {
                true
-           }
-           HeapCellValueTag::Atom => {
-               cell_as_atom_cell!(self).get_arity() > 0
-           }
-           _ => { false }
+            }
+            HeapCellValueTag::Atom => {
+                cell_as_atom_cell!(self).get_arity() > 0
+            }
+            _ => { false }
         }
     }
 
@@ -582,7 +584,7 @@ impl HeapCellValue {
         }
     }
 
-    pub fn order_category(self) -> Option<TermOrderCategory> {
+    pub fn order_category(self, heap: &[HeapCellValue]) -> Option<TermOrderCategory> {
         match Number::try_from(self).ok() {
             Some(Number::Integer(_)) | Some(Number::Fixnum(_)) | Some(Number::Rational(_)) => {
                 Some(TermOrderCategory::Integer)
@@ -601,9 +603,19 @@ impl HeapCellValue {
                     })
                 }
                 HeapCellValueTag::Lis | HeapCellValueTag::PStrLoc |
-                HeapCellValueTag::CStr | HeapCellValueTag::Str => {
+                HeapCellValueTag::CStr => {
                     Some(TermOrderCategory::Compound)
                 }
+                HeapCellValueTag::Str => {
+                    let value = heap[self.get_value()];
+                    let arity = cell_as_atom_cell!(value).get_arity();
+
+                    if arity == 0 {
+                        Some(TermOrderCategory::Atom)
+                    } else {
+                        Some(TermOrderCategory::Compound)
+                    }
+                }
                 _ => {
                     None
                 }
@@ -628,7 +640,7 @@ const_assert!(mem::size_of::<HeapCellValue>() == 8);
 
 #[bitfield]
 #[repr(u64)]
-#[derive(Copy, Clone, Debug)]
+#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
 pub struct UntypedArenaPtr {
     ptr: B61,
     m: bool,
@@ -644,6 +656,13 @@ impl From<*const ArenaHeader> for UntypedArenaPtr {
     }
 }
 
+impl From<*const IndexPtr> for UntypedArenaPtr {
+    #[inline]
+    fn from(ptr: *const IndexPtr) -> UntypedArenaPtr {
+        unsafe { mem::transmute(ptr) }
+    }
+}
+
 impl From<UntypedArenaPtr> for *const ArenaHeader {
     #[inline]
     fn from(ptr: UntypedArenaPtr) -> *const ArenaHeader {