1 /*-----------------------------------------------------------------------
2
3 File : cte_termbanks.c
4
5 Author: Stephan Schulz
6
7 Contents
8
9 Functions for term banks (efficient dag-representations for term
10 sets).
11
12 Bindings (i.e. values in term->binding) make only sense in dynamical
13 contexts, not in (mostly) static term banks. Thus, bindings are
14 followed whenever a term is treated as an individual term, but not
15 when they form part of a term bank and are manipulated as such.
16
17 Copyright 1998-2011 by the author.
18 This code is released under the GNU General Public Licence and
19 the GNU Lesser General Public License.
20 See the file COPYING in the main E directory for details..
21 Run "eprover -h" for contact information.
22
23 Changes
24
25 <1> Sat Nov 15 16:26:30 MET 1997
26 New
27 <2> Fri Oct 2 20:35:41 MET DST 1998
28 Variables are now longer in the term trees and have lost superterm
29 information -> 20% Speedup!
30 <3> You cannot take references for variables anymore. This requires
31 that no variables are ever replaced (but this is a requirement
32 anyways), but deals with a strange bug (and may speed up the code
33 even more).
34 <4> Sat Apr 6 21:42:35 CEST 2002
35 Changed for new rewriting. No Superterms anymore! References are
36 fully passive. Deletion does not work any more, I'm working on a
37 mark-and-sweep garbage collector for terms instead.
38
39 -----------------------------------------------------------------------*/
40
41 #include "cte_termbanks.h"
42 #include "cte_typecheck.h"
43
44
45
46 /*---------------------------------------------------------------------*/
47 /* Global Variables */
48 /*---------------------------------------------------------------------*/
49
50 bool TBPrintInternalInfo = false; /* Print internal information about
51 term nodes, e.g. the flag field */
52 bool TBPrintDetails = false; /* Collect potentially expensive
53 information (number of nodes,
54 number of unshared nodes, size of
55 various sub-data structures) and
56 print them if required */
57
58
59 /*---------------------------------------------------------------------*/
60 /* Forward Declarations */
61 /*---------------------------------------------------------------------*/
62
63
64 /*---------------------------------------------------------------------*/
65 /* Internal Functions */
66 /*---------------------------------------------------------------------*/
67
68 /*-----------------------------------------------------------------------
69 //
70 // Function: tb_print_dag()
71 //
72 // Print the terms as a dag in the order of insertion.
73 //
74 // Global Variables: TBPrintInternalInfo
75 //
76 // Side Effects : Output
77 //
78 /----------------------------------------------------------------------*/
79
tb_print_dag(FILE * out,NumTree_p in_index,Sig_p sig)80 static void tb_print_dag(FILE *out, NumTree_p in_index, Sig_p sig)
81 {
82 Term_p term;
83
84 if(!in_index)
85 {
86 return;
87 }
88 tb_print_dag(out, in_index->lson, sig);
89 term = in_index->val1.p_val;
90 fprintf(out, "*%ld : ", term->entry_no);
91
92 if(TermIsVar(term))
93 {
94 VarPrint(out, term->f_code);
95 }
96 else
97 {
98 fputs(SigFindName(sig, term->f_code), out);
99 if(!TermIsConst(term))
100 {
101 int i;
102
103 assert(term->arity>=1);
104 assert(term->args);
105 putc('(', out);
106
107 fprintf(out, "*%ld", TBCellIdent(term->args[0]));
108 for(i=1; i<term->arity; i++)
109 {
110 putc(',', out);
111 fprintf(out, "*%ld", TBCellIdent(term->args[i]));
112 }
113 putc(')', out);
114 }
115 printf(" = ");
116 TermPrint(out, term, sig, DEREF_NEVER);
117 }
118 if(TBPrintInternalInfo)
119 {
120 fprintf(out, "\t/* Properties: %10d */",
121 term->properties);
122 }
123 fprintf(out, "\n");
124 tb_print_dag(out, in_index->rson, sig);
125 }
126
127 /*-----------------------------------------------------------------------
128 //
129 // Function: tb_termtop_insert()
130 //
131 // Insert a term into the term bank for which the subterms are
132 // already in the term bank. Will reuse or destroy the top cell!
133 //
134 // Global Variables: TBSupportReplace
135 //
136 // Side Effects : Changes term bank
137 //
138 /----------------------------------------------------------------------*/
139
tb_termtop_insert(TB_p bank,Term_p t)140 static Term_p tb_termtop_insert(TB_p bank, Term_p t)
141 {
142 Term_p new;
143
144 assert(t);
145 assert(!TermIsVar(t));
146
147 /* Infer the sort of this term (may be temporary) */
148 if(t->sort == STNoSort)
149 {
150 TypeInferSort(bank->sig, t);
151 assert(t->sort != STNoSort);
152 }
153 bank->insertions++;
154
155 new = TermCellStoreInsert(&(bank->term_store), t);
156
157 if(new) /* Term node already existed, just add properties */
158 {
159 new->properties = (new->properties | t->properties)/*& bank->prop_mask*/;
160 TermTopFree(t);
161 return new;
162 }
163 else
164 {
165 t->entry_no = ++(bank->in_count);
166 TermCellAssignProp(t,TPGarbageFlag, bank->garbage_state);
167 TermCellSetProp(t, TPIsShared); /* Groundness may change below */
168 t->v_count = 0;
169 t->f_count = 1;
170 t->weight = DEFAULT_FWEIGHT;
171 for(int i=0; i<t->arity; i++)
172 {
173 assert(TermIsShared(t->args[i])||TermIsVar(t->args[i]));
174 if(TermIsVar(t->args[i]))
175 {
176 t->v_count += 1;
177 t->weight += DEFAULT_VWEIGHT;
178 }
179 else
180 {
181 t->v_count +=t->args[i]->v_count;
182 t->f_count +=t->args[i]->f_count;
183 t->weight +=t->args[i]->weight;
184 }
185 }
186
187 if(t->v_count == 0)
188 {
189 TermCellSetProp(t, TPIsGround);
190 }
191
192 assert(TermWeight(t, DEFAULT_VWEIGHT, DEFAULT_FWEIGHT) == TermWeightCompute(t, DEFAULT_VWEIGHT, DEFAULT_FWEIGHT));
193 assert((t->v_count == 0) == TermIsGround(t));
194 //assert(TermIsGround(t) == TermIsGroundCompute(t));
195 }
196 return t;
197 }
198
199
200 /*-----------------------------------------------------------------------
201 //
202 // Function: tb_parse_cons_list()
203 //
204 // Parse a LOP list into an (shared) internal $cons list.
205 //
206 // Global Variables: -
207 //
208 // Side Effects : Input, Memory operations
209 //
210 /----------------------------------------------------------------------*/
211
tb_parse_cons_list(Scanner_p in,TB_p bank,bool check_symb_prop)212 static Term_p tb_parse_cons_list(Scanner_p in, TB_p bank, bool check_symb_prop)
213 {
214 Term_p handle;
215 Term_p current;
216 PStack_p stack;
217
218 assert(SigSupportLists);
219
220 stack = PStackAlloc();
221 AcceptInpTok(in, OpenSquare);
222
223 handle = TermDefaultCellAlloc();
224 current = handle;
225
226 if(!TestInpTok(in, CloseSquare))
227 {
228
229 current->f_code = SIG_CONS_CODE;
230 current->arity = 2;
231 current->args = TermArgArrayAlloc(2);
232 current->args[0] = TBTermParseReal(in, bank, check_symb_prop);
233 current->args[1] = TermDefaultCellAlloc();
234 current = current->args[1];
235 PStackPushP(stack, current);
236
237 while(TestInpTok(in, Comma))
238 {
239 NextToken(in);
240 current->f_code = SIG_CONS_CODE;
241 current->arity = 2;
242 current->args = TermArgArrayAlloc(2);
243 current->args[0] = TBTermParseReal(in, bank, check_symb_prop);
244 current->args[1] = TermDefaultCellAlloc();
245 current = current->args[1];
246 PStackPushP(stack, current);
247 }
248 current = PStackPopP(stack);
249 }
250 AcceptInpTok(in, CloseSquare);
251 current->f_code = SIG_NIL_CODE;
252
253 /* Now insert the list into the bank */
254 handle = TBInsert(bank, current, DEREF_NEVER);
255
256 while(!PStackEmpty(stack))
257 {
258 current = PStackPopP(stack);
259 current->args[1] = handle;
260 handle = tb_termtop_insert(bank, current);
261 }
262
263 PStackFree(stack);
264 return handle;
265 }
266
267
268 /*-----------------------------------------------------------------------
269 //
270 // Function: tb_subterm_parse()
271 //
272 // Parse a subterm, i.e. a term which cannot start with a predicate
273 // symbol.
274 //
275 // Global Variables: -
276 //
277 // Side Effects : Input, memory operations, changes termbank.
278 //
279 /----------------------------------------------------------------------*/
280
tb_subterm_parse(Scanner_p in,TB_p bank)281 static Term_p tb_subterm_parse(Scanner_p in, TB_p bank)
282 {
283 Term_p res = TBTermParseReal(in, bank, true);
284
285 if(!TermIsVar(res))
286 {
287 if(SigIsPredicate(bank->sig, res->f_code))
288 {
289 if(SigIsFixedType(bank->sig, res->f_code))
290 {
291 AktTokenError(in,
292 "Predicate used as function symbol in preceeding term",
293 SYNTAX_ERROR);
294 }
295 else
296 {
297 SigDeclareIsFunction(bank->sig, res->f_code);
298 TypeInferSort(bank->sig, res);
299 assert(res->sort != STNoSort);
300 }
301 }
302 }
303 return res;
304 }
305
306
307
308
309
310
311 /*-----------------------------------------------------------------------
312 //
313 // Function: tb_term_parse_arglist()
314 //
315 // Parse a list of terms (comma-separated and enclosed in brackets)
316 // into an array of (shared) term pointers. See TermParseArgList()
317 // in cte_terms.c for more.
318 //
319 // Global Variables: -
320 //
321 // Side Effects : Input, memory operations, changes term bank
322 //
323 /----------------------------------------------------------------------*/
324
tb_term_parse_arglist(Scanner_p in,Term_p ** arg_anchor,TB_p bank,bool check_symb_prop)325 static int tb_term_parse_arglist(Scanner_p in, Term_p** arg_anchor,
326 TB_p bank, bool check_symb_prop)
327 {
328 Term_p *handle, tmp;
329 int arity;
330 int size;
331 int i;
332
333 AcceptInpTok(in, OpenBracket);
334 if(TestInpTok(in, CloseBracket))
335 {
336 NextToken(in);
337 *arg_anchor = NULL;
338 return 0;
339 }
340 size = TERMS_INITIAL_ARGS;
341 handle = (Term_p*)SizeMalloc(size*sizeof(Term_p));
342 arity = 0;
343 tmp = check_symb_prop?
344 tb_subterm_parse(in, bank):
345 TBRawTermParse(in,bank);
346
347 handle[arity] = tmp;
348 arity++;
349 while(TestInpTok(in, Comma))
350 {
351 NextToken(in);
352 if(arity==size)
353 {
354 size+=TERMS_INITIAL_ARGS;
355 handle = (Term_p*)SecureRealloc(handle, size*sizeof(Term_p));
356 }
357 handle[arity] = check_symb_prop?
358 tb_subterm_parse(in, bank):
359 TBRawTermParse(in,bank);
360 arity++;
361 }
362 AcceptInpTok(in, CloseBracket);
363 *arg_anchor = TermArgArrayAlloc(arity);
364 for(i=0;i<arity;i++)
365 {
366 (*arg_anchor)[i] = handle[i];
367 }
368 SizeFree(handle, size*sizeof(Term_p));
369
370 return arity;
371 }
372
373
374
375
376
377 /*---------------------------------------------------------------------*/
378 /* Exported Functions */
379 /*---------------------------------------------------------------------*/
380
381 /*-----------------------------------------------------------------------
382 //
383 // Function: TBAlloc()
384 //
385 // Allocate an empty, initialized termbank.
386 //
387 // Global Variables: -
388 //
389 // Side Effects : Memory operations
390 //
391 /----------------------------------------------------------------------*/
392
TBAlloc(Sig_p sig)393 TB_p TBAlloc(Sig_p sig)
394 {
395 TB_p handle;
396 Term_p term;
397
398 assert(sig);
399
400 handle = TBCellAlloc();
401
402 handle->in_count = 0;
403 handle->insertions = 0;
404 handle->rewrite_steps = 0;
405 handle->ext_index = PDIntArrayAlloc(1,100000);
406 handle->garbage_state = TPIgnoreProps;
407 handle->sig = sig;
408 handle->vars = VarBankAlloc(sig->sort_table);
409 TermCellStoreInit(&(handle->term_store));
410
411 term = TermConstCellAlloc(SIG_TRUE_CODE);
412 term->sort = STBool;
413 TermCellSetProp(term, TPPredPos);
414 handle->true_term = TBInsert(handle, term, DEREF_NEVER);
415 TermFree(term);
416 term = TermConstCellAlloc(SIG_FALSE_CODE);
417 term->sort = STBool;
418 TermCellSetProp(term, TPPredPos);
419 handle->false_term = TBInsert(handle, term, DEREF_NEVER);
420 TermFree(term);
421 handle->min_term = NULL;
422 handle->freevarsets = NULL;
423 return handle;
424 }
425
426
427 /*-----------------------------------------------------------------------
428 //
429 // Function: TBFree()
430 //
431 // Free a term bank (if the signature alread has been
432 // extracted). Voids all pointers to terms in the bank!
433 //
434 // Global Variables: -
435 //
436 // Side Effects : Memory operations.
437 //
438 /----------------------------------------------------------------------*/
439
TBFree(TB_p junk)440 void TBFree(TB_p junk)
441 {
442 assert(!junk->sig);
443
444 /* printf("TBFree(): %ld\n", TermCellStoreNodes(&(junk->term_store)));
445 */
446 TermCellStoreExit(&(junk->term_store));
447 PDArrayFree(junk->ext_index);
448 VarBankFree(junk->vars);
449
450 assert(!junk->freevarsets);
451 TBCellFree(junk);
452 }
453
454 /*-----------------------------------------------------------------------
455 //
456 // Function: TBVarSetStoreFree()
457 //
458 // Free and reset the VarSetStore in bank.
459 //
460 // Global Variables: -
461 //
462 // Side Effects : -
463 //
464 /----------------------------------------------------------------------*/
465
TBVarSetStoreFree(TB_p bank)466 void TBVarSetStoreFree(TB_p bank)
467 {
468 VarSetStoreFree(bank->freevarsets);
469 bank->freevarsets = NULL;
470 }
471
472
473 /*-----------------------------------------------------------------------
474 //
475 // Function: TBTermNodes()
476 //
477 // Return the number of term nodes (variables and non-variables) in
478 // the term bank.
479 //
480 // Global Variables: -
481 //
482 // Side Effects : -
483 //
484 /----------------------------------------------------------------------*/
485
TBTermNodes(TB_p bank)486 long TBTermNodes(TB_p bank)
487 {
488 assert(TermCellStoreNodes(&(bank->term_store))==
489 TermCellStoreCountNodes(&(bank->term_store)));
490 return TermCellStoreNodes(&(bank->term_store))+VarBankCardinal(bank->vars);
491 }
492
493
494 /*-----------------------------------------------------------------------
495 //
496 // Function: TBInsert()
497 //
498 // Insert the term into the termbank. The original term will remain
499 // untouched. The routine returns a pointer to a new, shared term of
500 // the same structure.
501 //
502 // TermProperties are masked with bank->prop_mask.
503 //
504 // Global Variables: -
505 //
506 // Side Effects : Changes term bank
507 //
508 /----------------------------------------------------------------------*/
509
TBInsert(TB_p bank,Term_p term,DerefType deref)510 Term_p TBInsert(TB_p bank, Term_p term, DerefType deref)
511 {
512 int i;
513 Term_p t;
514
515 assert(term);
516
517 term = TermDeref(term, &deref);
518
519 if(TermIsVar(term))
520 {
521 t = VarBankVarAssertAlloc(bank->vars, term->f_code, term->sort);
522 }
523 else
524 {
525 t = TermTopCopyWithoutArgs(term); /* This is an unshared term cell at the moment */
526
527 assert(SysDateIsCreationDate(t->rw_data.nf_date[0]));
528 assert(SysDateIsCreationDate(t->rw_data.nf_date[1]));
529
530 for(i=0; i<t->arity; i++)
531 {
532 t->args[i] = TBInsert(bank, term->args[i], deref);
533 }
534 t = tb_termtop_insert(bank, t);
535 }
536 return t;
537 }
538
539 /*-----------------------------------------------------------------------
540 //
541 // Function: TBInsertNoProps()
542 //
543 // As TBInsert, but will set all properties of the new term to 0
544 // first.
545 //
546 // Global Variables: TBSupportReplace
547 //
548 // Side Effects : Changes term bank
549 //
550 /----------------------------------------------------------------------*/
551
TBInsertNoProps(TB_p bank,Term_p term,DerefType deref)552 Term_p TBInsertNoProps(TB_p bank, Term_p term, DerefType deref)
553 {
554 int i;
555 Term_p t;
556
557 assert(term);
558
559 term = TermDeref(term, &deref);
560
561 if(TermIsVar(term))
562 {
563 t = VarBankVarAssertAlloc(bank->vars, term->f_code, term->sort);
564 }
565 else
566 {
567 t = TermTopCopyWithoutArgs(term); /* This is an unshared term cell at the moment */
568 t->properties = TPIgnoreProps;
569
570 assert(SysDateIsCreationDate(t->rw_data.nf_date[0]));
571 assert(SysDateIsCreationDate(t->rw_data.nf_date[1]));
572
573 for(i=0; i<t->arity; i++)
574 {
575 t->args[i] = TBInsertNoProps(bank, term->args[i], deref);
576 }
577 t = tb_termtop_insert(bank, t);
578 }
579 return t;
580 }
581
582
583 /*-----------------------------------------------------------------------
584 //
585 // Function: TBInsertRepl()
586 //
587 // As TBInsertNoProps, but when old is encountered as a subterm
588 // (regardless of instantiation), replace it with uninstantiated
589 // repl (which _must_ be in bank).
590 //
591 // Global Variables: -
592 //
593 // Side Effects : -
594 //
595 /----------------------------------------------------------------------*/
596
TBInsertRepl(TB_p bank,Term_p term,DerefType deref,Term_p old,Term_p repl)597 Term_p TBInsertRepl(TB_p bank, Term_p term, DerefType deref, Term_p old, Term_p repl)
598 {
599 int i;
600 Term_p t;
601
602 assert(term);
603
604 if(term == old)
605 {
606 assert(TBFind(bank, repl));
607 return repl;
608 }
609
610 term = TermDeref(term, &deref);
611
612 if(TermIsVar(term))
613 {
614 t = VarBankVarAssertAlloc(bank->vars, term->f_code, term->sort);
615 }
616 else
617 {
618 t = TermTopCopyWithoutArgs(term); /* This is an unshared term cell at the moment */
619 t->properties = TPIgnoreProps;
620
621 assert(SysDateIsCreationDate(t->rw_data.nf_date[0]));
622 assert(SysDateIsCreationDate(t->rw_data.nf_date[1]));
623
624 for(i=0; i<t->arity; i++)
625 {
626 t->args[i] = TBInsertRepl(bank, term->args[i], deref, old, repl);
627 }
628 t = tb_termtop_insert(bank, t);
629 }
630 return t;
631 }
632
633
634 /*-----------------------------------------------------------------------
635 //
636 // Function: TBInsertInstantiated()
637 //
638 // Insert a term into the termbank under the assumption that it is a
639 // right side of a rule (or equation) composed of terms from bank,
640 // and (possibly) instantiated with terms from bank - i.e. don't
641 // insert terms that are bound to variables and ground terms, but
642 // assume that they are in the term bank. Properties in newly
643 // created nodes are deleted.
644 //
645 // Global Variables: TBSupportReplace
646 //
647 // Side Effects : Changes term bank
648 //
649 /----------------------------------------------------------------------*/
650
TBInsertInstantiated(TB_p bank,Term_p term)651 Term_p TBInsertInstantiated(TB_p bank, Term_p term)
652 {
653 int i;
654 Term_p t;
655
656 assert(term);
657
658 if(TermIsGround(term))
659 {
660 assert(TBFind(bank, term));
661 return term;
662 }
663
664 if(term->binding)
665 {
666 assert(TBFind(bank, term->binding));
667 return term->binding;
668 }
669
670 if(TermIsVar(term))
671 {
672 t = VarBankVarAssertAlloc(bank->vars, term->f_code, term->sort);
673 }
674 else
675 {
676 t = TermTopCopyWithoutArgs(term); /* This is an unshared term cell at the moment */
677 t->properties = TPIgnoreProps;
678
679 assert(SysDateIsCreationDate(t->rw_data.nf_date[0]));
680 assert(SysDateIsCreationDate(t->rw_data.nf_date[1]));
681
682 for(i=0; i<t->arity; i++)
683 {
684 t->args[i] = TBInsertInstantiated(bank, term->args[i]);
685 }
686 t = tb_termtop_insert(bank, t);
687 }
688 return t;
689 }
690
691
692
693 /*-----------------------------------------------------------------------
694 //
695 // Function: TBInsertOpt()
696 //
697 // Insert term into bank under the assumption that it it already is
698 // in the bank (except possibly for variables appearing as
699 // bindings). This allows us to just return term for ground terms.
700 //
701 // Global Variables: -
702 //
703 // Side Effects : Changes term bank.
704 //
705 /----------------------------------------------------------------------*/
706
TBInsertOpt(TB_p bank,Term_p term,DerefType deref)707 Term_p TBInsertOpt(TB_p bank, Term_p term, DerefType deref)
708 {
709 int i;
710 Term_p t;
711
712 assert(term);
713
714 term = TermDeref(term, &deref);
715
716 if(TermIsGround(term))
717 {
718 return term;
719 }
720
721 if(TermIsVar(term))
722 {
723 t = VarBankVarAssertAlloc(bank->vars, term->f_code, term->sort);
724 }
725 else
726 {
727 t = TermTopCopyWithoutArgs(term); /* This is an unshared term cell at the moment */
728
729 assert(SysDateIsCreationDate(t->rw_data.nf_date[0]));
730 assert(SysDateIsCreationDate(t->rw_data.nf_date[1]));
731
732 for(i=0; i<t->arity; i++)
733 {
734 t->args[i] = TBInsertOpt(bank, term->args[i], deref);
735 }
736 t = tb_termtop_insert(bank, t);
737 }
738 return t;
739 }
740
741
742 /*-----------------------------------------------------------------------
743 //
744 // Function: TBInsertDisjoint()
745 //
746 // Create a copy of (uninstantiated) term with disjoint
747 // variables. This assumes that all variables in term are odd or
748 // even, the returned copy will have variable ids shifted by -1.
749 //
750 // Global Variables: -
751 //
752 // Side Effects : Changes bank.
753 //
754 /----------------------------------------------------------------------*/
755
TBInsertDisjoint(TB_p bank,Term_p term)756 Term_p TBInsertDisjoint(TB_p bank, Term_p term)
757 {
758 int i;
759 Term_p t;
760
761 assert(term);
762
763
764 if(TermIsGround(term))
765 {
766 return term;
767 }
768
769 if(TermIsVar(term))
770 {
771 t = VarBankVarAssertAlloc(bank->vars, term->f_code+1, term->sort);
772 }
773 else
774 {
775 t = TermTopCopyWithoutArgs(term); /* This is an unshared term cell at the moment */
776
777 assert(SysDateIsCreationDate(t->rw_data.nf_date[0]));
778 assert(SysDateIsCreationDate(t->rw_data.nf_date[1]));
779
780 for(i=0; i<t->arity; i++)
781 {
782 t->args[i] = TBInsertDisjoint(bank, term->args[i]);
783 }
784 t = tb_termtop_insert(bank, t);
785 }
786 return t;
787 }
788
789
790
791 /*-----------------------------------------------------------------------
792 //
793 // Function: TBTermTopInsert()
794 //
795 // See tb_termtop_insert, for export without hurting inlining
796 // capabilities.
797 //
798 // Global Variables: -
799 //
800 // Side Effects : Changes bank
801 //
802 /----------------------------------------------------------------------*/
803
TBTermTopInsert(TB_p bank,Term_p t)804 Term_p TBTermTopInsert(TB_p bank, Term_p t)
805 {
806 return tb_termtop_insert(bank,t);
807 }
808
809
810 /*-----------------------------------------------------------------------
811 //
812 // Function: TBAllocNewSkolem()
813 //
814 // Create a news Skolem term (or definition atom) with the given
815 // variables in the term bank and return the pointer to it.
816 //
817 // Global Variables:
818 //
819 // Side Effects :
820 //
821 /----------------------------------------------------------------------*/
822
TBAllocNewSkolem(TB_p bank,PStack_p variables,SortType sort)823 Term_p TBAllocNewSkolem(TB_p bank, PStack_p variables, SortType sort)
824 {
825 Term_p handle, res;
826
827 handle = TermAllocNewSkolem(bank->sig, variables, sort);
828 res = TBInsert(bank, handle, DEREF_NEVER);
829 TermFree(handle);
830
831 return res;
832 }
833
834
835 /*-----------------------------------------------------------------------
836 //
837 // Function: TBFind()
838 //
839 // Find a term in the term cell bank and return it.
840 //
841 // Global Variables: -
842 //
843 // Side Effects : -
844 //
845 /----------------------------------------------------------------------*/
846
TBFind(TB_p bank,Term_p term)847 Term_p TBFind(TB_p bank, Term_p term)
848 {
849 if(TermIsVar(term))
850 {
851 return VarBankFCodeFind(bank->vars, term->f_code, term->sort);
852 }
853 return TermCellStoreFind(&(bank->term_store), term);
854 }
855
856
857 /*-----------------------------------------------------------------------
858 //
859 // Function: TBPrintBankInOrder()
860 //
861 // Print the DAG in the order of ascending entry_no.
862 //
863 // Global Variables: TBPrintTermsFlat
864 //
865 // Side Effects : Output
866 //
867 /----------------------------------------------------------------------*/
868
TBPrintBankInOrder(FILE * out,TB_p bank)869 void TBPrintBankInOrder(FILE* out, TB_p bank)
870 {
871 NumTree_p tree = NULL;
872 long i;
873 PStack_p stack;
874 Term_p cell;
875 IntOrP dummy;
876
877 for(i=0; i<TERM_STORE_HASH_SIZE; i++)
878 {
879 stack = TermTreeTraverseInit(bank->term_store.store[i]);
880 while((cell = TermTreeTraverseNext(stack)))
881 {
882 dummy.p_val = cell;
883 NumTreeStore(&tree, cell->entry_no,dummy, dummy);
884 }
885 TermTreeTraverseExit(stack);
886 }
887 tb_print_dag(out, tree, bank->sig);
888 NumTreeFree(tree);
889 }
890
891 /*-----------------------------------------------------------------------
892 //
893 // Function: TBPrintTermCompact()
894 //
895 // Print a term bank term. Introduce abbreviations for all subterms
896 // encountered. Subterms with TPOutputFlag are not
897 // printed, but are assumed to be known. Does _not_ follow bindings
898 // (they are temporary and as such make little sense in the term
899 // bank context)
900 //
901 // Global Variables: -
902 //
903 // Side Effects : Output, set TPOutputFlag in subterms printed with
904 // abbreviation.
905 //
906 /----------------------------------------------------------------------*/
907
TBPrintTermCompact(FILE * out,TB_p bank,Term_p term)908 void TBPrintTermCompact(FILE* out, TB_p bank, Term_p term)
909 {
910 int i;
911
912 if(TermCellQueryProp(term, TPOutputFlag))
913 {
914 fprintf(out, "*%ld", term->entry_no);
915 }
916 else
917 {
918 if(TermIsVar(term))
919 {
920 VarPrint(out, term->f_code);
921 }
922 else
923 {
924 fprintf(out, "*%ld:", term->entry_no);
925 TermCellSetProp(term, TPOutputFlag);
926 fputs(SigFindName(bank->sig, term->f_code), out);
927 if(!TermIsConst(term))
928 {
929 fputc('(',out);
930 assert(term->args && (term->arity>0));
931 TBPrintTermCompact(out, bank, term->args[0]);
932 for(i=1;i<term->arity;i++)
933 {
934 fputc(',', out);
935 TBPrintTermCompact(out, bank, term->args[i]);
936 }
937 fputc(')',out);
938 }
939 }
940 }
941 }
942
943
944 /*-----------------------------------------------------------------------
945 //
946 // Function: TBPrintTerm()
947 //
948 // Print a term from a term bank either in compact form (with
949 // abbreviations) or as a conventional term.
950 //
951 // Global Variables: -
952 //
953 // Side Effects : By the called functions
954 //
955 /----------------------------------------------------------------------*/
956
TBPrintTerm(FILE * out,TB_p bank,Term_p term,bool fullterms)957 void TBPrintTerm(FILE* out, TB_p bank, Term_p term, bool fullterms)
958 {
959 if(fullterms)
960 {
961 TBPrintTermFull(out, bank, term);
962 }
963 else
964 {
965 TBPrintTermCompact(out, bank, term);
966 }
967 }
968
969
970
971 /*-----------------------------------------------------------------------
972 //
973 // Function: TBPrintBankTerms()
974 //
975 // Print the terms inserted into the term bank with abbreviations.
976 //
977 // Global Variables: -
978 //
979 // Side Effects : Output, changes by TBPrintTermCompact()
980 //
981 /----------------------------------------------------------------------*/
982
TBPrintBankTerms(FILE * out,TB_p bank)983 void TBPrintBankTerms(FILE* out, TB_p bank)
984 {
985 PStack_p stack = PStackAlloc();
986 Term_p term;
987 int i;
988
989 for(i=0; i<TERM_STORE_HASH_SIZE; i++)
990 {
991 PStackPushP(stack, bank->term_store.store[i]);
992
993 while(!PStackEmpty(stack))
994 {
995 term = PStackPopP(stack);
996 if(term)
997 {
998 PStackPushP(stack, term->lson);
999 PStackPushP(stack, term->rson);
1000 if(TermCellQueryProp(term, TPTopPos))
1001 {
1002 TBPrintTermCompact(out, bank, term);
1003 fprintf(out, "\n");
1004 }
1005 }
1006 }
1007 }
1008 PStackFree(stack);
1009 }
1010
1011
1012 /*-----------------------------------------------------------------------
1013 //
1014 // Function: TBTermParseReal()
1015 //
1016 // Parse a term from the given scanner object directly into the
1017 // termbank. Supports abbreviations. This function will _not_ set
1018 // the TPTopPos property on top terms while parsing. It will or will
1019 // not check and set symbol properties (function symbol, predicate
1020 // symbol), depending on the check_symb_prop parameter.
1021 //
1022 // Global Variables: -
1023 //
1024 // Side Effects : Input, memory operations, changes termbank.
1025 //
1026 /----------------------------------------------------------------------*/
1027
TBTermParseReal(Scanner_p in,TB_p bank,bool check_symb_prop)1028 Term_p TBTermParseReal(Scanner_p in, TB_p bank, bool check_symb_prop)
1029 {
1030 Term_p handle;
1031 DStr_p id;
1032 FuncSymbType id_type;
1033 DStr_p source_name, errpos;
1034 SortType sort;
1035 long line, column;
1036 StreamType type;
1037
1038 source_name = DStrGetRef(AktToken(in)->source);
1039 type = AktToken(in)->stream_type;
1040 line = AktToken(in)->line;
1041 column = AktToken(in)->column;
1042
1043 /* Test for abbreviation */
1044 if(TestInpTok(in, Mult))
1045 {
1046 long abbrev;
1047 TermProperties properties = TPIgnoreProps;
1048
1049 NextToken(in);
1050 abbrev = ParseInt(in);
1051
1052 if(TestInpTok(in, Colon|Slash))
1053 { /* This _defines_ the abbrev! */
1054 if(PDArrayElementP(bank->ext_index, abbrev))
1055 {
1056 /* Error: Abbreviation defined twice */
1057 errpos = DStrAlloc();
1058 DStrAppendStr(errpos, PosRep(type, source_name, line, column));
1059 DStrAppendStr(errpos, "Abbreviation *");
1060 DStrAppendInt(errpos, abbrev);
1061 DStrAppendStr(errpos, " already defined");
1062 Error(DStrView(errpos), SYNTAX_ERROR);
1063 DStrFree(errpos);
1064 }
1065 if(TestInpTok(in, Slash))
1066 {
1067 NextToken(in);
1068 properties = ParseInt(in);
1069 }
1070 NextToken(in);
1071 handle = TBTermParseReal(in, bank, check_symb_prop); /* Elegant, aint it? */
1072
1073 if(properties)
1074 {
1075 TBRefSetProp(bank, &handle, properties);
1076 }
1077 /* printf("# Term %ld = %ld\n", abbrev, handle->entry_no); */
1078 PDArrayAssignP(bank->ext_index, abbrev, handle);
1079 }
1080 else
1081 { /* This references the abbrev */
1082
1083 handle = PDArrayElementP(bank->ext_index, abbrev);
1084 if(!handle)
1085 {
1086 /* Error: Undefined abbrev */
1087 errpos = DStrAlloc();
1088 DStrAppendStr(errpos, PosRep(type, source_name, line, column));
1089 DStrAppendStr(errpos, "Abbreviation *");
1090 DStrAppendInt(errpos, abbrev);
1091 DStrAppendStr(errpos, " undefined");
1092 Error(DStrView(errpos), SYNTAX_ERROR);
1093 DStrFree(errpos);
1094 }
1095 }
1096 }
1097 else
1098 {
1099 /* Normal term stuff, bloated because of the nonsensical SETHEO
1100 syntax */
1101
1102 if(SigSupportLists && TestInpTok(in, OpenSquare))
1103 {
1104 handle = tb_parse_cons_list(in, bank, check_symb_prop);
1105 }
1106 else
1107 {
1108 id = DStrAlloc();
1109
1110 if((id_type=TermParseOperator(in, id))==FSIdentVar)
1111 {
1112 /* A variable may be annotated with a sort */
1113 if(TestInpTok(in, Colon))
1114 {
1115 AcceptInpTok(in, Colon);
1116 sort = SortParseTSTP(in, bank->sig->sort_table);
1117 handle = VarBankExtNameAssertAllocSort(bank->vars,
1118 DStrView(id), sort);
1119 }
1120 else
1121 {
1122 handle = VarBankExtNameAssertAlloc(bank->vars, DStrView(id));
1123 }
1124 }
1125 else
1126 {
1127 handle = TermDefaultCellAlloc();
1128
1129 if(TestInpTok(in, OpenBracket))
1130 {
1131 if((id_type == FSIdentInt)
1132 &&(bank->sig->distinct_props & FPIsInteger))
1133 {
1134 AktTokenError(in,
1135 "Number cannot have argument list "
1136 "(consider --free-numbers)",
1137 false);
1138 }
1139 if((id_type == FSIdentFloat)
1140 &&(bank->sig->distinct_props & FPIsFloat))
1141 {
1142 AktTokenError(in,
1143 "Floating point number cannot have argument list "
1144 "(consider --free-numbers)",
1145 false);
1146 }
1147 if((id_type == FSIdentRational)
1148 &&(bank->sig->distinct_props & FPIsRational))
1149 {
1150 AktTokenError(in,
1151 "Rational number cannot have argument list "
1152 "(consider --free-numbers)",
1153 false);
1154 }
1155 if((id_type == FSIdentObject)
1156 &&(bank->sig->distinct_props & FPIsObject))
1157 {
1158 AktTokenError(in,
1159 "Object cannot have argument list "
1160 "(consider --free-objects)",
1161 false);
1162 }
1163
1164 handle->arity = tb_term_parse_arglist(in, &(handle->args),
1165 bank, check_symb_prop);
1166 }
1167 else
1168 {
1169 handle->arity = 0;
1170 }
1171 handle->f_code = TermSigInsert(bank->sig, DStrView(id),
1172 handle->arity, false, id_type);
1173 if(!handle->f_code)
1174 {
1175 errpos = DStrAlloc();
1176 DStrAppendStr(errpos, PosRep(type, source_name, line, column));
1177 DStrAppendStr(errpos, DStrView(id));
1178 DStrAppendStr(errpos, " used with arity ");
1179 DStrAppendInt(errpos, (long)handle->arity);
1180 DStrAppendStr(errpos, ", but registered with arity ");
1181 DStrAppendInt(errpos,
1182 (long)(bank->sig)->
1183 f_info[SigFindFCode(bank->sig, DStrView(id))].arity);
1184 Error(DStrView(errpos), SYNTAX_ERROR);
1185 DStrFree(errpos);
1186 }
1187 handle = tb_termtop_insert(bank, handle);
1188 }
1189 DStrFree(id);
1190 }
1191 }
1192 DStrReleaseRef(source_name);
1193
1194 return handle;
1195 }
1196
1197
1198
1199
1200 /*-----------------------------------------------------------------------
1201 //
1202 // Function: TBRefSetProp()
1203 //
1204 // Make ref point to a term of the same structure as *ref, but with
1205 // properties prop set. Properties do not work for variables!
1206 //
1207 // Global Variables: -
1208 //
1209 // Side Effects : Changes bank, *ref
1210 //
1211 /----------------------------------------------------------------------*/
1212
TBRefSetProp(TB_p bank,TermRef ref,TermProperties prop)1213 void TBRefSetProp(TB_p bank, TermRef ref, TermProperties prop)
1214 {
1215 Term_p term, new;
1216
1217 assert(!TermIsVar(*ref));
1218
1219 term = *ref;
1220 if(TermCellQueryProp(term, prop)||TermIsVar(term))
1221 {
1222 return;
1223 }
1224
1225 new = TermTopCopy(term);
1226 TermCellSetProp(new, prop);
1227 new = tb_termtop_insert(bank, new);
1228 *ref = new;
1229 /* Old term will be garbage-collected eventually */
1230 }
1231
1232
1233
1234 /*-----------------------------------------------------------------------
1235 //
1236 // Function: TBRefDelProp()
1237 //
1238 // Make ref point to a term of the same structure as *ref, but with
1239 // properties prop deleted. If the term is a variable, do nothing!
1240 //
1241 // Global Variables: -
1242 //
1243 // Side Effects : Changes bank, *ref
1244 //
1245 /----------------------------------------------------------------------*/
1246
TBRefDelProp(TB_p bank,TermRef ref,TermProperties prop)1247 void TBRefDelProp(TB_p bank, TermRef ref, TermProperties prop)
1248 {
1249 Term_p term, new;
1250
1251 term = *ref;
1252 if(!TermCellIsAnyPropSet(term, prop)||TermIsVar(term))
1253 {
1254 return;
1255 }
1256 new = TermTopCopy(term);
1257 TermCellDelProp(new, prop);
1258 new = tb_termtop_insert(bank, new);
1259 *ref = new;
1260 }
1261
1262
1263 /*-----------------------------------------------------------------------
1264 //
1265 // Function: TBTermDelPropCount()
1266 //
1267 // Delete properties prop in term, return number of term cells with
1268 // this property. Does assume that all subterms of a term without
1269 // this property also do not carry it!
1270 //
1271 // Global Variables:
1272 //
1273 // Side Effects :
1274 //
1275 /----------------------------------------------------------------------*/
1276
TBTermDelPropCount(Term_p term,TermProperties prop)1277 long TBTermDelPropCount(Term_p term, TermProperties prop)
1278 {
1279 long count = 0;
1280 int i;
1281 PStack_p stack = PStackAlloc();
1282
1283 PStackPushP(stack, term);
1284 while(!PStackEmpty(stack))
1285 {
1286 term = PStackPopP(stack);
1287 if(TermCellQueryProp(term, prop))
1288 {
1289 TermCellDelProp(term, prop);
1290 count++;
1291 for(i=0; i<term->arity; i++)
1292 {
1293 PStackPushP(stack, term->args[i]);
1294 }
1295 }
1296 }
1297 PStackFree(stack);
1298 return count;
1299 }
1300
1301
1302 /*-----------------------------------------------------------------------
1303 //
1304 // Function: TBGCMarkTerm()
1305 //
1306 // Mark a term as used for the garbage collector.
1307 //
1308 // Global Variables: -
1309 //
1310 // Side Effects : Marks the term, memory operations
1311 //
1312 /----------------------------------------------------------------------*/
1313
TBGCMarkTerm(TB_p bank,Term_p term)1314 void TBGCMarkTerm(TB_p bank, Term_p term)
1315 {
1316 PStack_p stack = PStackAlloc();
1317 int i;
1318
1319 assert(bank);
1320 assert(term);
1321
1322 PStackPushP(stack, term);
1323 while(!PStackEmpty(stack))
1324 {
1325 term = PStackPopP(stack);
1326 if(!TBTermCellIsMarked(bank,term))
1327 {
1328 TermCellFlipProp(term, TPGarbageFlag);
1329 for(i=0; i<term->arity; i++)
1330 {
1331 PStackPushP(stack, term->args[i]);
1332 }
1333 if(TermIsRewritten(term))
1334 {
1335 PStackPushP(stack, TermRWReplaceField(term));
1336 }
1337 }
1338 }
1339 PStackFree(stack);
1340 }
1341
1342
1343 /*-----------------------------------------------------------------------
1344 //
1345 // Function: TBGCSweep()
1346 //
1347 // Sweep the term bank and free all unmarked term
1348 // cells. bank->true_term will be marked automatically. Returns the
1349 // number of term cells recovered.
1350 //
1351 // Global Variables: -
1352 //
1353 // Side Effects : Memory operations, flips bank->garbage_state
1354 //
1355 /----------------------------------------------------------------------*/
1356
TBGCSweep(TB_p bank)1357 long TBGCSweep(TB_p bank)
1358 {
1359 long recovered = 0;
1360
1361 assert(bank);
1362 assert(!TermIsRewritten(bank->true_term));
1363 TBGCMarkTerm(bank, bank->true_term);
1364 TBGCMarkTerm(bank, bank->false_term);
1365 if(bank->min_term)
1366 {
1367 TBGCMarkTerm(bank, bank->min_term);
1368 }
1369
1370 VERBOUT("Garbage collection started.\n");
1371 recovered = TermCellStoreGCSweep(&(bank->term_store),
1372 bank->garbage_state);
1373 VERBOSE(fprintf(stderr, "Garbage collection reclaimed %ld unused term cells.\n",recovered););
1374 /* #ifdef PRINT_SOMEERRORS_STDOUT */
1375 #ifdef NEVER_DEFINED
1376 if(OutputLevel)
1377 {
1378 fprintf(GlobalOut,
1379 "# Garbage collection reclaimed %ld unused term cells.\n",
1380 recovered);
1381 }
1382 #endif
1383 bank->garbage_state =
1384 bank->garbage_state?TPIgnoreProps:TPGarbageFlag;
1385
1386 return recovered;
1387 }
1388
1389
1390 /*-----------------------------------------------------------------------
1391 //
1392 // Function: TBCreateMinTerm()
1393 //
1394 // If bank->min_term exists, return it. Otherwise create and return
1395 // it.
1396 //
1397 // Global Variables: -
1398 //
1399 // Side Effects : Might set bank->min_term
1400 //
1401 /----------------------------------------------------------------------*/
1402
TBCreateMinTerm(TB_p bank,FunCode min_const)1403 Term_p TBCreateMinTerm(TB_p bank, FunCode min_const)
1404 {
1405 if(!bank->min_term)
1406 {
1407 Term_p t = TermConstCellAlloc(min_const);
1408 bank->min_term = TBInsert(bank, t, DEREF_NEVER);
1409 TermFree(t);
1410 }
1411 assert(bank->min_term->f_code == min_const);
1412 return bank->min_term;
1413 }
1414
1415
1416 /*-----------------------------------------------------------------------
1417 //
1418 // Function: TBTermCollectSubterms()
1419 //
1420 // Collect all subterms of term onto collector. Assumes that
1421 // TPOpFlag is set if and only if the term is already in the
1422 // collection. Returns the number of new terms found.
1423 //
1424 // Global Variables: -
1425 //
1426 // Side Effects : Sets the OpFlag of newly collected terms.
1427 //
1428 /----------------------------------------------------------------------*/
1429
TBTermCollectSubterms(Term_p term,PStack_p collector)1430 long TBTermCollectSubterms(Term_p term, PStack_p collector)
1431 {
1432 long res = 0;
1433 int i;
1434
1435 assert(term);
1436 assert(TermIsShared(term));
1437
1438 if(!TermCellQueryProp(term, TPOpFlag))
1439 {
1440 res = 1;
1441 TermCellSetProp(term, TPOpFlag);
1442 PStackPushP(collector, term);
1443 for(i=0; i<term->arity; i++)
1444 {
1445 res += TBTermCollectSubterms(term->args[i], collector);
1446 }
1447 }
1448 return res;
1449 }
1450
1451
1452 /*---------------------------------------------------------------------*/
1453 /* End of File */
1454 /*---------------------------------------------------------------------*/
1455