YAP 7.1.0
consult.c
1
2
3 #include "Yap.h"
4
5#include "YapHeap.h"
6#include "Yapproto.h"
7#ifdef SCCS
8static char SccsId[] = "@(#)cdmgr.c 1.1 05/02/98";
9#endif
10
11#include "YapEval.h"
12#include "clause.h"
13#include "tracer.h"
14#include "yapio.h"
15#ifdef YAPOR
16#include "or.macros.h"
17#endif /* YAPOR */
18#ifdef TABLING
19#include "tab.macros.h"
20#endif /* TABLING */
21#if HAVE_STRING_H
22#include <string.h>
23#endif
24#include <assert.h>
25#include <heapgc.h>
26#include <iopreds.h>
27
28static void retract_all(PredEntry *, int);
29static void expand_consult(void);
30static Int p_startconsult(USES_REGS1);
31static Int p_showconslultlev(USES_REGS1);
32
33static void InitConsultStack(void) {
34 CACHE_REGS
35 LOCAL_ConsultLow = (consult_obj *)Yap_AllocCodeSpace(sizeof(consult_obj) *
36 InitialConsultCapacity);
37 if (LOCAL_ConsultLow == NULL) {
38 Yap_ThrowError(RESOURCE_ERROR_HEAP, TermNil, "No Heap Space in InitCodes");
39 return;
40 }
41 LOCAL_ConsultCapacity = InitialConsultCapacity;
42 LOCAL_ConsultBase = LOCAL_ConsultSp =
43 LOCAL_ConsultLow + LOCAL_ConsultCapacity;
44}
45
46Atom Yap_ConsultingFile(USES_REGS1) {
47 int sno;
48 if ((sno = Yap_CheckAlias(AtomLoopStream)) >= 0) {
49 // if(sno ==0)
50 // return(AtomUserIn);
51 Atom at = StreamFullName(sno);
52 if (at) return at;
53 }
54 if (LOCAL_SourceFileName != NULL) {
55 return LOCAL_SourceFileName;
56 }
57 if (LOCAL_consult_level == 0) {
58 return (AtomUser);
59 } else {
60 return (Yap_ULookupAtom(LOCAL_ConsultBase->f_layer->f_name));
61 }
62}
63/* p is already locked */
64static void retract_all(PredEntry *p, int in_use) {
65 yamop *q;
66
67 q = p->cs.p_code.FirstClause;
68 if (q != NULL) {
69 if (p->PredFlags & LogUpdatePredFlag) {
70 LogUpdClause *cl = ClauseCodeToLogUpdClause(q);
71 do {
72 LogUpdClause *ncl = cl->ClNext;
73 Yap_ErLogUpdCl(cl);
74 cl = ncl;
75 } while (cl != NULL);
76 } else if (p->PredFlags & MegaClausePredFlag) {
77 MegaClause *cl = ClauseCodeToMegaClause(q);
78
79 if (in_use || cl->ClFlags & HasBlobsMask) {
80 LOCK(DeadMegaClausesLock);
81 cl->ClNext = DeadMegaClauses;
82 DeadMegaClauses = cl;
83 UNLOCK(DeadMegaClausesLock);
84 } else {
85 Yap_InformOfRemoval(cl);
86 Yap_ClauseSpace -= cl->ClSize;
87 Yap_FreeCodeSpace((char *)cl);
88 }
89 /* make sure this is not a MegaClause */
90 p->PredFlags &= ~MegaClausePredFlag;
91 p->cs.p_code.NOfClauses = 0;
92 } else {
93 StaticClause *cl = ClauseCodeToStaticClause(q);
94
95 while (cl) {
96 StaticClause *ncl = cl->ClNext;
97
98 if (in_use || cl->ClFlags & HasBlobsMask) {
99 LOCK(DeadStaticClausesLock);
100 cl->ClNext = DeadStaticClauses;
101 DeadStaticClauses = cl;
102 UNLOCK(DeadStaticClausesLock);
103 } else {
104 Yap_InformOfRemoval(cl);
105 Yap_ClauseSpace -= cl->ClSize;
106 Yap_FreeCodeSpace((char *)cl);
107 }
108 p->cs.p_code.NOfClauses--;
109 if (!ncl)
110 break;
111 cl = ncl;
112 }
113 }
114 }
115 p->cs.p_code.FirstClause = NULL;
116 p->cs.p_code.LastClause = NULL;
117 if (is_live(p)) {
118 p->cs.p_code.TrueCodeOfPred = p->CodeOfPred =
119 (yamop *)(&p->OpcodeOfPred);
120 p->OpcodeOfPred = FAIL_OPCODE;
121 } else {
122 p->OpcodeOfPred = UNDEF_OPCODE;
123 p->PredFlags |= UndefPredFlag;
124 }
125 p->cs.p_code.TrueCodeOfPred = p->CodeOfPred = (yamop *)(&(p->OpcodeOfPred));
126 if (trueGlobalPrologFlag(PROFILING_FLAG)) {
127 p->PredFlags |= ProfiledPredFlag;
128 if (!Yap_initProfiler(p)) {
129 return;
130 }
131 } else
132 p->PredFlags &= ~ProfiledPredFlag;
133 if (CALL_COUNTING) {
134 p->PredFlags |= CountPredFlag;
135 } else
136 p->PredFlags &= ~CountPredFlag;
137 Yap_PutValue(AtomAbol, MkAtomTerm(AtomTrue));
138}
139
140static void addcl_permission_error(AtomEntry *ap, Int Arity, int in_use) {
141 CACHE_REGS
142
143 LOCAL_Error_TYPE = PERMISSION_ERROR_MODIFY_STATIC_PROCEDURE;
144 LOCAL_ErrorMessage = Malloc(256);
145
146 if (in_use) {
147 if (Arity == 0)
148 sprintf(LOCAL_ErrorMessage, "static predicate %s is in use", ap->StrOfAE);
149 else
150 sprintf(LOCAL_ErrorMessage,
151 "static predicate %s/" Int_FORMAT " is in use", ap->StrOfAE,
152 Arity);
153 } else {
154 if (Arity == 0)
155 sprintf(LOCAL_ErrorMessage, "system predicate %s", ap->StrOfAE);
156 else
157 sprintf(LOCAL_ErrorMessage, "system predicate %s/" Int_FORMAT,
158 ap->StrOfAE, Arity);
159 }
160}
161
162
163int Yap_not_was_reconsulted(PredEntry *p, Term t, int mode) {
164 CACHE_REGS
165 register consult_obj *fp;
166 Prop p0 = AbsProp((PropEntry *)p);
167
168 if (p == LOCAL_LastAssertedPred)
169 return FALSE;
170 if (!LOCAL_ConsultSp) {
171 InitConsultStack();
172 }
173 if (p->cs.p_code.NOfClauses) {
174 for (fp = LOCAL_ConsultSp; fp < LOCAL_ConsultBase; ++fp)
175 if (fp->p == p0)
176 break;
177 } else {
178 fp = LOCAL_ConsultBase;
179 }
180 if (fp != LOCAL_ConsultBase) {
181 LOCAL_LastAssertedPred = p;
182 return false; /* careful */
183 } else if (mode) { // consulting again a predicate in the original file.
184 if ((p->cs.p_code.NOfClauses &&
185 p->src.OwnerFile == Yap_ConsultingFile(PASS_REGS1) &&
186 p->src.OwnerFile != AtomNil && !(p->PredFlags & MultiFileFlag) &&
187 p->src.OwnerFile != AtomUserIn)) {
188 // if (p->ArityOfPE)
189 // printf("+ %s %s
190 //%d\n",NameOfFunctor(p->FunctorOfPred)->StrOfAE,p->src.OwnerFile->StrOfAE,
191 // p->cs.p_code.NOfClauses);
192 retract_all(p, Yap_static_in_use(p, TRUE));
193 }
194 // printf("- %s
195 //%s\n",NameOfFunctor(p->FunctorOfPred)->StrOfAE,p->src.OwnerFile->StrOfAE);
196 }
197 if (mode) {
198 if (LOCAL_ConsultSp <= LOCAL_ConsultLow + 6) {
199 expand_consult();
200 }
201 --LOCAL_ConsultSp;
202 LOCAL_ConsultSp->p = p0;
203 if (LOCAL_ConsultBase != LOCAL_ConsultLow + LOCAL_ConsultCapacity &&
204 LOCAL_ConsultBase->f_layer->mode &&
205 !(p->PredFlags & MultiFileFlag)) /* we are in reconsult mode */ {
206 retract_all(p, Yap_static_in_use(p, TRUE));
207 }
208 // p->src.OwnerFile = Yap_ConsultingFile(PASS_REGS1);
209 }
210 LOCAL_LastAssertedPred = p;
211 return TRUE; /* careful */
212}
213
214static Int parent_stream_file(USES_REGS1) {
215 if (LOCAL_consult_level <= 0) {
216 return Yap_unify(ARG1,TermUserIn);
217 } else {
218 return Yap_unify(ARG1,MkAtomTerm(Yap_ULookupAtom(LOCAL_ConsultBase->f_layer->f_name)));
219 }
220}
221
222static Int parent_source_module(USES_REGS1) {
223 if (LOCAL_consult_level <= 0) {
224 return Yap_unify(ARG1,TermUser);
225 } else {
226 Term m = (LOCAL_ConsultBase->f_layer->m==0?TermProlog:LOCAL_ConsultBase->f_layer->m);
227 return Yap_unify(ARG1,m);
228 }
229}
230
231static Int parent_stream_line(USES_REGS1) {
232 if (LOCAL_consult_level <= 0) {
233 return Yap_unify(ARG1,MkIntTerm(0));
234 } else {
235 return Yap_unify(ARG1,MkIntTerm(LOCAL_ConsultBase->f_layer->line));
236 }
237}
238
239static Int grandparent_source_module(USES_REGS1) {
240 if (LOCAL_consult_level < 2) {
241 return Yap_unify(ARG1,TermUser);
242 } else {
243 union CONSULT_OBJ *p = LOCAL_ConsultBase+LOCAL_ConsultBase->f_layer->c;
244 if (p->f_layer->m)
245 return Yap_unify(ARG1,p->f_layer->m);
246 else
247 return Yap_unify(ARG1,TermProlog);
248 }
249}
250
251
252static void end_consult(USES_REGS1) {
253 int osnow = Yap_CheckAlias(AtomLoopStream);
254 if (osnow > 0)
255 Yap_CloseStream(osnow);
256 setAtomicLocalPrologFlag(COMPILATION_MODE_FLAG, LOCAL_ConsultSp->f_layer->CompilationMode);
257 Yap_ChDir(RepAtom(AtomOfTerm(LOCAL_ConsultBase->f_layer->cwd))->StrOfAE);
258 CurrentModule = LOCAL_SourceModule = LOCAL_ConsultBase->f_layer->m;
259 setBooleanLocalPrologFlag(VERBOSE_LOAD_FLAG, !LOCAL_ConsultBase->f_layer->silent);
260 setBooleanLocalPrologFlag(AUTOLOAD_FLAG, !LOCAL_ConsultBase->f_layer->autoload);
261 LOCAL_ConsultSp = LOCAL_ConsultBase;
262 LOCAL_ConsultBase = LOCAL_ConsultSp + LOCAL_ConsultSp->f_layer->c;
263 Yap_FreeCodeSpace(LOCAL_ConsultSp->f_layer);
264 LOCAL_ConsultSp ++;
265 if (LOCAL_consult_level>0)
266 LOCAL_consult_level--;
267 LOCAL_LastAssertedPred = NULL;
268#if !defined(YAPOR) && !defined(YAPOR_SBA)
269/* if (LOCAL_consult_level == 0)
270 do_toggle_static_predicates_in_use(FALSE);*/
271#endif
272 if (LOCAL_consult_level==0)
273 setBooleanLocalPrologFlag(COMPILING_FLAG, false);
274
275}
276
277static void expand_consult(void) {
278 CACHE_REGS
279 consult_obj *new_cl, *new_cs;
280 UInt OldConsultCapacity = LOCAL_ConsultCapacity;
281
282 /* now double consult capacity */
283 LOCAL_ConsultCapacity += InitialConsultCapacity;
284 /* I assume it always works ;-) */
285 while ((new_cl = (consult_obj *)Yap_AllocCodeSpace(
286 sizeof(consult_obj) * LOCAL_ConsultCapacity)) == NULL) {
287 if (!Yap_growheap(FALSE, sizeof(consult_obj) * LOCAL_ConsultCapacity,
288 NULL)) {
289 Yap_ThrowError(RESOURCE_ERROR_HEAP, TermNil, LOCAL_ErrorMessage);
290 return;
291 }
292 }
293 new_cs = new_cl + InitialConsultCapacity;
294 /* start copying */
295 memcpy((void *)new_cs, (void *)LOCAL_ConsultLow,
296 OldConsultCapacity * sizeof(consult_obj));
297 /* copying done, release old space */
298 Yap_FreeCodeSpace((char *)LOCAL_ConsultLow);
299 /* next, set up pointers correctly */
300 new_cs += (LOCAL_ConsultSp - LOCAL_ConsultLow);
301 /* put LOCAL_ConsultBase at same offset as before move */
302 LOCAL_ConsultBase = new_cl + ((LOCAL_ConsultBase - LOCAL_ConsultLow) +
303 InitialConsultCapacity);
304 /* new consult pointer */
305 LOCAL_ConsultSp =
306 new_cl + ((LOCAL_ConsultSp - LOCAL_ConsultLow) + InitialConsultCapacity);
307 /* new end of memory */
308 LOCAL_ConsultLow = new_cl;
309}
310
311
312void Yap_ResetConsultStack(void) {
313 CACHE_REGS
314 while(LOCAL_consult_level) {
315 end_consult();
316 }
317 Yap_FreeCodeSpace((char *)LOCAL_ConsultLow);
318 LOCAL_ConsultBase = LOCAL_ConsultSp = LOCAL_ConsultLow = NULL;
319 LOCAL_ConsultCapacity = InitialConsultCapacity;
320}
321
322/* consult file *file*, *mode* may be one of either consult or reconsult */
323void Yap_init_consult(int mode, const char *filename, int sno, const char *encoding) {
324 CACHE_REGS
325 char dir[MAX_PATH + 1];
326 if (!LOCAL_ConsultSp) {
327 InitConsultStack();
328 }
329 if (LOCAL_ConsultSp >= LOCAL_ConsultLow + 6) {
330 expand_consult();
331 }
332 LOCAL_ConsultSp--;
333 LOCAL_ConsultSp->f_layer = Yap_AllocCodeSpace(sizeof(struct CONSULT_Layer));
334 if (filename)
335 LOCAL_ConsultSp->f_layer->f_name = (const unsigned char *)filename;
336 else
337 LOCAL_ConsultSp->f_layer->f_name = (const unsigned char *)"user_input";
338
339 LOCAL_ConsultSp->f_layer->sno = Yap_CheckAlias(AtomLoopStream);
340 if ( LOCAL_ConsultSp->f_layer->sno > 0) {
341 LOCAL_ConsultSp->f_layer->line = GLOBAL_Stream[LOCAL_ConsultSp->f_layer->sno].linecount;
342 } else {
343 LOCAL_ConsultSp->f_layer->line=0;
344 }
345 LOCAL_ConsultSp->f_layer->encoding = enc_id(encoding, GLOBAL_Stream[sno].encoding);
346 LOCAL_ConsultSp->f_layer->mode = mode;
347 LOCAL_ConsultSp->f_layer->c = (LOCAL_ConsultBase - LOCAL_ConsultSp);
348 LOCAL_ConsultSp->f_layer->m = LOCAL_SourceModule;
349 LOCAL_ConsultSp->f_layer->CompilationMode = getAtomicLocalPrologFlag(COMPILATION_MODE_FLAG);
350 LOCAL_ConsultSp->f_layer->must_be_module = false;
351 LOCAL_ConsultSp->f_layer->autoload = trueLocalPrologFlag(AUTOLOAD_FLAG);
352 LOCAL_ConsultSp->f_layer->silent = falseLocalPrologFlag(VERBOSE_LOAD_FLAG);
353 LOCAL_ConsultSp->f_layer->cwd = MkAtomTerm(Yap_LookupAtom(Yap_getcwd(dir, MAX_PATH)));
354 LOCAL_ConsultBase = LOCAL_ConsultSp;
355#if !defined(YAPOR) && !defined(YAPOR_SBA)
356/* if (LOCAL_consult_level == 0)
357 do_toggle_static_predicates_in_use(TRUE); */
358#endif
359 LOCAL_consult_level++;
360 LOCAL_LastAssertedPred = NULL;
361 Yap_AddAlias(AtomLoopStream, sno);
362 GLOBAL_Stream[sno].encoding = LOCAL_ConsultSp->f_layer->encoding;
363}
364
365static Int p_startconsult(USES_REGS1) { /* '$start_consult'(+Mode) */
366 Term t;
367 char *smode = RepAtom(AtomOfTerm(Deref(ARG1)))->StrOfAE;
368 int sno = Yap_CheckStream(Deref(ARG3),Input_Stream_f, " bad consult stream" );
369
370 const char *enc = RepAtom(AtomOfTerm(Deref(ARG4)))->StrOfAE;
371 int mode;
372 setBooleanLocalPrologFlag(COMPILING_FLAG, true);
373 mode = strcmp("consult", (char *)smode);
374 Yap_init_consult(mode, RepAtom(AtomOfTerm(Deref(ARG2)))->StrOfAE, sno, enc);
375 t = MkIntTerm(LOCAL_consult_level);
376 return (Yap_unify_constant(ARG5, t));
377}
378
379static Int p_showconslultlev(USES_REGS1) {
380 Term t;
381 if (LOCAL_consult_level < 0)
382 LOCAL_consult_level=0;
383 t = MkIntTerm(LOCAL_consult_level);
384 return (Yap_unify_constant(ARG1, t));
385}
386
387
388
389void Yap_end_consult(void) {
390 CACHE_REGS
391 end_consult(PASS_REGS1);
392}
393
394static Int p_endconsult(USES_REGS1) { /* '$end_consult' */
395 end_consult(PASS_REGS1);
396 return (TRUE);
397}
398
399
400static void purge_clauses(PredEntry *pred) {
401 if (pred->PredFlags & UDIPredFlag) {
402 Yap_udi_abolish(pred);
403 }
404 if (pred->cs.p_code.NOfClauses) {
405 if (pred->PredFlags & IndexedPredFlag)
406 Yap_RemoveIndexation(pred);
407 Yap_PutValue(AtomAbol, MkAtomTerm(AtomTrue));
408 retract_all(pred, Yap_static_in_use(pred, TRUE));
409 }
410}
411
412void Yap_Abolish(PredEntry *pred) {
413 purge_clauses(pred);
414 pred->src.OwnerFile = AtomNil;
415}
416
417
418bool Yap_discontiguous(PredEntry *ap, Term mode USES_REGS) {
419 register consult_obj *fp;
420
421 if (ap->PredFlags & (DiscontiguousPredFlag | MultiFileFlag) ||
422 falseGlobalPrologFlag(DISCONTIGUOUS_WARNINGS_FLAG))
423 return false;
424 if ((mode != TermConsult && mode != TermReconsult))
425 return false;
426 if (!LOCAL_ConsultSp) {
427 return false;
428 }
429
430 if (ap == LOCAL_LastAssertedPred)
431 return false;
432 if (ap->cs.p_code.NOfClauses) {
433 Term repeat = AbsPair((CELL *)AbsPredProp(ap));
434 for (fp = LOCAL_ConsultSp; fp < LOCAL_ConsultBase; ++fp)
435 if (fp->p == AbsPredProp(ap)) {
436 // detect repeated warnings
437 if (LOCAL_ConsultSp == LOCAL_ConsultLow + 1) {
438 expand_consult();
439 }
440 --LOCAL_ConsultSp;
441 LOCAL_ConsultSp->r = repeat;
442 return true;
443 } else if (fp->r == repeat && ap->cs.p_code.NOfClauses > 4) {
444 return false;
445 }
446 }
447 return false;
448}
449
450static Int get_must_be_module(USES_REGS1)
451{
452 return LOCAL_ConsultSp->f_layer->must_be_module;
453}
454
455
456static Int set_must_be_module(USES_REGS1)
457{
458 Term t = Deref(ARG1);
459 //must_be_boolean(t);
460 LOCAL_ConsultSp->f_layer->must_be_module = (t == TermTrue ||t == TermOn)
461 ;
462 return true;
463}
464
465static Int p_is_discontiguous(USES_REGS1) { /* '$is_multifile'(+S,+Mod) */
466 PredEntry *pe;
467 Int out;
468
469 pe = Yap_get_pred(Deref(ARG1), Deref(ARG2), "discontiguous");
470 if (EndOfPAEntr(pe))
471 return FALSE;
472 PELOCK(27, pe);
473 out = (pe->PredFlags & DiscontiguousPredFlag);
474 UNLOCKPE(44, pe);
475 return (out);
476}
477
478static Int
479 p_new_discontiguous(USES_REGS1) { /* '$new_discontiguous'(+N,+Ar,+Mod) */
480 Atom at;
481 int arity;
482 PredEntry *pe;
483 Term t = Deref(ARG1);
484 Term mod = Deref(ARG3);
485
486 if (IsVarTerm(t))
487 return false;
488 if (IsAtomTerm(t))
489 at = AtomOfTerm(t);
490 else
491 return false;
492 t = Deref(ARG2);
493 if (IsVarTerm(t))
494 return false;
495 if (IsIntTerm(t))
496 arity = IntOfTerm(t);
497 else
498 return false;
499 if (arity == 0)
500 pe = RepPredProp(PredPropByAtom(at, mod));
501 else
502 pe = RepPredProp(PredPropByFunc(Yap_MkFunctor(at, arity), mod));
503 PELOCK(26, pe);
504 pe->PredFlags |= DiscontiguousPredFlag;
505 /* mutifile-predicates are weird, they do not seat really on the default
506 * module */
507 if (pe->cs.p_code.NOfClauses == 0) {
508 pe->cs.p_code.TrueCodeOfPred = pe->CodeOfPred =
509 (yamop *)(&pe->OpcodeOfPred);
510 pe->OpcodeOfPred = FAIL_OPCODE;
511 }
512 UNLOCKPE(43, pe);
513 return (TRUE);
514}
515
516bool Yap_multiple(PredEntry *ap, Term mode USES_REGS) {
517 consult_obj *fp;
518
519 if ((ap->PredFlags & (MultiFileFlag | LogUpdatePredFlag | DynamicPredFlag)) ||
520 mode != TermReconsult)
521 return false;
522 if (LOCAL_consult_level == 0)
523 return false;
524 for (fp = LOCAL_ConsultSp; fp < LOCAL_ConsultBase; ++fp)
525 if (fp->p == AbsPredProp(ap)) {
526 return false;
527 }
528 return ap->cs.p_code.NOfClauses > 0 && ap->src.OwnerFile != AtomNil &&
529 Yap_ConsultingFile(PASS_REGS1) != ap->src.OwnerFile &&
530 LOCAL_Including != MkAtomTerm(ap->src.OwnerFile);
531}
532
533
534/* @pred '$new_multifile'(+G,+Mod)
535 * sets the multi-file flag
536 * */
537static Int new_multifile(USES_REGS1) {
538 PredEntry *pe;
539 Atom at;
540 arity_t arity;
541
542 pe = Yap_new_pred(Deref(ARG1), Deref(ARG2), false, "multifile");
543 if (EndOfPAEntr(pe))
544 return FALSE;
545 PELOCK(30, pe);
546 arity = pe->ArityOfPE;
547 if (arity == 0)
548 at = (Atom)pe->FunctorOfPred;
549 else
550 at = NameOfFunctor(pe->FunctorOfPred);
551
552 if (pe->PredFlags & MultiFileFlag) {
553 UNLOCKPE(26, pe);
554 return true;
555 }
556 if (pe->PredFlags & (TabledPredFlag | ForeignPredFlags)) {
557 UNLOCKPE(26, pe);
558 addcl_permission_error(RepAtom(at), arity, FALSE);
559 return false;
560 }
561 if (pe->cs.p_code.NOfClauses) {
562 UNLOCKPE(26, pe);
563 addcl_permission_error(RepAtom(at), arity, FALSE);
564 return false;
565 }
566 pe->PredFlags &= ~UndefPredFlag;
567 pe->PredFlags |= MultiFileFlag;
568 /* mutifile-predicates are weird, they do not seat really on the default
569 * module */
570 if (!(pe->PredFlags & (DynamicPredFlag | LogUpdatePredFlag))) {
571 /* static */
572 pe->PredFlags |= (SourcePredFlag | CompiledPredFlag);
573 }
574 pe->src.OwnerFile = Yap_ConsultingFile(PASS_REGS1);
575 if (pe->cs.p_code.NOfClauses == 0) {
576 pe->CodeOfPred = pe->cs.p_code.TrueCodeOfPred = FAILCODE;
577 pe->OpcodeOfPred = FAIL_OPCODE;
578 }
579 UNLOCKPE(43, pe);
580 return true;
581}
582
583static Int p_is_multifile(USES_REGS1) { /* '$is_multifile'(+S,+Mod) */
584 PredEntry *pe;
585 bool out;
586
587 pe = Yap_get_pred(Deref(ARG1), Deref(ARG2), "$is_multifile");
588 if (EndOfPAEntr(pe))
589 return FALSE;
590 PELOCK(27, pe);
591
592 out = (pe->PredFlags & MultiFileFlag);
593 UNLOCKPE(44, pe);
594 return (out);
595}
596
597
598static Int p_purge_clauses(USES_REGS1) { /* '$purge_clauses'(+Func) */
599 PredEntry *pred;
600 Term t = Deref(ARG1);
601 Term mod = Deref(ARG2);
602 MegaClause *before = DeadMegaClauses;
603
604 Yap_PutValue(AtomAbol, MkAtomTerm(AtomNil));
605 if (IsVarTerm(t))
606 return FALSE;
607 if (IsVarTerm(mod) || !IsAtomTerm(mod)) {
608 return FALSE;
609 }
610 if (IsAtomTerm(t)) {
611 Atom at = AtomOfTerm(t);
612 pred = RepPredProp(PredPropByAtom(at, mod));
613 } else if (IsApplTerm(t)) {
614 Functor fun = FunctorOfTerm(t);
615 pred = RepPredProp(PredPropByFunc(fun, mod));
616 } else
617 return (FALSE);
618 PELOCK(21, pred);
619 if (pred->PredFlags & StandardPredFlag) {
620 UNLOCKPE(33, pred);
621 Yap_Error(PERMISSION_ERROR_MODIFY_STATIC_PROCEDURE, t, "assert/1");
622 return (FALSE);
623 }
624 purge_clauses(pred);
625 UNLOCKPE(34, pred);
626 /* try to use the garbage collector to recover the mega clause,
627 in case the objs pointing to it are dead themselves */
628 if (DeadMegaClauses != before) {
629 gc_entry_info_t info;
630 Yap_track_cpred( 0, P, 0, &info);
631
632 if (!Yap_gc(&info)) {
633 Yap_Error(RESOURCE_ERROR_STACK, TermNil, LOCAL_ErrorMessage);
634 return FALSE;
635 }
636 }
637 return TRUE;
638}
639
640Int being_consulted(USES_REGS1)
641
642{
643 int lvl;
644 lvl =LOCAL_consult_level;
645 union CONSULT_OBJ *sp = LOCAL_ConsultSp, *base = LOCAL_ConsultBase;
646
647 while(lvl) {
648 int sno= Yap_CheckStream(Deref(ARG1),Input_Stream_f, " bad consult stream" );
649 sp = base;
650 if (sp==NULL) {
651 return false;
652 }
653 if(sno == sp->f_layer->sno ||
654 GLOBAL_Stream[sno].name ==
655 GLOBAL_Stream[sp->f_layer->sno].name)
656 return true; /* */
657 base = sp + sp->f_layer->c;
658 sp ++;
659 lvl --;
660 }
661 return false;
662}
663
664#if 0
665
666
667#define LOAD_FILES_DEFS( ) \
668 PAR("autoload", isatom, LOAD_FILES_AUTOLOAD ), \
669 PAR("derived_from", isatom, LOAD_FILES_DERIVED_FROM), \
670 PAR("encoding", isatom, LOAD_FILES_ENCODING), \
671 PAR("expand", booleanFlag, LOAD_FILES_EXPAND), \
672 PAR("if", booleanFlag, LOAD_FILES_IF), \
673 PAR("imports", ok, LOAD_FILES_IMPORTS), \
674 PAR("qcompile", booleanFlag, LOAD_FILES_QCOMPILE), \
675 PAR("file_errors", is_file_errors, LOAD_FILES_FILE_ERRORS), \
676 PAR("silent", booleanFlag, LOAD_FILES_SILENT), \
677 PAR("skip_unix_header", ok, LOAD_FILES_SKIP_UNIX_HEADER), \
678 PAR("compilation_mode", ok, LOAD_FILES_COMPILATION_MODE), \
679 PAR("consult", isatom, LOAD_FILES_CONSULT), \
680 PAR("stream", ok, LOAD_FILES_STREAM), \
681 PAR("dialect", isatom, LOAD_FILES_DIALECT) , \
682 PAR("redefine_module", booleanFlag, LOAD_FILES_REDEFINE_MODULE), \
683 PAR("reexport", ok, LOAD_FILES_REEXPORT), \
684 PAR("must_be_module", booleanFlag, LOAD_FILES_MUST_BE_MODULE), \
685 PAR("initialization", ok, LOAD_FILES_INITIALIZATION), \
686 PAR(NULL, ok, LOAD_FILES_END)
687
688#define PAR(x, y, z) z
689
690typedef enum LOAD_FILES_enum_ {
691 LOAD_FILES_DEFS()
692} load_files_choices_t;
693
694#undef PAR
695
696#define PAR(x, y, z) \
697 { x, y, z }
698
699static const param_t load_files_search_defs[] = {
700 LOAD_FILES_DEFS()};
701#undef PAR
702
703static Int load_files_parameters(USES_REGS1) {
704 Term tlist = Deref(ARG1), tf;
705 /* get options */
706 xarg *args = Malloc(sizeof(xarg)*LOAD_FILES_END);
707 memset(args, 0, sizeof(xarg)*LOAD_FILES_END);
708 args = Yap_ArgListToVector(tlist, load_files_search_defs,
709 LOAD_FILES_END,args,
710 DOMAIN_ERROR_LOAD_FILES_OPTION);
711 if (args == NULL) {
712 if (LOCAL_Error_TYPE != YAP_NO_ERROR) {
713 Yap_Error(LOCAL_Error_TYPE, tlist, NULL);
714 }
715 return false;
716 }
717 /* done */
718 if (args[LOAD_FILES_AUTOLOAD].used) {
719 setBooleanLocalPrologFlag(LOAD_FILES_AUTOLOAD,
720 args[LOAD_FILES_AUTOLOAD].tvalue);
721 }
722 Term toProlog[11];
723 if (args[LOAD_FILES_DERIVED_FROM].used) {
725 toProlog[0] = args[LOAD_FILES_DERIVED_FROM].tvalue;
726 } else {
727 toProlog[0] = TermNil;
728 }
729 if (args[LOAD_FILES_EXPAND].used) {
730 toProlog[1] = args[LOAD_FILES_EXPAND].tvalue;
731 } else {
732 toProlog[1] = TermFalse;
733 }
734 if (args[LOAD_FILES_IF].used) {
735 toProlog[2] = args[LOAD_FILES_IF].tvalue;
736 } else {
737 toProlog[2] = TermTrue;
738 }
739 if (args[LOAD_FILES_IMPORTS].used) {
740 toProlog[3] = args[LOAD_FILES_IMPORTS].tvalue;
741 } else {
742 toProlog[3] = TermAll;
743 }
744 if (args[LOAD_FILES_QCOMPILE].used) {
745 toProlog[4] = args[LOAD_FILES_QCOMPILE].tvalue;
746 } else {
747 toProlog[4] = TermFalse;
748 }
749 if (args[LOAD_FILES_SILENT].used) {
750 Term v;
751 if (args[LOAD_FILES_SILENT].tvalue == TermTrue)
752 v=TermFalse;
753 else if (args[LOAD_FILES_SILENT].tvalue == TermFalse)
754 v=TermTrue;
755 else
756 Yap_ThrowError(TYPE_ERROR_BOOLEAN,args[LOAD_FILES_SILENT].tvalue,NULL);
757 setBooleanLocalPrologFlag(VERBOSE_LOAD_FLAG,v);
758 }
759 if (args[LOAD_FILES_SKIP_UNIX_HEADER].used) {
760 toProlog[4] = args[LOAD_FILES_SKIP_UNIX_HEADER].tvalue;
761 } else {
762 toProlog[4] = TermFalse;
763 }
764 if (args[LOAD_FILES_SKIP_UNIX_HEADER].used) {
765 toProlog[4] = args[LOAD_FILES_SKIP_UNIX_HEADER].tvalue;
766 } else {
767 toProlog[4] = TermFalse;
768 }
769 if (args[LOAD_FILES_COMPILATION_MODE].used) {
770 Term v;
771 if (args[LOAD_FILES_COMPILATION_MODE].tvalue == TermSource)
772 v=TermTrue;
773 else if (args[LOAD_FILES_COMPILATION_MODE].tvalue == TermCompact)
774 v=TermFalse;
775 else
776 Yap_ThrowError(TYPE_ERROR_BOOLEAN,args[LOAD_FILES_COMPILATION_MODE].tvalue,NULL);
777 setBooleanLocalPrologFlag(SOURCE_FLAG,v);
778 }
779 if (args[LOAD_FILES_CONSULT].used) {
780 toProlog[5] = args[LOAD_FILES_CONSULT].tvalue;
781 } else {
782 toProlog[5] = TermReconsult;
783 }
784 if (args[LOAD_FILES_STREAM].used) {
785 toProlog[6] = args[LOAD_FILES_STREAM].tvalue;
786 } else {
787 toProlog[6] = MkVarTerm();
788 }
789 if (args[LOAD_FILES_DIALECT].used) {
790 setAtomicLocalPrologFlag(DIALECT_FLAG,
791 args[LOAD_FILES_DIALECT].tvalue);
792 }
793 if (args[LOAD_FILES_REDEFINE_MODULE].used) {
794 toProlog[7] = args[LOAD_FILES_REDEFINE_MODULE].tvalue;
795 } else {
796 toProlog[7] = TermSource;
797 }
798 if (args[LOAD_FILES_REEXPORT].used) {
799 toProlog[8] = args[LOAD_FILES_REEXPORT].tvalue;
800 } else {
801 toProlog[8] = TermTrue;
802 }
803 if (args[LOAD_FILES_MUST_BE_MODULE].used) {
804 toProlog[9] = args[LOAD_FILES_MUST_BE_MODULE].tvalue;
805 } else {
806 toProlog[9] = TermTrue;
807 }
808 if (args[LOAD_FILES_INITIALIZATION].used) {
809 toProlog[10] = args[LOAD_FILES_INITIALIZATION].tvalue;
810 } else {
811 toProlog[10] = TermTrue;
812 }
813 tf = Yap_MkApplTerm(Yap_MkFunctor(AtomDot,11),11,toProlog);
814 return (Yap_unify(ARG2, tf));
815 }
816
817static Int get_load_files_parameter(USES_REGS1) {
818 Term t = Deref(ARG1), topts = Deref(ARG2);
819 /* get options */
820 /* done */
821 int i = Yap_ArgKey(AtomOfTerm(t), load_files_search_defs,
822 LOAD_FILES_END);
823 if (i >= 0)
824 return Yap_unify(ARG3, ArgOfTerm(i + 1, topts));
825 Yap_Error(DOMAIN_ERROR_LOAD_FILES_OPTION, ARG1, NULL);
826 return false;
827}
828#endif
829
830void Yap_InitConsult(void) {
831 CACHE_REGS
832 Yap_InitCPred("$purge_clauses", 2, p_purge_clauses,
833 SafePredFlag | SyncPredFlag);
834 Yap_InitCPred("$new_multifile", 2, new_multifile,
835
836 SafePredFlag | SyncPredFlag | HiddenPredFlag);
837 Yap_InitCPred("$is_multifile", 2, p_is_multifile,
838 TestPredFlag | SafePredFlag);
839 Yap_InitCPred("$new_discontiguous", 3, p_new_discontiguous,
840 SafePredFlag | SyncPredFlag);
841 Yap_InitCPred("$is_discontiguous", 2, p_is_discontiguous,
842 TestPredFlag | SafePredFlag);
843 Yap_InitCPred("$start_consult", 5, p_startconsult,
844 SafePredFlag | SyncPredFlag);
845 Yap_InitCPred("$show_consult_level", 1, p_showconslultlev, SafePredFlag);
846 Yap_InitCPred("$end_consult", 0, p_endconsult,
847 SafePredFlag | SyncPredFlag);
848 Yap_InitCPred("$parent_source_module", 1, parent_source_module,
849 SafePredFlag | SyncPredFlag);
850 Yap_InitCPred("$parent_stream_line", 1, parent_stream_line,
851 SafePredFlag | SyncPredFlag);
852 Yap_InitCPred("$parent_stream_file", 1, parent_stream_file,
853 SafePredFlag | SyncPredFlag);
854 Yap_InitCPred("$grandparent_source_module", 1, grandparent_source_module,
855 SafePredFlag | SyncPredFlag);
856 Yap_InitCPred("$get_must_be_module", 0, get_must_be_module,
857 SafePredFlag | SyncPredFlag);
858 Yap_InitCPred("$set_must_be_module", 1, set_must_be_module,
859 SafePredFlag | SyncPredFlag);
860 Yap_InitCPred("$being_consulted", 1, being_consulted,
861 SafePredFlag | SyncPredFlag);
862 // Yap_InitCPred("$load_files_parameters", 2, load_files_parameters, HiddenPredFlag);
863 // Yap_InitCPred("$lf_opt__", 3, get_load_files_parameter, HiddenPredFlag|SafePredFlag);
864}
Main definitions.
int Yap_ArgKey(Atom key, const param_t *def, int n)
Returns the index of an argument key, or -1 if not found.
Definition: args.c:42
void * Malloc(size_t sz USES_REGS)
allocate a temporary text block
Definition: alloc.c:1759
@ encoding
support for coding systens, YAP relies on UTF-8 internally
Definition: YapLFlagInfo.h:83
Definition: heapgc.h:272
A matrix.
Definition: matrix.c:68
Definition: Yatom.h:544
Definition: YapFlags.h:152
Definition: amidefs.h:264