From ac2a3b01afd4f8d2454700fa4eabec4dbbcdfd1f Mon Sep 17 00:00:00 2001 From: vsc Date: Wed, 6 Oct 2004 16:55:48 +0000 Subject: [PATCH] change configure to support big mem configs get rid of extra globals fix trouble with multifile preds git-svn-id: https://yap.svn.sf.net/svnroot/yap/trunk@1155 b08c6af1-5177-4d33-ba66-4b1c6b8b522a --- C/c_interface.c | 12 ++++++++++-- C/cdmgr.c | 47 ++++++++++++++++++++++++++++++++++------------- C/dbase.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ C/heapgc.c | 38 +++++++++++++++++--------------------- C/init.c | 2 ++ C/tracer.c | 5 +++++ C/utilpreds.c | 3 ++- H/Heap.h | 16 +++++++++++++++- H/clause.h | 3 ++- H/rheap.h | 13 ++++++++++++- m4/Yap.h.m4 | 6 +----- pl/boot.yap | 12 ------------ pl/consult.yap | 3 +-- 13 files changed, 147 insertions(+), 59 deletions(-) diff --git a/C/c_interface.c b/C/c_interface.c index 47833344f..4290f9d8c 100644 --- a/C/c_interface.c +++ b/C/c_interface.c @@ -10,8 +10,16 @@ * File: c_interface.c * * comments: c_interface primitives definition * * * -* Last rev: $Date: 2004-08-11 16:14:51 $,$Author: vsc $ * +* Last rev: $Date: 2004-10-06 16:55:46 $,$Author: vsc $ * * $Log: not supported by cvs2svn $ +* Revision 1.53 2004/08/11 16:14:51 vsc +* whole lot of fixes: +* - memory leak in indexing +* - memory management in WIN32 now supports holes +* - extend Yap interface, more support for SWI-Interface +* - new predicate mktime in system +* - buffer console I/O in WIN32 +* * Revision 1.52 2004/07/23 03:37:16 vsc * fix heap overflow in YAP_LookupAtom * @@ -968,7 +976,7 @@ YAP_CompileClause(Term t) codeaddr = Yap_cclause (t,0, mod, t); if (codeaddr != NULL) { t = Deref(ARG1); /* just in case there was an heap overflow */ - Yap_addclause (t, codeaddr, TRUE, mod); + Yap_addclause (t, codeaddr, TRUE, mod, TermNil); } YAPLeaveCriticalSection(); diff --git a/C/cdmgr.c b/C/cdmgr.c index df8abbd3d..4aa6f6c49 100644 --- a/C/cdmgr.c +++ b/C/cdmgr.c @@ -11,8 +11,11 @@ * File: cdmgr.c * * comments: Code manager * * * -* Last rev: $Date: 2004-09-30 21:37:40 $,$Author: vsc $ * +* Last rev: $Date: 2004-10-06 16:55:46 $,$Author: vsc $ * * $Log: not supported by cvs2svn $ +* Revision 1.135 2004/09/30 21:37:40 vsc +* fixes for thread support +* * Revision 1.134 2004/09/30 19:51:53 vsc * fix overflow from within clause/2 * @@ -1466,8 +1469,8 @@ is_fact(Term t) return FALSE; } -static Term -addclause(Term t, yamop *cp, int mode, int mod) +static int +addclause(Term t, yamop *cp, int mode, Term mod, Term t4ref) /* * mode @@ -1589,15 +1592,32 @@ addclause(Term t, yamop *cp, int mode, int mod) #endif WRITE_UNLOCK(p->PRWLock); if (pflags & LogUpdatePredFlag) { - return MkDBRefTerm((DBRef)ClauseCodeToLogUpdClause(cp)); + tf = MkDBRefTerm((DBRef)ClauseCodeToLogUpdClause(cp)); } else { - return Yap_MkStaticRefTerm((StaticClause *)cp); + tf = Yap_MkStaticRefTerm((StaticClause *)cp); } + if (t4ref != TermNil) { + if (!Yap_unify(t4ref,tf)) { + return FALSE; + } + } + if (pflags & MultiFileFlag) { + /* add Info on new clause for multifile predicates to the DB */ + Term t[5], tn; + t[0] = MkAtomTerm(YapConsultingFile()); + t[1] = MkAtomTerm(at); + t[2] = MkIntegerTerm(Arity); + t[3] = mod; + t[4] = tf; + tn = Yap_MkApplTerm(FunctorMultiFileClause,5,t); + Yap_Recordz(AtomMultiFile,tn); + } + return TRUE; } -void -Yap_addclause(Term t, yamop *cp, int mode, Term mod) { - addclause(t, cp, mode, mod); +int +Yap_addclause(Term t, yamop *cp, int mode, Term mod, Term t4ref) { + return addclause(t, cp, mode, mod, t4ref); } void @@ -1855,7 +1875,7 @@ p_compile(void) to cclause in case there is overflow */ t = Deref(ARG1); /* just in case there was an heap overflow */ if (!Yap_ErrorMessage) - addclause(t, codeadr, (int) (IntOfTerm(t1) & 3), mod); + addclause(t, codeadr, (int) (IntOfTerm(t1) & 3), mod, TermNil); YAPLeaveCriticalSection(); if (Yap_ErrorMessage) { if (IntOfTerm(t1) & 4) { @@ -1890,17 +1910,18 @@ p_compile_dynamic(void) if (!Yap_ErrorMessage) { optimizer_on = old_optimize; - t = addclause(t, code_adr, (int) (IntOfTerm(t1) & 3), mod); - } else { + addclause(t, code_adr, (int) (IntOfTerm(t1) & 3), mod, ARG5); + } + if (Yap_ErrorMessage) { if (IntOfTerm(t1) & 4) { Yap_Error(Yap_Error_TYPE, Yap_Error_Term, "line %d, %s", Yap_FirstLineInParse(), Yap_ErrorMessage); } else Yap_Error(Yap_Error_TYPE, Yap_Error_Term, Yap_ErrorMessage); YAPLeaveCriticalSection(); - return (FALSE); + return FALSE; } YAPLeaveCriticalSection(); - return Yap_unify(ARG5, t); + return TRUE; } static int consult_level = 0; diff --git a/C/dbase.c b/C/dbase.c index 33b004273..09992e66b 100644 --- a/C/dbase.c +++ b/C/dbase.c @@ -2078,6 +2078,52 @@ p_rcdz(void) goto restart_record; } +/* recordz(+Functor,+Term,-Ref) */ +Int +Yap_Recordz(Atom at, Term t2) +{ + PredEntry *pe; + + pe = find_lu_entry(MkAtomTerm(at)); + restart_record: + Yap_Error_Size = 0; + if (pe) { + record_lu(pe, t2, MkLast); + } else { + record(MkLast, MkAtomTerm(at), t2, Unsigned(0)); + } + if (YAP_NO_ERROR == Yap_Error_TYPE) { + return TRUE; + } + ARG1 = t2; + switch(Yap_Error_TYPE) { + case OUT_OF_STACK_ERROR: + if (!Yap_gc(1, ENV, P)) { + Yap_Error(OUT_OF_STACK_ERROR, TermNil, Yap_ErrorMessage); + return FALSE; + } + goto recover_record; + case OUT_OF_TRAIL_ERROR: + if(!Yap_growtrail (sizeof(CELL) * 16 * 1024L)) { + Yap_Error(OUT_OF_TRAIL_ERROR, TermNil, "YAP could not grow trail in recorda/3"); + return FALSE; + } + goto recover_record; + case OUT_OF_HEAP_ERROR: + if (!Yap_ExpandPreAllocCodeSpace(Yap_Error_Size)) { + return FALSE; + } + goto recover_record; + default: + Yap_Error(Yap_Error_TYPE, Yap_Error_Term, Yap_ErrorMessage); + return(FALSE); + } + recover_record: + Yap_Error_TYPE = YAP_NO_ERROR; + t2 = Deref(ARG1); + goto restart_record; +} + /* '$recordzp'(+Functor,+Term,-Ref) */ static Int p_rcdzp(void) diff --git a/C/heapgc.c b/C/heapgc.c index b120185c0..a81d24514 100644 --- a/C/heapgc.c +++ b/C/heapgc.c @@ -35,11 +35,7 @@ static char SccsId[] = "%W% %G%"; #ifndef DEBUG static #endif -unsigned int gc_calls = 0; /* number of times GC has been called */ - -static Int tot_gc_time = 0; /* total time spent in GC */ - -static Int tot_gc_recovered = 0; /* number of heap objects in all garbage collections */ +static Int Tot_Gc_Recovered = 0; /* number of heap objects in all garbage collections */ /* in a single gc */ static unsigned long int total_marked; /* number of heap objects marked */ @@ -2915,7 +2911,7 @@ compact_heap(void) #ifdef DEBUG if (total_marked != found_marked) fprintf(Yap_stderr,"%% Upward (%d): %ld total against %ld found\n", - gc_calls, + GcCalls, (unsigned long int)total_marked, (unsigned long int)found_marked); found_marked = 0; @@ -2975,7 +2971,7 @@ compact_heap(void) #ifdef DEBUG if (total_marked != found_marked) fprintf(Yap_stderr,"%% Downward (%d): %ld total against %ld found\n", - gc_calls, + GcCalls, (unsigned long int)total_marked, (unsigned long int)found_marked); #endif @@ -3118,7 +3114,7 @@ icompact_heap(void) #ifdef DEBUG if (total_marked != found_marked) fprintf(Yap_stderr,"%% Upward (%d): %ld total against %ld found\n", - gc_calls, + GcCalls, (unsigned long int)total_marked, (unsigned long int)found_marked); found_marked = 0; @@ -3173,7 +3169,7 @@ icompact_heap(void) #ifdef DEBUG if (total_marked != found_marked) fprintf(Yap_stderr,"%% Downward (%d): %ld total against %ld found\n", - gc_calls, + GcCalls, (unsigned long int)total_marked, (unsigned long int)found_marked); #endif @@ -3365,7 +3361,7 @@ do_gc(Int predarity, CELL *current_env, yamop *nextop) if (gc_trace) { fprintf(Yap_stderr, "[gc]\n"); } else if (gc_verbose) { - fprintf(Yap_stderr, "%% Start of garbage collection %d:\n", gc_calls); + fprintf(Yap_stderr, "%% Start of garbage collection %d:\n", GcCalls); #ifndef EARLY_RESET fprintf(Yap_stderr, "%% no early reset in trail\n"); #endif @@ -3452,10 +3448,10 @@ do_gc(Int predarity, CELL *current_env, yamop *nextop) fprintf(Yap_stderr, "%% Compress: took %g sec\n", (double)(c_time-time_start)/1000); } gc_time += (c_time-time_start); - tot_gc_time += gc_time; - tot_gc_recovered += heap_cells-total_marked; + TotGcTime += gc_time; + Tot_Gc_Recovered += heap_cells-total_marked; if (gc_verbose) { - fprintf(Yap_stderr, "%% GC %d took %g sec, total of %g sec doing GC so far.\n", gc_calls, (double)gc_time/1000, (double)tot_gc_time/1000); + fprintf(Yap_stderr, "%% GC %d took %g sec, total of %g sec doing GC so far.\n", GcCalls, (double)gc_time/1000, (double)TotGcTime/1000); fprintf(Yap_stderr, "%% Left %ld cells free in stacks.\n", (unsigned long int)(ASP-H)); } @@ -3490,15 +3486,15 @@ is_gc_very_verbose(void) Int Yap_total_gc_time(void) { - return(tot_gc_time); + return(TotGcTime); } static Int p_inform_gc(void) { - Term tn = MkIntegerTerm(tot_gc_time); - Term tt = MkIntegerTerm(gc_calls); - Term ts = MkIntegerTerm((tot_gc_recovered*sizeof(CELL))); + Term tn = MkIntegerTerm(TotGcTime); + Term tt = MkIntegerTerm(GcCalls); + Term ts = MkIntegerTerm((Tot_Gc_Recovered*sizeof(CELL))); return(Yap_unify(tn, ARG2) && Yap_unify(tt, ARG1) && Yap_unify(ts, ARG3)); @@ -3526,17 +3522,17 @@ call_gc(UInt gc_lim, Int predarity, CELL *current_env, yamop *nextop) gc_margin = (UInt)IntegerOfTerm(Tgc_margin); } else { /* only go exponential for the first 8 calls */ - if (gc_calls < 8) - gc_margin <<= gc_calls; + if (GcCalls < 8) + gc_margin <<= GcCalls; else { /* next grow linearly */ gc_margin <<= 8; - gc_margin *= gc_calls; + gc_margin *= GcCalls; } } if (gc_margin < gc_lim) gc_margin = gc_lim; - gc_calls++; + GcCalls++; if (gc_on) { effectiveness = do_gc(predarity, current_env, nextop); if (effectiveness > 90) { diff --git a/C/init.c b/C/init.c index a94291377..03e9ef682 100644 --- a/C/init.c +++ b/C/init.c @@ -964,6 +964,7 @@ InitCodes(void) heap_regs->atom_local = Yap_LookupAtom("local_sp"); heap_regs->atom_meta_call = Yap_FullLookupAtom("$call"); heap_regs->atom_minus = Yap_LookupAtom("-"); + heap_regs->atom_multi_file = Yap_FullLookupAtom("$mf"); heap_regs->atom_nan = Yap_LookupAtom("nan"); AtomNot = Yap_LookupAtom("\\+"); heap_regs->atom_otherwise = Yap_LookupAtom("otherwise"); @@ -1024,6 +1025,7 @@ InitCodes(void) heap_regs->functor_list = Yap_MkFunctor(Yap_LookupAtom("."), 2); heap_regs->functor_mega_clause = Yap_MkFunctor (Yap_FullLookupAtom("$mega_clause"), 2); heap_regs->functor_module = Yap_MkFunctor(Yap_LookupAtom(":"), 2); + heap_regs->functor_multi_file_clause = Yap_MkFunctor(Yap_FullLookupAtom("$mf_clause"), 5); #ifdef MULTI_ASSIGNMENT_VARIABLES heap_regs->functor_mutable = Yap_MkFunctor(Yap_FullLookupAtom("$mutable_variable"), sizeof(timed_var)/sizeof(CELL)); diff --git a/C/tracer.c b/C/tracer.c index 413f95013..1f177ed24 100644 --- a/C/tracer.c +++ b/C/tracer.c @@ -120,6 +120,11 @@ low_level_trace(yap_low_level_port port, PredEntry *pred, CELL *args) /* extern int gc_calls; */ vsc_count++; + /* if (vsc_count < 16458458000LL) + return; + if (vsc_count == 16458458322LL) + jmp_deb(1); + */ #ifdef COMMENTED // if (vsc_count == 218280) // vsc_xstop = 1; diff --git a/C/utilpreds.c b/C/utilpreds.c index 024211693..20caae6cd 100644 --- a/C/utilpreds.c +++ b/C/utilpreds.c @@ -1529,6 +1529,7 @@ p_variant(void) /* variant terms t1 and t2 */ RepPair(t1)+1, RepPair(t2)-1); if (out < 0) goto error; + return out; } else return (FALSE); } @@ -1850,7 +1851,7 @@ void Yap_InitUtilCPreds(void) Yap_InitCPred("term_variables", 2, p_term_variables, SafePredFlag); Yap_InitCPred("variable_in_term", 2, p_var_in_term, SafePredFlag); Yap_InitCPred("term_hash", 4, GvNTermHash, SafePredFlag); - Yap_InitCPred("variant", 2, p_variant, SafePredFlag); + Yap_InitCPred("variant", 2, p_variant, 0); Yap_InitCPred("subsumes", 2, p_subsumes, SafePredFlag); CurrentModule = cm; #ifdef DEBUG diff --git a/H/Heap.h b/H/Heap.h index bdcc39b68..42887669a 100644 --- a/H/Heap.h +++ b/H/Heap.h @@ -10,7 +10,7 @@ * File: Heap.h * * mods: * * comments: Heap Init Structure * -* version: $Id: Heap.h,v 1.66 2004-09-27 20:45:03 vsc Exp $ * +* version: $Id: Heap.h,v 1.67 2004-10-06 16:55:47 vsc Exp $ * *************************************************************************/ /* information that can be stored in Code Space */ @@ -60,6 +60,10 @@ typedef struct worker_local_struct { Term mutable_list; Term atts_mutable_list; #endif + /* gc_stuff */ + unsigned int gc_calls; /* number of times GC has been called */ + Int tot_gc_time; /* total time spent in GC */ + Int tot_gc_recovered; /* number of heap objects in all garbage collections */ } worker_local; #ifdef THREADS @@ -264,6 +268,7 @@ typedef struct various_codes { atom_local, atom_meta_call, atom_minus, + atom_multi_file, atom_nan, atom_otherwise, atom_pi, @@ -323,6 +328,7 @@ typedef struct various_codes { functor_list, functor_mega_clause, functor_module, + functor_multi_file_clause, #ifdef MULTI_ASSIGNMENT_VARIABLES functor_mutable, #endif @@ -523,6 +529,7 @@ struct various_codes *heap_regs; #define AtomLT heap_regs->atom_l_t #define AtomMetaCall heap_regs->atom_meta_call #define AtomMinus heap_regs->atom_minus +#define AtomMultiFile heap_regs->atom_multi_file #define AtomNan heap_regs->atom_nan #define AtomOtherwise heap_regs->atom_otherwise #define AtomPi heap_regs->atom_pi @@ -580,6 +587,7 @@ struct various_codes *heap_regs; #define FunctorList heap_regs->functor_list #define FunctorMegaClause heap_regs->functor_mega_clause #define FunctorModule heap_regs->functor_module +#define FunctorMultiFileClause heap_regs->functor_multi_file_clause #ifdef MULTI_ASSIGNMENT_VARIABLES #define FunctorMutable heap_regs->functor_mutable #endif @@ -661,6 +669,9 @@ struct various_codes *heap_regs; #define MutableList heap_regs->wl[worker_id].mutable_list #define AttsMutableList heap_regs->wl[worker_id].atts_mutable_list #endif +#define GcCalls heap_regs->wl[worker_id].gc_calls +#define TotGcTime heap_regs->wl[worker_id].tot_gc_time +#define TotGcRecovered heap_regs->wl[worker_id].tot_gc_recovered #else #define ActiveSignals heap_regs->wl.active_signals #define DelayedTrace heap_regs->wl.delayed_trace @@ -672,6 +683,9 @@ struct various_codes *heap_regs; #define WokenGoals heap_regs->wl.woken_goals #define MutableList heap_regs->wl.mutable_list #define AttsMutableList heap_regs->wl.atts_mutable_list +#define GcCalls heap_regs->wl.gc_calls +#define TotGcTime heap_regs->wl.tot_gc_time +#define TotGcRecovered heap_regs->wl.tot_gc_recovered #endif #endif #define profiling heap_regs->compiler_profiling diff --git a/H/clause.h b/H/clause.h index dbe0cad53..4776bb9cf 100644 --- a/H/clause.h +++ b/H/clause.h @@ -185,7 +185,7 @@ void STD_PROTO(Yap_InitComma,(void)); /* cdmgr.c */ void STD_PROTO(Yap_IPred,(PredEntry *, UInt)); -void STD_PROTO(Yap_addclause,(Term,yamop *,int,Term)); +int STD_PROTO(Yap_addclause,(Term,yamop *,int,Term,Term)); void STD_PROTO(Yap_add_logupd_clause,(PredEntry *,LogUpdClause *,int)); void STD_PROTO(Yap_kill_iblock,(ClauseUnion *,ClauseUnion *,PredEntry *)); void STD_PROTO(Yap_cleanup_dangling_indices,(yamop *,yamop *,yamop *,yamop *)); @@ -196,6 +196,7 @@ ClauseUnion *STD_PROTO(Yap_find_owner_index,(yamop *, PredEntry *)); void STD_PROTO(Yap_ErCl,(DynamicClause *)); void STD_PROTO(Yap_ErLogUpdCl,(LogUpdClause *)); void STD_PROTO(Yap_ErLogUpdIndex,(LogUpdIndex *)); +Int STD_PROTO(Yap_Recordz,(Atom, Term)); /* exec.c */ Term STD_PROTO(Yap_cp_as_integer,(choiceptr)); diff --git a/H/rheap.h b/H/rheap.h index e8407be68..4c3c51ad8 100644 --- a/H/rheap.h +++ b/H/rheap.h @@ -11,8 +11,17 @@ * File: rheap.h * * comments: walk through heap code * * * -* Last rev: $Date: 2004-09-27 20:45:04 $,$Author: vsc $ * +* Last rev: $Date: 2004-10-06 16:55:47 $,$Author: vsc $ * * $Log: not supported by cvs2svn $ +* Revision 1.43 2004/09/27 20:45:04 vsc +* Mega clauses +* Fixes to sizeof(expand_clauses) which was being overestimated +* Fixes to profiling+indexing +* Fixes to reallocation of memory after restoring +* Make sure all clauses, even for C, end in _Ystop +* Don't reuse space for Streams +* Fix Stream_F on StreaNo+1 +* * Revision 1.42 2004/06/05 03:37:00 vsc * coroutining is now a part of attvars. * some more fixes. @@ -281,6 +290,7 @@ restore_codes(void) heap_regs->atom_local = AtomAdjust(heap_regs->atom_local); heap_regs->atom_meta_call = AtomAdjust(heap_regs->atom_meta_call); heap_regs->atom_minus = AtomAdjust(heap_regs->atom_minus); + heap_regs->atom_multi_file = AtomAdjust(heap_regs->atom_multi_file); heap_regs->atom_nan = AtomAdjust(heap_regs->atom_nan); heap_regs->atom_otherwise = AtomAdjust(heap_regs->atom_otherwise); heap_regs->atom_pi = AtomAdjust(heap_regs->atom_pi); @@ -334,6 +344,7 @@ restore_codes(void) heap_regs->functor_list = FuncAdjust(heap_regs->functor_list); heap_regs->functor_mega_clause = FuncAdjust(heap_regs->functor_mega_clause); heap_regs->functor_module = FuncAdjust(heap_regs->functor_module); + heap_regs->functor_multi_file_clause = FuncAdjust(heap_regs->functor_multi_file_clause); #ifdef MULTI_ASSIGNMENT_VARIABLES heap_regs->functor_mutable = FuncAdjust(heap_regs->functor_mutable); #endif diff --git a/m4/Yap.h.m4 b/m4/Yap.h.m4 index 7fc95bc74..b3d3ae039 100644 --- a/m4/Yap.h.m4 +++ b/m4/Yap.h.m4 @@ -10,7 +10,7 @@ * File: Yap.h.m4 * * mods: * * comments: main header file for YAP * -* version: $Id: Yap.h.m4,v 1.69 2004-10-04 18:56:20 vsc Exp $ * +* version: $Id: Yap.h.m4,v 1.70 2004-10-06 16:55:48 vsc Exp $ * *************************************************************************/ #include "config.h" @@ -85,10 +85,6 @@ #define FROZEN_STACKS 1 #endif /* TABLING || SBA */ -#if USE_SYSTEM_MALLOC -#define GC_NO_TAGS 1 -#endif - #ifdef _MSC_VER /* Microsoft's Visual C++ Compiler */ /* adjust a config.h from mingw32 to work with vc++ */ #ifdef HAVE_GCC diff --git a/pl/boot.yap b/pl/boot.yap index 53cf70f1f..90bef0643 100644 --- a/pl/boot.yap +++ b/pl/boot.yap @@ -872,7 +872,6 @@ break :- get_value('$break',BL), NBL is BL+1, ), '$loop'(Stream,consult), '$end_consult', - '$add_multifile_clauses'(File), set_value('$consulting',Old), set_value('$consulting_file',OldF), '$current_module'(NewMod,OldModule), @@ -1126,16 +1125,5 @@ throw(Ball) :- '$run_toplevel_hooks'. -% add multifile clauses belonging to current file. -'$add_multifile_clauses'(FileName) :- - recorded('$multifile_defs','$defined'(File,Name,Arity,Module),_), - functor(P,Name,Arity), - '$clause'(P,Module,_,Ref), - % check if someone else defines it. - \+ recorded('$mf','$mf_clause'(_,_,_,_,Ref),_), - recordz('$mf','$mf_clause'(FileName,Name,Arity,Module,Ref),R), - fail. -'$add_multifile_clauses'(_). - diff --git a/pl/consult.yap b/pl/consult.yap index b625cab54..5e6fefcbf 100644 --- a/pl/consult.yap +++ b/pl/consult.yap @@ -129,7 +129,6 @@ reconsult(Fs) :- '$loop'(Stream,reconsult), '$end_consult', '$clear_reconsulting', - '$add_multifile_clauses'(File), set_value('$consulting',Old), set_value('$consulting_file',OldF), '$cd'(OldD), @@ -280,7 +279,7 @@ remove_from_path(New) :- '$check_path'(New,Path), '$check_path'([Ch],[Ch,A]) :- !, integer(Ch), '$dir_separator'(A). '$check_path'([N|S],[N|SN]) :- integer(N), '$check_path'(S,SN). -% add_multifile_predicate when we start consul +% add_multifile_predicate when we start consult '$add_multifile'(Name,Arity,Module) :- get_value('$consulting_file',File), '$add_multifile'(File,Name,Arity,Module).