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