]> Repositorios git - scryer-prolog.git/commitdiff
improve efficiency of call/N, replace '$call_with_default_policy' with
authorMark Thom <[email protected]>
Mon, 13 Jun 2022 04:17:44 +0000 (22:17 -0600)
committerMark Thom <[email protected]>
Mon, 13 Jun 2022 04:34:07 +0000 (22:34 -0600)
'$call_with_inference_counting'

12 files changed:
build/instructions_template.rs
src/codegen.rs
src/forms.rs
src/lib/builtins.pl
src/lib/iso_ext.pl
src/loader.pl
src/machine/compile.rs
src/machine/dispatch.rs
src/machine/loader.rs
src/machine/machine_state_impl.rs
src/machine/preprocessor.rs
src/machine/system_calls.rs

index 336cf395ca20c89cb3cfefa87637472d6fc0ec6d..ed891b4956926da3441f0a7cdd236b8a29e13fd2 100644 (file)
@@ -276,6 +276,8 @@ enum SystemClauseType {
     DeleteHeadAttribute,
     #[strum_discriminants(strum(props(Arity = "arity", Name = "$module_call")))]
     DynamicModuleResolution(usize),
+    #[strum_discriminants(strum(props(Arity = "arity", Name = "$prepare_call_clause")))]
+    PrepareCallClause(usize),
     #[strum_discriminants(strum(props(Arity = "1", Name = "$enqueue_attr_var")))]
     EnqueueAttributedVar,
     #[strum_discriminants(strum(props(Arity = "2", Name = "$fetch_global_var")))]
@@ -544,6 +546,8 @@ enum SystemClauseType {
     HttpOpen,
     #[strum_discriminants(strum(props(Arity = "3", Name = "$predicate_defined")))]
     PredicateDefined,
+    #[strum_discriminants(strum(props(Arity = "3", Name = "$strip_module")))]
+    StripModule,
     REPL(REPLCodePtr),
 }
 
@@ -1592,6 +1596,7 @@ fn generate_instruction_preface() -> TokenStream {
                     &Instruction::CallDeleteAttribute(_) |
                     &Instruction::CallDeleteHeadAttribute(_) |
                     &Instruction::CallDynamicModuleResolution(..) |
+                    &Instruction::CallPrepareCallClause(..) |
                     &Instruction::CallEnqueueAttributedVar(_) |
                     &Instruction::CallFetchGlobalVar(_) |
                     &Instruction::CallFirstStream(_) |
@@ -1668,6 +1673,7 @@ fn generate_instruction_preface() -> TokenStream {
                     &Instruction::CallDeterministicLengthRundown(_) |
                     &Instruction::CallHttpOpen(_) |
                     &Instruction::CallPredicateDefined(_) |
+                    &Instruction::CallStripModule(_) |
                     &Instruction::CallCurrentTime(_) |
                     &Instruction::CallQuotedToken(_) |
                     &Instruction::CallReadTermFromChars(_) |
@@ -1796,7 +1802,8 @@ fn generate_instruction_preface() -> TokenStream {
                     &Instruction::ExecuteFileTime(_) |
                     &Instruction::ExecuteDeleteAttribute(_) |
                     &Instruction::ExecuteDeleteHeadAttribute(_) |
-                    &Instruction::ExecuteDynamicModuleResolution(_, _) |
+                    &Instruction::ExecuteDynamicModuleResolution(..) |
+                    &Instruction::ExecutePrepareCallClause(..) |
                     &Instruction::ExecuteEnqueueAttributedVar(_) |
                     &Instruction::ExecuteFetchGlobalVar(_) |
                     &Instruction::ExecuteFirstStream(_) |
@@ -1873,6 +1880,7 @@ fn generate_instruction_preface() -> TokenStream {
                     &Instruction::ExecuteDeterministicLengthRundown(_) |
                     &Instruction::ExecuteHttpOpen(_) |
                     &Instruction::ExecutePredicateDefined(_) |
+                    &Instruction::ExecuteStripModule(_) |
                     &Instruction::ExecuteCurrentTime(_) |
                     &Instruction::ExecuteQuotedToken(_) |
                     &Instruction::ExecuteReadTermFromChars(_) |
index 5f9a68ce118467cd2976b899f0ae028473990f5f..832c4c898ef9697638bd1d35e0a9e1d4a30b44e8 100644 (file)
@@ -196,6 +196,16 @@ impl CodeGenSettings {
             Instruction::TrustMe(0)
         }
     }
+
+    pub(crate) fn default_call_policy(&self) -> CallPolicy {
+        // calls are inference counted by default if and only if
+        // backtracking is counted too.
+        if self.non_counted_bt {
+            CallPolicy::Default
+        } else {
+            CallPolicy::Counted
+        }
+    }
 }
 
 #[derive(Debug)]
@@ -459,10 +469,10 @@ impl<'b> CodeGenerator<'b> {
                 self.jmp_by_locs.push(code.len());
                 code.push(instr!("jmp_by_call", vars.len(), 0, pvs));
             }
-            &QueryTerm::Clause(_, ref ct, _, true) => {
+            &QueryTerm::Clause(_, ref ct, _, CallPolicy::Default) => {
                 code.push(call_clause_by_default!(ct.clone(), pvs));
             }
-            &QueryTerm::Clause(_, ref ct, _, false) => {
+            &QueryTerm::Clause(_, ref ct, _, CallPolicy::Counted) => {
                 code.push(call_clause!(ct.clone(), pvs));
             }
             _ => {}
@@ -748,7 +758,7 @@ impl<'b> CodeGenerator<'b> {
         terms: &Vec<Term>,
         code: &mut Code,
         term_loc: GenContext,
-        use_default_call_policy: bool,
+        call_policy: CallPolicy,
     ) -> Result<(), CompilationError> {
         macro_rules! compile_expr {
             ($self:expr, $terms:expr, $term_loc:expr, $code:expr) => ({
@@ -790,7 +800,7 @@ impl<'b> CodeGenerator<'b> {
 
         let at = at.unwrap_or(interm!(1));
 
-        Ok(if use_default_call_policy {
+        Ok(if let CallPolicy::Default = call_policy {
             code.push(instr!("is", default, temp_v!(1), at, 0));
         } else {
             code.push(instr!("is", temp_v!(1), at, 0));
@@ -852,8 +862,8 @@ impl<'b> CodeGenerator<'b> {
                         _,
                         ClauseType::BuiltIn(BuiltInClauseType::Is(..)),
                         ref terms,
-                        use_default_call_policy,
-                    ) => self.compile_is_call(terms, code, term_loc, use_default_call_policy)?,
+                        call_policy,
+                    ) => self.compile_is_call(terms, code, term_loc, call_policy)?,
                     &QueryTerm::Clause(_, ClauseType::Inlined(ref ct), ref terms, _) => {
                         self.compile_inlined(ct, terms, term_loc, code)?
                     }
index ee632b6d07ac4e63b8dbea13b7a74a2931847e4f..8433e1e6b3907a33523fb8c708a1a091c1079546 100644 (file)
@@ -73,10 +73,16 @@ impl Level {
     }
 }
 
+#[derive(Debug, Clone, Copy)]
+pub enum CallPolicy {
+    Default,
+    Counted,
+}
+
 #[derive(Debug, Clone)]
 pub enum QueryTerm {
-    // register, clause type, subterms, use default call policy.
-    Clause(Cell<RegType>, ClauseType, Vec<Term>, bool),
+    // register, clause type, subterms, clause call policy.
+    Clause(Cell<RegType>, ClauseType, Vec<Term>, CallPolicy),
     BlockedCut, // a cut which is 'blocked by letters', like the P term in P -> Q.
     UnblockedCut(Cell<VarReg>),
     GetLevelAndUnify(Cell<VarReg>, Rc<String>),
@@ -84,9 +90,9 @@ pub enum QueryTerm {
 }
 
 impl QueryTerm {
-    pub(crate) fn set_default_caller(&mut self) {
+    pub(crate) fn set_call_policy(&mut self, cp: CallPolicy) {
         match self {
-            &mut QueryTerm::Clause(_, _, _, ref mut use_default_cp) => *use_default_cp = true,
+            &mut QueryTerm::Clause(_, _, _, ref mut clause_cp) => *clause_cp = cp,
             _ => {}
         }
     }
index 3106a7b0982f48d97c1f3bebb1ea796d7e260f0c..59f214c934fffef4af1940d4553a5db155ab9361 100644 (file)
@@ -318,61 +318,62 @@ dispatch_prep(Gs, B, [Cont|Conts]) :-
 dispatch_call_list([]).
 dispatch_call_list([G1,G2,G3,G4,G5,G6,G7,G8|Gs]) :-
     !,
-    '$call'(G1),
-    '$call'(G2),
-    '$call'(G3),
-    '$call'(G4),
-    '$call'(G5),
-    '$call'(G6),
-    '$call'(G7),
-    '$call'(G8),
-    '$call_with_default_policy'(dispatch_call_list(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)),
+    dispatch_call_list(Gs).
 dispatch_call_list([G1,G2,G3,G4,G5,G6,G7]) :-
     !,
-    '$call'(G1),
-    '$call'(G2),
-    '$call'(G3),
-    '$call'(G4),
-    '$call'(G5),
-    '$call'(G6),
-    '$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'(G1),
-    '$call'(G2),
-    '$call'(G3),
-    '$call'(G4),
-    '$call'(G5),
-    '$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'(G1),
-    '$call'(G2),
-    '$call'(G3),
-    '$call'(G4),
-    '$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'(G1),
-    '$call'(G2),
-    '$call'(G3),
-    '$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'(G1),
-    '$call'(G2),
-    '$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'(G1),
-    '$call'(G2).
+    '$call_with_inference_counting'('$call'(G1)),
+    '$call_with_inference_counting'('$call'(G2)).
 dispatch_call_list([G1]) :-
-    '$call'(G1).
+    '$call_with_inference_counting'('$call'(G1)).
 
 
 % univ.
 
 :- non_counted_backtracking univ_errors/3.
+
 univ_errors(Term, List, N) :-
     '$skip_max_list'(N, _, List, R),
     (  var(R)        ->
@@ -404,9 +405,11 @@ univ_errors(Term, List, N) :-
     ;  true
     ).
 
+:- non_counted_backtracking (=..)/2.
+
 Term =.. List :-
-    '$call_with_default_policy'(univ_errors(Term, List, N)),
-    '$call_with_default_policy'(univ_worker(Term, List, N)).
+    univ_errors(Term, List, N),
+    univ_worker(Term, List, N).
 
 
 :- non_counted_backtracking univ_worker/3.
@@ -414,31 +417,31 @@ Term =.. List :-
 univ_worker(Term, List, _) :-
     atomic(Term),
     !,
-    '$call_with_default_policy'(List = [Term]).
+    List = [Term].
 univ_worker(Term, [Name|Args], N) :-
     var(Term),
     !,
-    '$call_with_default_policy'(Arity is N-1),
-    '$call_with_default_policy'(functor(Term, Name, Arity)), % Term = {var}, Name = nonvar, Arity = 0.
-    '$call_with_default_policy'(get_args(Args, Term, 1, Arity)).
+    Arity is N-1,
+    functor(Term, Name, Arity), % Term = {var}, Name = nonvar, Arity = 0.
+    get_args(Args, Term, 1, Arity).
 univ_worker(Term, List, _) :-
-    '$call_with_default_policy'(functor(Term, Name, Arity)),
-    '$call_with_default_policy'(get_args(Args, Term, 1, Arity)),
-    '$call_with_default_policy'(List = [Name|Args]).
+    functor(Term, Name, Arity),
+    get_args(Args, Term, 1, Arity),
+    List = [Name|Args].
 
 
 :- non_counted_backtracking get_args/4.
 
 get_args(Args, _, _, 0) :-
     !,
-    '$call_with_default_policy'(Args = []).
+    Args = [].
 get_args([Arg], Func, N, N) :-
     !,
-    '$call_with_default_policy'(arg(N, Func, Arg)).
+    arg(N, Func, Arg).
 get_args([Arg|Args], Func, I0, N) :-
-    '$call_with_default_policy'(arg(I0, Func, Arg)),
-    '$call_with_default_policy'(I1 is I0 + 1),
-    '$call_with_default_policy'(get_args(Args, Func, I1, N)).
+    arg(I0, Func, Arg),
+    I1 is I0 + 1,
+    get_args(Args, Func, I1, N).
 
 
 :- meta_predicate parse_options_list(?, 0, ?, ?, ?).
@@ -618,9 +621,11 @@ term_variables(Term, Vars) :-
 
 :- meta_predicate catch(0, ?, 0).
 
+:- non_counted_backtracking catch/3.
+
 catch(G,C,R) :-
     '$get_current_block'(Bb),
-    '$call_with_default_policy'(catch(G,C,R,Bb)).
+    catch(G,C,R,Bb).
 
 :- meta_predicate catch(0, ?, 0, ?).
 
@@ -628,12 +633,12 @@ catch(G,C,R) :-
 
 catch(G,C,R,Bb) :-
     '$install_new_block'(NBb),
-    '$call'(G),
-    '$call_with_default_policy'(end_block(Bb, NBb)).
+    '$call_with_inference_counting'('$call'(G)),
+    end_block(Bb, NBb).
 catch(G,C,R,Bb) :-
     '$reset_block'(Bb),
     '$get_ball'(Ball),
-    '$call_with_default_policy'(handle_ball(Ball, C, R)).
+    handle_ball(Ball, C, R).
 
 
 :- non_counted_backtracking end_block/2.
@@ -654,6 +659,8 @@ handle_ball(C, C, R) :-
 handle_ball(_, _, _) :-
     '$unwind_stack'.
 
+:- non_counted_backtracking throw/1.
+
 throw(Ball) :-
     (   var(Ball) ->
         '$set_ball'(error(instantiation_error,throw/1))
@@ -661,11 +668,10 @@ throw(Ball) :-
     ),
     '$unwind_stack'.
 
-
 :- non_counted_backtracking '$iterate_find_all'/4.
 
 '$iterate_find_all'(Template, Goal, _, LhOffset) :-
-    '$call'(Goal),
+    '$call_with_inference_counting'('$call'(Goal)),
     '$copy_to_lh'(LhOffset, Template),
     '$fail'.
 '$iterate_find_all'(_, _, Solutions, LhOffset) :-
@@ -678,19 +684,20 @@ truncate_lh_to(LhLength) :- '$truncate_lh_to'(LhLength).
 
 :- meta_predicate findall(?, 0, ?).
 
+:- non_counted_backtracking findall/3.
+
 findall(Template, Goal, Solutions) :-
-    '$call_with_default_policy'(error:can_be(list, Solutions)),
+    error:can_be(list, Solutions),
     '$lh_length'(LhLength),
-    '$call_with_default_policy'(
-        catch(builtins:'$iterate_find_all'(Template, Goal, Solutions, LhLength),
-              Error,
-              ( builtins:truncate_lh_to(LhLength), builtins:throw(Error) ))
-    ).
+    catch(builtins:'$iterate_find_all'(Template, Goal, Solutions, LhLength),
+          Error,
+          ( builtins:truncate_lh_to(LhLength), builtins:throw(Error) )
+         ).
 
 :- non_counted_backtracking '$iterate_find_all_diff'/5.
 
 '$iterate_find_all_diff'(Template, Goal, _, _, LhOffset) :-
-    '$call'(Goal),
+    '$call_with_inference_counting'('$call'(Goal)),
     '$copy_to_lh'(LhOffset, Template),
     '$fail'.
 '$iterate_find_all_diff'(_, _, Solutions0, Solutions1, LhOffset) :-
@@ -700,16 +707,19 @@ findall(Template, Goal, Solutions) :-
 
 :- meta_predicate findall(?, 0, ?, ?).
 
+:- non_counted_backtracking findall/4.
+
 findall(Template, Goal, Solutions0, Solutions1) :-
-    '$call_with_default_policy'(error:can_be(list, Solutions0)),
-    '$call_with_default_policy'(error:can_be(list, Solutions1)),
+    error:can_be(list, Solutions0),
+    error:can_be(list, Solutions1),
     '$lh_length'(LhLength),
-    '$call_with_default_policy'(
-        catch(builtins:'$iterate_find_all_diff'(Template, Goal, Solutions0,
-                                                Solutions1, LhLength),
-              Error,
-              ( builtins:truncate_lh_to(LhLength), builtins:throw(Error) ))
-    ).
+    catch(builtins:'$iterate_find_all_diff'(Template, Goal, Solutions0,
+                                            Solutions1, LhLength),
+          Error,
+          ( builtins:truncate_lh_to(LhLength), builtins:throw(Error) )
+         ).
+
+:- non_counted_backtracking set_difference/3.
 
 set_difference([X|Xs], [Y|Ys], Zs) :-
     X == Y, !, set_difference(Xs, [Y|Ys], Zs).
@@ -720,6 +730,8 @@ set_difference([X|Xs], [Y|Ys], Zs) :-
 set_difference([], _, []) :- !.
 set_difference(Xs, [], Xs).
 
+:- non_counted_backtracking group_by_variant/4.
+
 group_by_variant([V2-S2 | Pairs], V1-S1, [S2 | Solutions], Pairs0) :-
     V1 = V2, % \+ \+ (V1 = V2), % (2) % iso_ext:variant(V1, V2), % (1)
     !,
@@ -727,11 +739,15 @@ group_by_variant([V2-S2 | Pairs], V1-S1, [S2 | Solutions], Pairs0) :-
     group_by_variant(Pairs, V2-S2, Solutions, Pairs0).
 group_by_variant(Pairs, _, [], Pairs).
 
+:- non_counted_backtracking group_by_variants/2.
+
 group_by_variants([V-S|Pairs], [V-Solution|Solutions]) :-
     group_by_variant([V-S|Pairs], V-S, Solution, Pairs0),
     group_by_variants(Pairs0, Solutions).
 group_by_variants([], []).
 
+:- non_counted_backtracking iterate_variants/3.
+
 iterate_variants([V-Solution|GroupSolutions], V, Solution) :-
     (  GroupSolutions == [] -> !
     ;  true
@@ -739,6 +755,7 @@ iterate_variants([V-Solution|GroupSolutions], V, Solution) :-
 iterate_variants([_|GroupSolutions], Ws, Solution) :-
     iterate_variants(GroupSolutions, Ws, Solution).
 
+:- non_counted_backtracking rightmost_power/3.
 
 rightmost_power(Term, FinalTerm, Xs) :-
     (  Term = X ^ Y
@@ -752,6 +769,7 @@ rightmost_power(Term, FinalTerm, Xs) :-
     ;  Xs = [], FinalTerm = Term
     ).
 
+:- non_counted_backtracking findall_with_existential/5.
 
 findall_with_existential(Template, Goal, PairedSolutions, Witnesses0, Witnesses) :-
     (  nonvar(Goal),
@@ -771,6 +789,8 @@ findall_with_existential(Template, Goal, PairedSolutions, Witnesses0, Witnesses)
 
 :- meta_predicate bagof(?, 0, ?).
 
+:- non_counted_backtracking bagof/3.
+
 bagof(Template, Goal, Solution) :-
     error:can_be(list, Solution),
     term_variables(Template, TemplateVars0),
@@ -783,6 +803,8 @@ bagof(Template, Goal, Solution) :-
     group_by_variants(PairedSolutions, GroupedSolutions),
     iterate_variants(GroupedSolutions, Witnesses, Solution).
 
+:- non_counted_backtracking iterate_variants_and_sort/3.
+
 iterate_variants_and_sort([V-Solution0|GroupSolutions], V, Solution) :-
     sort(Solution0, Solution),
     (  GroupSolutions == [] -> !
@@ -794,6 +816,8 @@ iterate_variants_and_sort([_|GroupSolutions], Ws, Solution) :-
 
 :- meta_predicate setof(?, 0, ?).
 
+:- non_counted_backtracking setof/3.
+
 setof(Template, Goal, Solution) :-
     error:can_be(list, Solution),
     term_variables(Template, TemplateVars0),
@@ -808,6 +832,7 @@ setof(Template, Goal, Solution) :-
 
 % Clause retrieval and information.
 
+
 '$clause_body_is_valid'(B) :-
     (  var(B) -> true
     ;  functor(B, Name, _) ->
@@ -832,7 +857,6 @@ setof(Template, Goal, Solution) :-
     ;  throw(error(type_error(callable, H), clause/2))
     ).
 
-
 clause(H, B) :-
     (  var(H) ->
        throw(error(instantiation_error, clause/2))
@@ -853,11 +877,13 @@ clause(H, B) :-
     ;  throw(error(type_error(callable, H), clause/2))
     ).
 
+
 call_asserta(Head, Body, Name, Arity, Module) :-
     '$clause_body_is_valid'(Body),
     functor(_, Name, Arity),
     '$asserta'(Head, Body, Name, Arity, Module).
 
+
 module_asserta_clause(Head, Body, Module) :-
     (  var(Head) ->
        throw(error(instantiation_error, asserta/1))
@@ -871,6 +897,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))
@@ -895,6 +922,7 @@ asserta_clause(Head, Body) :-
     ;  throw(error(type_error(callable, Head), asserta/1))
     ).
 
+
 :- meta_predicate asserta(0).
 
 asserta(Clause0) :-
@@ -910,6 +938,7 @@ asserta(Clause0) :-
        module_asserta_clause(Head, Body, Module)
     ).
 
+
 module_assertz_clause(Head, Body, Module) :-
     (  var(Head) ->
        throw(error(instantiation_error, assertz/1))
@@ -930,6 +959,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))
@@ -954,6 +984,7 @@ assertz_clause(Head, Body) :-
     ;  throw(error(type_error(callable, Head), assertz/1))
     ).
 
+
 :- meta_predicate assertz(0).
 
 assertz(Clause0) :-
@@ -981,13 +1012,16 @@ module_retract_clauses([Clause|Clauses0], Head, Body, Name, Arity, Module) :-
     ;  true
     ).
 
+
 module_retract_clauses([_|Clauses0], Head, Body, Name, Arity, Module) :-
     module_retract_clauses(Clauses0, Head, Body, Name, Arity, Module).
 
+
 call_module_retract(Head, Body, Name, Arity, Module) :-
     findall((Head :- Body), Module:'$clause'(Head, Body), Clauses),
     module_retract_clauses(Clauses, Head, Body, Name, Arity, Module).
 
+
 retract_module_clause(Head, Body, Module) :-
     (  var(Head) ->
        throw(error(instantiation_error, retract/1))
@@ -1012,6 +1046,7 @@ first_match_index([_ | Clauses], Clause, N0, N) :-
     N1 is N0 + 1,
     first_match_index(Clauses, Clause, N1, N).
 
+
 retract_clauses([Clause | Clauses0], Head, Body, Name, Arity) :-
     functor(VarHead, Name, Arity),
     findall((VarHead :- VarBody), builtins:'$clause'(VarHead, VarBody), Clauses1),
@@ -1022,14 +1057,15 @@ retract_clauses([Clause | Clauses0], Head, Body, Name, Arity) :-
     (  Clauses0 == [] -> !
     ;  true
     ).
-
 retract_clauses([_ | Clauses0], Head, Body, Name, Arity) :-
     retract_clauses(Clauses0, Head, Body, Name, Arity).
 
+
 call_retract(Head, Body, Name, Arity) :-
     findall((Head :- Body), builtins:'$clause'(Head, Body), Clauses),
     retract_clauses(Clauses, Head, Body, Name, Arity).
 
+
 retract_clause(Head, Body) :-
     (  var(Head) ->
        throw(error(instantiation_error, retract/1))
@@ -1049,6 +1085,7 @@ retract_clause(Head, Body) :-
     ;  throw(error(type_error(callable, Head), retract/1))
     ).
 
+
 :- meta_predicate retract(0).
 
 retract(Clause0) :-
@@ -1137,12 +1174,14 @@ abolish(Pred) :-
     ;  throw(error(type_error(predicate_indicator, Pred), abolish/1))
     ).
 
+
 '$iterate_db_refs'(Name, Arity, Name/Arity). % :-
 %   '$lookup_db_ref'(Ref, Name, Arity).
 '$iterate_db_refs'(RName, RArity, Name/Arity) :-
     '$get_next_db_ref'(RName, RArity, RRName, RRArity),
     '$iterate_db_refs'(RRName, RRArity, Name/Arity).
 
+
 current_predicate(Pred) :-
     (  var(Pred) ->
        '$get_next_db_ref'(RN, RA, _, _),
@@ -1159,17 +1198,21 @@ current_predicate(Pred) :-
        '$iterate_db_refs'(RN, RA, Pred)
     ).
 
+
 '$iterate_op_db_refs'(RPriority, RSpec, ROp, _, RPriority, RSpec, ROp).
 '$iterate_op_db_refs'(RPriority, RSpec, ROp, OssifiedOpDir, Priority, Spec, Op) :-
     '$get_next_op_db_ref'(RPriority, RSpec, ROp, OssifiedOpDir, RRPriority, RRSpec, RROp),
     '$iterate_op_db_refs'(RRPriority, RRSpec, RROp, OssifiedOpDir, Priority, Spec, Op).
 
+
 can_be_op_priority(Priority) :- var(Priority).
 can_be_op_priority(Priority) :- op_priority(Priority).
 
+
 can_be_op_specifier(Spec) :- var(Spec).
 can_be_op_specifier(Spec) :- op_specifier(Spec).
 
+
 current_op(Priority, Spec, Op) :-
     (  can_be_op_priority(Priority),
        can_be_op_specifier(Spec),
@@ -1187,25 +1230,26 @@ list_of_op_atoms([Atom|Atoms]) :-
     ).
 list_of_op_atoms([]).
 
+
 op_priority(Priority) :-
     integer(Priority), !,
     (  ( Priority < 0 ; Priority > 1200 ) ->
        throw(error(domain_error(operator_priority, Priority), op/3)) % 8.14.3.3 h)
     ;  true
     ).
-
 op_priority(Priority) :-
     throw(error(type_error(integer, Priority), op/3)). % 8.14.3.3 d)
 
+
 op_specifier(OpSpec) :-
     atom(OpSpec),
     (  lists:member(OpSpec, [yfx, xfy, xfx, yf, fy, xf, fx]), !
     ;  throw(error(domain_error(operator_specifier, OpSpec), op/3)) % 8.14.3.3 i)
     ).
-
 op_specifier(OpSpec) :-
     throw(error(type_error(atom, OpSpec), op/3)).
 
+
 valid_op(Op) :-
     atom(Op),
     (  Op == (',') ->
@@ -1217,9 +1261,11 @@ valid_op(Op) :-
     ;  true
     ).
 
+
 op_(Priority, OpSpec, Op) :-
     '$op'(Priority, OpSpec, Op).
 
+
 op(Priority, OpSpec, Op) :-
     (  var(Priority) ->
        throw(error(instantiation_error, op/3)) % 8.14.3.3 a)
@@ -1242,7 +1288,6 @@ op(Priority, OpSpec, Op) :-
     ;  throw(error(type_error(list, Op), op/3)) % 8.14.3.3 f)
     ).
 
-
 halt :- halt(0).
 
 halt(N) :-
@@ -1255,6 +1300,7 @@ halt(N) :-
     ;   throw(error(domain_error(exit_code, N), halt/1))
     ).
 
+
 atom_length(Atom, Length) :-
     (  var(Atom)  ->
        throw(error(instantiation_error, atom_length/2)) % 8.16.1.3 a)
@@ -1271,6 +1317,7 @@ atom_length(Atom, Length) :-
     ;  throw(error(type_error(atom, Atom), atom_length/2)) % 8.16.1.3 b)
     ).
 
+
 atom_chars(Atom, List) :-
     '$skip_max_list'(_, _, List, Tail),
     (  ( Tail == [] ; var(Tail) ) ->
@@ -1311,6 +1358,7 @@ atom_codes(Atom, List) :-
     ;  throw(error(type_error(atom, Atom), atom_codes/2))
     ).
 
+
 atom_concat(Atom_1, Atom_2, Atom_12) :-
     error:can_be(atom, Atom_1),
     error:can_be(atom, Atom_2),
@@ -1336,6 +1384,7 @@ atom_concat(Atom_1, Atom_2, Atom_12) :-
        atom_chars(Atom_12, Atom_12_Chars)
     ).
 
+
 sub_atom(Atom, Before, Length, After, Sub_atom) :-
     error:must_be(atom, Atom),
     error:can_be(atom, Sub_atom),
@@ -1357,6 +1406,7 @@ sub_atom(Atom, Before, Length, After, Sub_atom) :-
        atom_chars(Sub_atom, LengthChars)
     ).
 
+
 char_code(Char, Code) :-
     (  var(Char) ->
        (  var(Code) ->
@@ -1391,6 +1441,7 @@ can_be_number(N, PI) :-
     ;  must_be_number(N, PI)
     ).
 
+
 must_be_number(N, _) :-
     (  integer(N)
     ;  float(N)
@@ -1402,6 +1453,7 @@ must_be_number(N, PI) :-
     ;  throw(error(instantiation_error, PI))
     ).
 
+
 chars_or_vars(Cs, _) :-
     (  var(Cs) ->
        !
@@ -1418,6 +1470,7 @@ chars_or_vars([C|Cs], PI) :-
     ;  chars_or_vars(Cs, PI)
     ).
 
+
 codes_or_vars(Cs, _) :-
     (  var(Cs) ->
        !
@@ -1435,6 +1488,7 @@ codes_or_vars([C|Cs], PI) :-
     ;  codes_or_vars(Cs, PI)
     ).
 
+
 number_chars(N, Chs) :-
     (  ground(Chs) ->
        can_be_number(N, number_chars/2),
@@ -1451,10 +1505,12 @@ number_chars(N, Chs) :-
        '$number_to_chars'(N, Chs)
     ).
 
+
 list_of_ints(Ns) :-
     error:must_be(list, Ns),
     lists:maplist(error:must_be(integer), Ns).
 
+
 number_codes(N, Chs) :-
    (  ground(Chs) ->
       can_be_number(N, number_codes/2),
@@ -1471,6 +1527,7 @@ number_codes(N, Chs) :-
       '$number_to_codes'(N, Chs)
    ).
 
+
 subsumes_term(General, Specific) :-
    \+ \+ (
       term_variables(Specific, SVs1),
@@ -1479,12 +1536,15 @@ subsumes_term(General, Specific) :-
       SVs1 == SVs2
    ).
 
+
 unify_with_occurs_check(X, Y) :- '$unify_with_occurs_check'(X, Y).
 
+
 current_input(S) :- '$current_input'(S).
 
 current_output(S) :- '$current_output'(S).
 
+
 set_input(S) :-
     (  var(S) ->
        throw(error(instantiation_error, set_input/1))
@@ -1536,6 +1596,7 @@ parse_stream_options_(E, _) :-
 open(SourceSink, Mode, Stream) :-
     open(SourceSink, Mode, Stream, []).
 
+
 open(SourceSink, Mode, Stream, StreamOptions) :-
     (  var(SourceSink) ->
        throw(error(instantiation_error, open/4)) % 8.11.5.3a)
@@ -1564,6 +1625,7 @@ parse_close_options(Options, OptionValues, Stub) :-
     DefaultOptions = [force-false],
     parse_options_list(Options, builtins:parse_close_options_, DefaultOptions, OptionValues, Stub).
 
+
 parse_close_options_(force(Force), force-Force) :-
     (  nonvar(Force), lists:member(Force, [true, false]), !
     ;
@@ -1581,6 +1643,7 @@ close(Stream) :-
     '$close'(Stream, []).
 
 
+
 flush_output(S) :-
     '$flush_output'(S).
 
index 1797c66817217bb2599ee8bc1d9e3ba6dc05fdd3..52dbd178e5dcd0ff79c021550fd22686b80c4923 100644 (file)
@@ -60,28 +60,31 @@ call_cleanup(G, C) :- setup_call_cleanup(true, G, C).
 
 :- meta_predicate(setup_call_cleanup(0, 0, 0)).
 
+:- non_counted_backtracking setup_call_cleanup/3.
+
 setup_call_cleanup(S, G, C) :-
     '$get_b_value'(B),
-    '$call'(S),
+    '$call_with_inference_counting'('$call'(S)),
     '$set_cp_by_default'(B),
     '$get_current_block'(Bb),
     (  C = _:CC,
-       '$call_with_default_policy'(var(CC)) ->
+       var(CC) ->
        instantiation_error(setup_call_cleanup/3)
-    ;  '$call_with_default_policy'(scc_helper(C, G, Bb))
+    ;  scc_helper(C, G, Bb)
     ).
 
 :- meta_predicate(scc_helper(?,0,?)).
 
 :- non_counted_backtracking scc_helper/3.
+
 scc_helper(C, G, Bb) :-
     '$get_cp'(Cp),
     '$install_scc_cleaner'(C, NBb),
-    '$call'(G),
+    '$call_with_inference_counting'('$call'(G)),
     ( '$check_cp'(Cp) ->
       '$reset_block'(Bb),
-      '$call_with_default_policy'(run_cleaners_without_handling(Cp))
-    ; '$call_with_default_policy'(true)
+      run_cleaners_without_handling(Cp)
+    ; true
     ; '$reset_block'(NBb),
       '$fail'
     ).
@@ -89,30 +92,32 @@ scc_helper(_, _, Bb) :-
     '$reset_block'(Bb),
     '$get_ball'(Ball),
     '$erase_ball',
-    '$call_with_default_policy'(run_cleaners_with_handling),
-    '$call_with_default_policy'(throw(Ball)).
+    run_cleaners_with_handling,
+    throw(Ball).
 scc_helper(_, _, _) :-
     '$get_cp'(Cp),
-    '$call_with_default_policy'(run_cleaners_without_handling(Cp)),
+    run_cleaners_without_handling(Cp),
     '$fail'.
 
 :- non_counted_backtracking run_cleaners_with_handling/0.
+
 run_cleaners_with_handling :-
     '$get_scc_cleaner'(C),
     '$get_level'(B),
-    '$call_with_default_policy'(catch(C, _, true)),
+    catch(C, _, true),
     '$set_cp_by_default'(B),
-    '$call_with_default_policy'(run_cleaners_with_handling).
+    run_cleaners_with_handling.
 run_cleaners_with_handling :-
     '$restore_cut_policy'.
 
 :- non_counted_backtracking run_cleaners_without_handling/1.
+
 run_cleaners_without_handling(Cp) :-
     '$get_scc_cleaner'(C),
     '$get_level'(B),
     '$call'(C),
     '$set_cp_by_default'(B),
-    '$call_with_default_policy'(run_cleaners_without_handling(Cp)).
+    run_cleaners_without_handling(Cp).
 run_cleaners_without_handling(Cp) :-
     '$set_cp_by_default'(Cp),
     '$restore_cut_policy'.
@@ -120,6 +125,7 @@ run_cleaners_without_handling(Cp) :-
 % call_with_inference_limit
 
 :- non_counted_backtracking end_block/4.
+
 end_block(_, Bb, NBb, _L) :-
     '$clean_up_block'(NBb),
     '$reset_block'(Bb).
@@ -129,13 +135,16 @@ end_block(B, _Bb, NBb, L) :-
     '$fail'.
 
 :- non_counted_backtracking handle_ile/3.
+
 handle_ile(B, inference_limit_exceeded(B), inference_limit_exceeded) :- !.
 handle_ile(B, E, _) :-
     '$remove_call_policy_check'(B),
-    '$call_with_default_policy'(throw(E)).
+    throw(E).
 
 :- meta_predicate(call_with_inference_limit(0, ?, ?)).
 
+:- non_counted_backtracking call_with_inference_limit/3.
+
 call_with_inference_limit(G, L, R) :-
     (  integer(L) ->
        (  L < 0 ->
@@ -148,7 +157,7 @@ call_with_inference_limit(G, L, R) :-
     ),
     '$get_current_block'(Bb),
     '$get_b_value'(B),
-    '$call_with_default_policy'(call_with_inference_limit(G, L, R, Bb, B)),
+    call_with_inference_limit(G, L, R, Bb, B),
     '$remove_call_policy_check'(B).
 
 install_inference_counter(B, L, Count0) :-
@@ -161,11 +170,11 @@ 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'(G),
+    '$call_with_inference_counting'('$call'(G)),
     '$inference_level'(R, B),
     '$remove_inference_counter'(B, Count1),
-    '$call_with_default_policy'(is(Diff, L - (Count1 - Count0))),
-    '$call_with_default_policy'(end_block(B, Bb, NBb, Diff)).
+    is(Diff, L - (Count1 - Count0)),
+    end_block(B, Bb, NBb, Diff).
 call_with_inference_limit(_, _, R, Bb, B) :-
     '$reset_block'(Bb),
     '$remove_inference_counter'(B, _),
@@ -176,7 +185,7 @@ call_with_inference_limit(_, _, R, Bb, B) :-
        '$fail'
     ),
     '$erase_ball',
-    '$call_with_default_policy'(handle_ile(B, Ball, R)).
+    handle_ile(B, Ball, R).
 
 partial_string(String, L, L0) :-
     (  String == [] ->
index 4738494a8b51da3949304d85d5c503262b36df17..acdd4885d90b2fb9be88e9fa858e50a9eb7cc517 100644 (file)
@@ -603,18 +603,10 @@ predicate_property(Callable, Property) :-
        )
     ).
 
-
-strip_module(M0, G0, M1, G1) :-
-    (  nonvar(G0),
-       G0 = (MG1:G2) ->
-       strip_module(MG1, G2, M1, G1)
-    ;  M0 = M1,
-       G0 = G1
-    ).
-
 strip_module(Goal, M, G) :-
-    strip_module(_, Goal, M, G).
+    '$strip_module'(Goal, M, G).
 
+:- non_counted_backtracking expand_subgoal/5.
 
 expand_subgoal(UnexpandedGoals, MS, Module, ExpandedGoals, HeadVars) :-
     (  var(UnexpandedGoals) ->
@@ -638,6 +630,8 @@ expand_subgoal(UnexpandedGoals, MS, Module, ExpandedGoals, HeadVars) :-
     ).
 
 
+:- non_counted_backtracking expand_module_name/4.
+
 expand_module_name(ESG0, MS, M, ESG) :-
     (  var(ESG0) ->
        ESG = M:ESG0
@@ -653,6 +647,8 @@ expand_module_name(ESG0, MS, M, ESG) :-
     ).
 
 
+:- non_counted_backtracking expand_meta_predicate_subgoals/5.
+
 expand_meta_predicate_subgoals([SG | SGs], [MS | MSs], M, [ESG | ESGs], HeadVars) :-
     (  (  integer(MS),
           MS >= 0
@@ -672,6 +668,8 @@ expand_meta_predicate_subgoals([SG | SGs], [MS | MSs], M, [ESG | ESGs], HeadVars
 expand_meta_predicate_subgoals([], _, _, [], _).
 
 
+:- non_counted_backtracking expand_module_names/5.
+
 expand_module_names(Goals, MetaSpecs, Module, ExpandedGoals, HeadVars) :-
     Goals =.. [GoalFunctor | SubGoals],
     (  GoalFunctor == (:),
@@ -683,6 +681,8 @@ 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, [])),
@@ -690,6 +690,8 @@ expand_goal(UnexpandedGoals, Module, ExpandedGoals) :-
           '$call'(UnexpandedGoals = ExpandedGoals)),
     !.
 
+:- non_counted_backtracking expand_goal_cases/4.
+
 expand_goal_cases((Goal0, Goals0), Module, ExpandedGoals, HeadVars) :-
     (  expand_goal(Goal0, Module, Goal1, HeadVars) ->
        expand_goal(Goals0, Module, Goals1, HeadVars),
@@ -712,6 +714,8 @@ expand_goal_cases((Module:Goals0), _, ExpandedGoals, HeadVars) :-
     expand_goal(Goals0, Module, Goals1, HeadVars),
     ExpandedGoals = (Module:Goals1).
 
+:- non_counted_backtracking expand_goal/4.
+
 expand_goal(UnexpandedGoals, Module, ExpandedGoals, HeadVars) :-
     (  var(UnexpandedGoals) ->
        expand_module_names(call(UnexpandedGoals), [0], Module, ExpandedGoals, HeadVars)
@@ -730,6 +734,8 @@ expand_goal(UnexpandedGoals, Module, ExpandedGoals, HeadVars) :-
        )
     ).
 
+:- non_counted_backtracking thread_goals/4.
+
 thread_goals(Goals0, Goals1, Hole, Functor) :-
     (  var(Goals0) ->
        Goals1 =.. [Functor, Goals0, Hole]
@@ -742,6 +748,8 @@ thread_goals(Goals0, Goals1, Hole, Functor) :-
     ;  Goals1 =.. [Functor, Goals0, Hole]
     ).
 
+:- non_counted_backtracking thread_goals/3.
+
 thread_goals(Goals0, Goals1, Functor) :-
     (  var(Goals0) ->
        Goals0 = Goals1
@@ -761,6 +769,7 @@ thread_goals(Goals0, Goals1, Functor) :-
 % The program used to generate the call/N predicates:
 %
 %
+%
 % :- use_module(library(between)).
 % :- use_module(library(error)).
 % :- use_module(library(lists)).
@@ -770,615 +779,808 @@ thread_goals(Goals0, Goals1, Functor) :-
 %     length(Args, N),
 %     Head =.. [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)
-%                       ;   call_clause(G, Args, N1, G0) ->
-%                           '$call'(G0)
-%                       ;   type_error(callable, G, call/N1)
-%                       )).
+%                          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))
+%                       )
+%              ).
 %
 % generate_call_forms :-
 %     between(1, 64, N),
 %     n_call_clause(N, Clause),
+%     N1 is N+1,
+%     portray_clause((:- non_counted_backtracking call/N1)),
 %     portray_clause(Clause),
 %     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.
 
-call_clause('$call'(G), G0) :-
-    (  var(G),
-       instantiation_error(call/1)
-    ;  G = M:G1,
-       !,
-       callable(G1),
-       functor(G1, F, _),
-       atom(F),
-       atom(M),
-       F \== [],
-       G0 = M:G1
-    ;  !,
-       callable(G),
-       functor(G, F, _),
-       atom(F),
-       F \== [],
-       load_context(M),
-       G0 = M:G
-    ).
-
-call_clause(G, G0) :-
-    strip_module(G, M, G1),
-    callable(G1),
-    functor(G1, F, _),
-    atom(F),
-    F \== [],
-    (  var(M) ->
-       load_context(M)
-    ;  true
-    ),
-    expand_goal(call(M:G1), M, call(G0)).
-
-
+:- non_counted_backtracking call/1.
 call(G) :-
-    (  var(G) ->
-       instantiation_error(call/1)
-    ;  call_clause(G, G0) ->
-       '$call'(G0)
-    ;  type_error(callable, G, call/1)
-    ).
-
-
-call_clause('$call'(G1), Args, N, G0) :-
-    (  var(G1),
-       instantiation_error(call/N)
-    ;  G1 = M:G2,
-       !,
-       atom(M),
-       G2 =.. [F | As],
-       atom(F),
-       F \== [],
-       append(As, Args, As1),
-       G3 =.. [F | As1],
-       callable(G3),
-       G0 = M:G3
-    ;  !,
-       G1 =.. [F | As],
-       atom(F),
-       F \== [],
-       load_context(M),
-       append(As, Args, As1),
-       G2 =.. [F | As1],
-       callable(G2),
-       G0 = M:G2
-    ).
-
-call_clause(G, Args, _, G0) :-
-    strip_module(G, M, G1),
-    G1 =.. [F | As],
-    atom(F),
-    F \== [],
-    (  var(M) ->
-       load_context(M)
-    ;  true
-    ),
-    append(As, Args, As1),
-    G2 =.. [F | As1],
-    callable(G2),
-    expand_goal(call(M:G2), M, call(G0)).
-
-
+   (  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))
+   ).
+
+:-non_counted_backtracking call/2.
 call(A,B) :-
-    (  var(A) ->
-       instantiation_error(call/2)
-    ;  call_clause(A,[B],2,C) ->
-       '$call'(C)
-    ;  type_error(callable,A,call/2)
-    ).
-
+   (  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))
+   ).
+
+:-non_counted_backtracking call/3.
 call(A,B,C) :-
-    (  var(A) ->
-       instantiation_error(call/3)
-    ;  call_clause(A,[B,C],3,D) ->
-       '$call'(D)
-    ;  type_error(callable,A,call/3)
-    ).
-
+   (  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))
+   ).
+
+:-non_counted_backtracking call/4.
 call(A,B,C,D) :-
-    (  var(A) ->
-       instantiation_error(call/4)
-    ;  call_clause(A,[B,C,D],4,E) ->
-       '$call'(E)
-    ;  type_error(callable,A,call/4)
-    ).
-
+   (  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))
+   ).
+
+:-non_counted_backtracking call/5.
 call(A,B,C,D,E) :-
-    (  var(A) ->
-       instantiation_error(call/5)
-    ;  call_clause(A,[B,C,D,E],5,F) ->
-       '$call'(F)
-    ;  type_error(callable,A,call/5)
-    ).
-
+   (  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))
+   ).
+
+:-non_counted_backtracking call/6.
 call(A,B,C,D,E,F) :-
-    (  var(A) ->
-       instantiation_error(call/6)
-    ;  call_clause(A,[B,C,D,E,F],6,G) ->
-       '$call'(G)
-    ;  type_error(callable,A,call/6)
-    ).
-
+   (  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))
+   ).
+
+:-non_counted_backtracking call/7.
 call(A,B,C,D,E,F,G) :-
-    (  var(A) ->
-       instantiation_error(call/7)
-    ;  call_clause(A,[B,C,D,E,F,G],7,H) ->
-       '$call'(H)
-    ;  type_error(callable,A,call/7)
-    ).
-
+   (  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))
+   ).
+
+:-non_counted_backtracking call/8.
 call(A,B,C,D,E,F,G,H) :-
-    (  var(A) ->
-       instantiation_error(call/8)
-    ;  call_clause(A,[B,C,D,E,F,G,H],8,I) ->
-       '$call'(I)
-    ;  type_error(callable,A,call/8)
-    ).
-
+   (  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))
+   ).
+
+:-non_counted_backtracking call/9.
 call(A,B,C,D,E,F,G,H,I) :-
-    (  var(A) ->
-       instantiation_error(call/9)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I],9,J) ->
-       '$call'(J)
-    ;  type_error(callable,A,call/9)
-    ).
-
+   (  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))
+   ).
+
+:-non_counted_backtracking call/10.
 call(A,B,C,D,E,F,G,H,I,J) :-
-    (  var(A) ->
-       instantiation_error(call/10)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J],10,K) ->
-       '$call'(K)
-    ;  type_error(callable,A,call/10)
-    ).
-
+   (  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))
+   ).
+
+:-non_counted_backtracking call/11.
 call(A,B,C,D,E,F,G,H,I,J,K) :-
-    (  var(A) ->
-       instantiation_error(call/11)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K],11,L) ->
-       '$call'(L)
-    ;  type_error(callable,A,call/11)
-    ).
-
+   (  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))
+   ).
+
+:-non_counted_backtracking call/12.
 call(A,B,C,D,E,F,G,H,I,J,K,L) :-
-    (  var(A) ->
-       instantiation_error(call/12)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L],12,M) ->
-       '$call'(M)
-    ;  type_error(callable,A,call/12)
-    ).
-
+   (  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))
+   ).
+
+:-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)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M],13,N) ->
-       '$call'(N)
-    ;  type_error(callable,A,call/13)
-    ).
-
+   (  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))
+   ).
+
+:-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)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N],14,O) ->
-       '$call'(O)
-    ;  type_error(callable,A,call/14)
-    ).
-
+   (  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))
+   ).
+
+:-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)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O],15,P) ->
-       '$call'(P)
-    ;  type_error(callable,A,call/15)
-    ).
-
+   (  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))
+   ).
+
+:-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)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P],16,Q) ->
-       '$call'(Q)
-    ;  type_error(callable,A,call/16)
-    ).
-
+   (  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))
+   ).
+
+:-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)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q],17,R) ->
-       '$call'(R)
-    ;  type_error(callable,A,call/17)
-    ).
-
+   (  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))
+   ).
+
+:-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)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R],18,S) ->
-       '$call'(S)
-    ;  type_error(callable,A,call/18)
-    ).
-
+   (  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))
+   ).
+
+:-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)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S],19,T) ->
-       '$call'(T)
-    ;  type_error(callable,A,call/19)
-    ).
-
+   (  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))
+   ).
+
+:-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)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T],20,U) ->
-       '$call'(U)
-    ;  type_error(callable,A,call/20)
-    ).
-
+   (  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))
+   ).
+
+:-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)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U],21,V) ->
-       '$call'(V)
-    ;  type_error(callable,A,call/21)
-    ).
-
+   (  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))
+   ).
+
+:-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)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V],22,W) ->
-       '$call'(W)
-    ;  type_error(callable,A,call/22)
-    ).
-
+   (  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))
+   ).
+
+:-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)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W],23,X) ->
-       '$call'(X)
-    ;  type_error(callable,A,call/23)
-    ).
-
+   (  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))
+   ).
+
+:-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)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X],24,Y) ->
-       '$call'(Y)
-    ;  type_error(callable,A,call/24)
-    ).
-
+   (  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))
+   ).
+
+:-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)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y],25,Z) ->
-       '$call'(Z)
-    ;  type_error(callable,A,call/25)
-    ).
-
+   (  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))
+   ).
+
+:-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)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z],26,A1) ->
-       '$call'(A1)
-    ;  type_error(callable,A,call/26)
-    ).
-
+   (  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))
+   ).
+
+:-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)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1],27,B1) ->
-       '$call'(B1)
-    ;  type_error(callable,A,call/27)
-    ).
-
+   (  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))
+   ).
+
+:-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)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1],28,C1) ->
-       '$call'(C1)
-    ;  type_error(callable,A,call/28)
-    ).
-
+   (  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))
+   ).
+
+:-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)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1],29,D1) ->
-       '$call'(D1)
-    ;  type_error(callable,A,call/29)
-    ).
-
+   (  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))
+   ).
+
+:-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)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1],30,E1) ->
-       '$call'(E1)
-    ;  type_error(callable,A,call/30)
-    ).
-
+   (  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))
+   ).
+
+:-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)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1],31,F1) ->
-       '$call'(F1)
-    ;  type_error(callable,A,call/31)
-    ).
-
+   (  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))
+   ).
+
+:-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)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1],32,G1) ->
-       '$call'(G1)
-    ;  type_error(callable,A,call/32)
-    ).
-
+   (  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))
+   ).
+
+:-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)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1],33,H1) ->
-       '$call'(H1)
-    ;  type_error(callable,A,call/33)
-    ).
-
+   (  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))
+   ).
+
+:-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)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1],34,I1) ->
-       '$call'(I1)
-    ;  type_error(callable,A,call/34)
-    ).
-
+   (  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))
+   ).
+
+:-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)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1],35,J1) ->
-       '$call'(J1)
-    ;  type_error(callable,A,call/35)
-    ).
-
+   (  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))
+   ).
+
+:-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)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1],36,K1) ->
-       '$call'(K1)
-    ;  type_error(callable,A,call/36)
-    ).
-
+   (  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))
+   ).
+
+:-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)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1],37,L1) ->
-       '$call'(L1)
-    ;  type_error(callable,A,call/37)
-    ).
-
+   (  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))
+   ).
+
+:-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)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,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],38,M1) ->
-       '$call'(M1)
-    ;  type_error(callable,A,call/38)
-    ).
-
+   (  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))
+   ).
+
+:-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)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,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],39,N1) ->
-       '$call'(N1)
-    ;  type_error(callable,A,call/39)
-    ).
-
+   (  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))
+   ).
+
+:-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)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,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],40,O1) ->
-       '$call'(O1)
-    ;  type_error(callable,A,call/40)
-    ).
-
+   (  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))
+   ).
+
+:-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)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,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],41,P1) ->
-       '$call'(P1)
-    ;  type_error(callable,A,call/41)
-    ).
-
+   (  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))
+   ).
+
+:-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)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,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],42,Q1) ->
-       '$call'(Q1)
-    ;  type_error(callable,A,call/42)
-    ).
-
+   (  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))
+   ).
+
+:-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)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,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],43,R1) ->
-       '$call'(R1)
-    ;  type_error(callable,A,call/43)
-    ).
-
+   (  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))
+   ).
+
+:-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)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,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],44,S1) ->
-       '$call'(S1)
-    ;  type_error(callable,A,call/44)
-    ).
-
+   (  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))
+   ).
+
+:-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)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,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],45,T1) ->
-       '$call'(T1)
-    ;  type_error(callable,A,call/45)
-    ).
-
+   (  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))
+   ).
+
+:-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)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,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],46,U1) ->
-       '$call'(U1)
-    ;  type_error(callable,A,call/46)
-    ).
-
+   (  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))
+   ).
+
+:-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)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,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],47,V1) ->
-       '$call'(V1)
-    ;  type_error(callable,A,call/47)
-    ).
-
+   (  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))
+   ).
+
+:-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)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,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],48,W1) ->
-       '$call'(W1)
-    ;  type_error(callable,A,call/48)
-    ).
-
+   (  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))
+   ).
+
+:-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)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,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],49,X1) ->
-       '$call'(X1)
-    ;  type_error(callable,A,call/49)
-    ).
-
+   (  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))
+   ).
+
+:-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)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,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],50,Y1) ->
-       '$call'(Y1)
-    ;  type_error(callable,A,call/50)
-    ).
-
+   (  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))
+   ).
+
+:-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)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,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],51,Z1) ->
-       '$call'(Z1)
-    ;  type_error(callable,A,call/51)
-    ).
-
+   (  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))
+   ).
+
+:-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)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,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],52,A2) ->
-       '$call'(A2)
-    ;  type_error(callable,A,call/52)
-    ).
-
+   (  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))
+   ).
+
+:-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)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,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],53,B2) ->
-       '$call'(B2)
-    ;  type_error(callable,A,call/53)
-    ).
-
+   (  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))
+   ).
+
+:-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)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,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],54,C2) ->
-       '$call'(C2)
-    ;  type_error(callable,A,call/54)
-    ).
-
+   (  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))
+   ).
+
+:-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)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,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],55,D2) ->
-       '$call'(D2)
-    ;  type_error(callable,A,call/55)
-    ).
-
+   (  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))
+   ).
+
+:-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)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,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],56,E2) ->
-       '$call'(E2)
-    ;  type_error(callable,A,call/56)
-    ).
-
+   (  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))
+   ).
+
+:-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)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,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],57,F2) ->
-       '$call'(F2)
-    ;  type_error(callable,A,call/57)
-    ).
-
+   (  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))
+   ).
+
+:-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)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,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],58,G2) ->
-       '$call'(G2)
-    ;  type_error(callable,A,call/58)
-    ).
-
+   (  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))
+   ).
+
+:-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)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,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],59,H2) ->
-       '$call'(H2)
-    ;  type_error(callable,A,call/59)
-    ).
-
+   (  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))
+   ).
+
+:-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)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,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],60,I2) ->
-       '$call'(I2)
-    ;  type_error(callable,A,call/60)
-    ).
-
+   (  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))
+   ).
+
+:-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)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,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],61,J2) ->
-       '$call'(J2)
-    ;  type_error(callable,A,call/61)
-    ).
-
+   (  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))
+   ).
+
+:-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)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,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],62,K2) ->
-       '$call'(K2)
-    ;  type_error(callable,A,call/62)
-    ).
-
+   (  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))
+   ).
+
+:-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)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,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],63,L2) ->
-       '$call'(L2)
-    ;  type_error(callable,A,call/63)
-    ).
-
+   (  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))
+   ).
+
+:-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)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,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],64,M2) ->
-       '$call'(M2)
-    ;  type_error(callable,A,call/64)
-    ).
-
+   (  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))
+   ).
+
+:-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)
-    ;  call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,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],65,N2) ->
-       '$call'(N2)
-    ;  type_error(callable,A,call/65)
-    ).
+   (  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))
+   ).
index 4b8988faecbd7e369e2e5d768bdbe83045183ef5..f85a06e955d2dbb596aab44c559c788e9cd6ce9a 100644 (file)
@@ -1339,7 +1339,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
         term: Term,
         settings: CodeGenSettings,
     ) -> Result<StandaloneCompileResult, SessionError> {
-        let mut preprocessor = Preprocessor::new();
+        let mut preprocessor = Preprocessor::new(settings);
 
         let clause = self.try_term_to_tl(term, &mut preprocessor)?;
         let queue = preprocessor.parse_queue(self)?;
@@ -1379,7 +1379,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
         let mut code_ptr = code_len;
 
         let mut clauses = vec![];
-        let mut preprocessor = Preprocessor::new();
+        let mut preprocessor = Preprocessor::new(settings);
 
         for term in predicates.predicates.drain(0..) {
             clauses.push(self.try_term_to_tl(term, &mut preprocessor)?);
index 0e0baade15b0aa20c7b255565de012c9d1c0c20a..47f67da0b0bb16540af7e924514d661afa2d769e 100644 (file)
@@ -4692,11 +4692,11 @@ impl Machine {
                     step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
                 }
                 &Instruction::CallLoadContextModule(_) => {
-                    self.load_context_module();
+                    self.load_context_module(self.machine_st.registers[1]);
                     step_or_fail!(self, self.machine_st.p += 1);
                 }
                 &Instruction::ExecuteLoadContextModule(_) => {
-                    self.load_context_module();
+                    self.load_context_module(self.machine_st.registers[1]);
                     step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
                 }
                 &Instruction::CallLoadContextStream(_) => {
@@ -4859,6 +4859,62 @@ impl Machine {
                     self.machine_st.fail = !self.predicate_defined();
                     self.machine_st.p = self.machine_st.cp;
                 }
+                &Instruction::CallStripModule(_) => {
+                    let (module_loc, qualified_goal) = self.machine_st.strip_module(
+                        self.machine_st.registers[1],
+                        self.machine_st.registers[2],
+                    );
+
+                    let target_module_loc = self.machine_st.registers[2];
+
+                    unify_fn!(
+                        &mut self.machine_st,
+                        module_loc,
+                        target_module_loc
+                    );
+
+                    let target_qualified_goal = self.machine_st.registers[3];
+
+                    unify_fn!(
+                        &mut self.machine_st,
+                        qualified_goal,
+                        target_qualified_goal
+                    );
+
+                    step_or_fail!(self, self.machine_st.p += 1);
+                }
+                &Instruction::ExecuteStripModule(_) => {
+                    let (module_loc, qualified_goal) = self.machine_st.strip_module(
+                        self.machine_st.registers[1],
+                        self.machine_st.registers[2]
+                    );
+
+                    let target_module_loc = self.machine_st.registers[2];
+
+                    unify_fn!(
+                        &mut self.machine_st,
+                        module_loc,
+                        target_module_loc
+                    );
+
+                    let target_qualified_goal = self.machine_st.registers[3];
+
+                    unify_fn!(
+                        &mut self.machine_st,
+                        qualified_goal,
+                        target_qualified_goal
+                    );
+
+                    step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+                }
+                &Instruction::CallPrepareCallClause(arity, _) => {
+                    try_or_throw!(self.machine_st, self.prepare_call_clause(arity));
+                    step_or_fail!(self, self.machine_st.p += 1);
+                }
+                &Instruction::ExecutePrepareCallClause(arity, _) => {
+                    try_or_throw!(self.machine_st, self.prepare_call_clause(arity));
+                    step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+                }
             }
         }
 
index e8f0688db41fbed0fea86b4ff8caf63cf1c3fec5..c974540f09d9629efab330113f59b1328fedbda4 100644 (file)
@@ -1844,7 +1844,7 @@ impl Machine {
                     return;
                 }
                 _ => {
-                    return self.load_context_module();
+                    return self.load_context_module(self.machine_st.registers[1]);
                 }
             }
         }
@@ -1866,9 +1866,9 @@ impl Machine {
         self.machine_st.fail = true;
     }
 
-    pub(crate) fn load_context_module(&mut self) {
+    pub(crate) fn load_context_module(&mut self, target: HeapCellValue) {
         if let Some(load_context) = self.load_contexts.last() {
-            self.machine_st.unify_atom(load_context.module, self.machine_st.registers[1]);
+            self.machine_st.unify_atom(load_context.module, target);
         } else {
             self.machine_st.fail = true;
         }
index be7edd3390f005fb2b289b80a6361ac37354392d..012c7d1917f530fecd04076734a601341b812113 100644 (file)
@@ -2039,12 +2039,15 @@ impl MachineState {
         )
     }
 
-    pub(super) fn setup_call_n(&mut self, arity: usize) -> Result<PredicateKey, MachineStub> {
-        let addr = self.store(self.deref(self.registers[arity]));
-
-        let (name, narity) = read_heap_cell!(addr,
+    pub(crate) fn setup_call_n_init_goal_info(
+        &mut self,
+        goal: HeapCellValue,
+        arity: usize,
+    ) -> Result<(Atom, usize, usize), MachineStub> {
+        Ok(read_heap_cell!(goal,
             (HeapCellValueTag::Str, s) => {
-                let (name, narity) = cell_as_atom_cell!(self.heap[s]).get_name_and_arity();
+                let (name, narity) = cell_as_atom_cell!(self.heap[s])
+                    .get_name_and_arity();
 
                 if narity + arity > MAX_ARITY {
                     let stub = functor_stub(atom!("call"), arity + 1);
@@ -2052,34 +2055,48 @@ impl MachineState {
                     return Err(self.error_form(err, stub));
                 }
 
-                for i in (1..arity).rev() {
-                    self.registers[i + narity] = self.registers[i];
-                }
-
-                for i in 1..narity + 1 {
-                    self.registers[i] = self.heap[s + i];
-                }
-
-                (name, narity)
+                (name, narity, s)
             }
             (HeapCellValueTag::Atom, (name, arity)) => {
                 debug_assert_eq!(arity, 0);
-                (name, 0)
+
+                if name == atom!("[]") {
+                    let stub = functor_stub(atom!("call"), arity + 1);
+                    let err = self.type_error(ValidType::Callable, goal);
+                    return Err(self.error_form(err, stub));
+                }
+
+                (name, 0, 0)
             }
             (HeapCellValueTag::Char, c) => {
-                (self.atom_tbl.build_with(&c.to_string()), 0)
+                (self.atom_tbl.build_with(&c.to_string()), 0, 0)
             }
-            (HeapCellValueTag::Var | HeapCellValueTag::AttrVar | HeapCellValueTag::StackVar, _h) => {
+            (HeapCellValueTag::Var | HeapCellValueTag::AttrVar | HeapCellValueTag::StackVar) => {
                 let stub = functor_stub(atom!("call"), arity + 1);
                 let err = self.instantiation_error();
                 return Err(self.error_form(err, stub));
             }
             _ => {
                 let stub = functor_stub(atom!("call"), arity + 1);
-                let err = self.type_error(ValidType::Callable, addr);
+                let err = self.type_error(ValidType::Callable, goal);
                 return Err(self.error_form(err, stub));
             }
-        );
+        ))
+    }
+
+    pub(crate) fn setup_call_n(&mut self, arity: usize) -> Result<PredicateKey, MachineStub> {
+        let addr = self.store(self.deref(self.registers[arity]));
+        let (name, narity, s) = self.setup_call_n_init_goal_info(addr, arity)?;
+
+        if narity > 0 {
+            for i in (1..arity).rev() {
+                self.registers[i + narity] = self.registers[i];
+            }
+
+            for i in 1..narity + 1 {
+                self.registers[i] = self.heap[s + i];
+            }
+        }
 
         Ok((name, arity + narity - 1))
     }
index 257bc44354794c1404cf81fa4c12363433469a26..6b925522e52590be997dc54522c207972b09ea60 100644 (file)
@@ -1,4 +1,5 @@
 use crate::atom_table::*;
+use crate::codegen::CodeGenSettings;
 use crate::forms::*;
 use crate::instructions::*;
 use crate::iterators::*;
@@ -474,9 +475,10 @@ fn clause_to_query_term<'a, LS: LoadState<'a>>(
     loader: &mut Loader<'a, LS>,
     name: Atom,
     terms: Vec<Term>,
+    call_policy: CallPolicy,
 ) -> QueryTerm {
     let ct = loader.get_clause_type(name, terms.len());
-    QueryTerm::Clause(Cell::default(), ct, terms, false)
+    QueryTerm::Clause(Cell::default(), ct, terms, call_policy)
 }
 
 #[inline]
@@ -485,20 +487,23 @@ fn qualified_clause_to_query_term<'a, LS: LoadState<'a>>(
     module_name: Atom,
     name: Atom,
     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, false)
+    QueryTerm::Clause(Cell::default(), ct, terms, call_policy)
 }
 
 #[derive(Debug)]
 pub(crate) struct Preprocessor {
     queue: VecDeque<VecDeque<Term>>,
+    settings: CodeGenSettings,
 }
 
 impl Preprocessor {
-    pub(super) fn new() -> Self {
+    pub(super) fn new(settings: CodeGenSettings) -> Self {
         Preprocessor {
             queue: VecDeque::new(),
+            settings,
         }
     }
 
@@ -599,7 +604,10 @@ impl Preprocessor {
                 if name == atom!("!") || name == atom!("blocked_!") {
                     Ok(QueryTerm::BlockedCut)
                 } else {
-                    Ok(clause_to_query_term(loader, name, vec![]))
+                    Ok(clause_to_query_term(
+                        loader, name, vec![],
+                        self.settings.default_call_policy(),
+                    ))
                 }
             }
             Term::Literal(_, Literal::Char('!')) => Ok(QueryTerm::BlockedCut),
@@ -663,6 +671,7 @@ impl Preprocessor {
                             module_name,
                             predicate_name,
                             vec![],
+                            self.settings.default_call_policy(),
                         )),
                         (
                             Term::Literal(_, Literal::Atom(module_name)),
@@ -672,22 +681,29 @@ impl Preprocessor {
                             module_name,
                             name,
                             terms,
+                            self.settings.default_call_policy()
                         )),
                         (module_name, predicate_name) => {
                             terms.push(module_name);
                             terms.push(predicate_name);
 
-                            Ok(clause_to_query_term(loader, name, terms))
+                            Ok(clause_to_query_term(
+                                loader,
+                                name,
+                                terms,
+                                self.settings.default_call_policy(),
+                            ))
                         }
                     }
                 }
-                _ => Ok(clause_to_query_term(loader, name, terms)),
+                _ => Ok(clause_to_query_term(loader, name, terms,
+                                             self.settings.default_call_policy())),
             },
             Term::Var(..) => Ok(QueryTerm::Clause(
                 Cell::default(),
                 ClauseType::CallN(1),
                 vec![term],
-                false,
+                self.settings.default_call_policy(),
             )),
             _ => Err(CompilationError::InadmissibleQueryTerm),
         }
@@ -700,10 +716,10 @@ impl Preprocessor {
     ) -> Result<QueryTerm, CompilationError> {
         match term {
             Term::Clause(r, name, mut subterms) => {
-                if subterms.len() == 1 && name == atom!("$call_with_default_policy") {
+                if subterms.len() == 1 && name == atom!("$call_with_inference_counting") {
                     self.to_query_term(loader, subterms.pop().unwrap())
                         .map(|mut query_term| {
-                            query_term.set_default_caller();
+                            query_term.set_call_policy(CallPolicy::Counted);
                             query_term
                         })
                 } else {
index 9a2cd575327941d71ca711225e3fcb813e881be6..c39000102528abfdc37192e44a08c57d3386ee6a 100644 (file)
@@ -887,9 +887,117 @@ impl MachineState {
 
         Ok(string)
     }
+
+    pub(crate) fn strip_module(
+        &self,
+        mut qualified_goal: HeapCellValue,
+        mut module_loc: HeapCellValue,
+    ) -> (HeapCellValue, HeapCellValue) {
+        loop {
+            read_heap_cell!(qualified_goal,
+                (HeapCellValueTag::Str, s) => {
+                    let (name, arity) = cell_as_atom_cell!(self.heap[s])
+                        .get_name_and_arity();
+
+                    if name == atom!(":") && arity == 2 {
+                        module_loc = self.heap[s+1];
+                        qualified_goal = self.heap[s+2];
+                    } else {
+                        break;
+                    }
+                }
+                (HeapCellValueTag::AttrVar | HeapCellValueTag::Var, h) => {
+                    if qualified_goal != self.heap[h] {
+                        qualified_goal = self.heap[h];
+                    } else {
+                        break;
+                    }
+                }
+                _ => {
+                    break;
+                }
+            );
+        }
+
+        (module_loc, qualified_goal)
+    }
 }
 
 impl Machine {
+    #[inline(always)]
+    pub(crate) fn prepare_call_clause(&mut self, arity: usize) -> CallResult {
+        let (module_loc, qualified_goal) = self.machine_st.strip_module(
+            self.machine_st.registers[3],
+            self.machine_st.registers[2],
+        );
+
+        // the first three arguments don't belong to the containing call/N.
+        let arity = arity - 3;
+
+        let (name, narity, s) = self.machine_st.setup_call_n_init_goal_info(
+            qualified_goal,
+            arity,
+        )?;
+
+        let module_loc = self.machine_st.store(self.machine_st.deref(module_loc));
+
+        if module_loc.is_var() {
+            self.load_context_module(module_loc);
+
+            if self.machine_st.fail {
+                self.machine_st.fail = false;
+                self.machine_st.unify_atom(atom!("user"), module_loc);
+
+                if self.machine_st.fail {
+                    return Ok(());
+                }
+            }
+        }
+
+        let target_module_loc = self.machine_st.registers[2];
+
+        unify_fn!(
+            &mut self.machine_st,
+            module_loc,
+            target_module_loc
+        );
+
+        if self.machine_st.fail {
+            return Ok(());
+        }
+
+        // assemble goal from pre-loaded (narity) and supplementary
+        // (arity) arguments.
+
+        let h = self.machine_st.heap.len();
+
+        self.machine_st.heap.push(atom_as_cell!(name, narity + arity));
+
+        let target_goal = if narity + arity > 0 {
+            for idx in 1 .. narity + 1 {
+                self.machine_st.heap.push(self.machine_st.heap[s + idx]);
+            }
+
+            for idx in 1 .. arity + 1 {
+                self.machine_st.heap.push(self.machine_st.registers[3 + idx]);
+            }
+
+            str_loc_as_cell!(h)
+        } else {
+            heap_loc_as_cell!(h)
+        };
+
+        let target_qualified_goal = self.machine_st.registers[1];
+
+        unify_fn!(
+            &mut self.machine_st,
+            target_goal,
+            target_qualified_goal
+        );
+
+        Ok(())
+    }
+
     #[inline(always)]
     pub(crate) fn is_reset_cont_marker(&self, p: usize) -> bool {
         match &self.code[p] {