1 /*-----------------------------------------------------------------------
2 
3 File  : cte_termfunc.c
4 
5 Author: Stephan Schulz
6 
7 Contents
8 
9   Most of the user-level functionality for unshared terms.
10 
11   Copyright 1998, 1999 by the author.
12   This code is released under the GNU General Public Licence and
13   the GNU Lesser General Public License.
14   See the file COPYING in the main E directory for details..
15   Run "eprover -h" for contact information.
16 
17 Changes
18 
19 <1> Wed Feb 25 16:50:36 MET 1998
20     Ripped from cte_terms.c (should be obsolete by now)
21 
22 -----------------------------------------------------------------------*/
23 
24 
25 #include "cte_termfunc.h"
26 #include "cte_typecheck.h"
27 #include "clb_plocalstacks.h"
28 
29 
30 /*---------------------------------------------------------------------*/
31 /*                        Global Variables                             */
32 /*---------------------------------------------------------------------*/
33 
34 bool      TermPrintLists = true;
35 bool      TermPrintTypes = false;
36 
37 /*---------------------------------------------------------------------*/
38 /*                      Forward Declarations                           */
39 /*---------------------------------------------------------------------*/
40 
41 
42 /*---------------------------------------------------------------------*/
43 /*                         Internal Functions                          */
44 /*---------------------------------------------------------------------*/
45 
46 
47 /*-----------------------------------------------------------------------
48 //
49 // Function: print_cons_list()
50 //
51 //   Print a list of $cons'ed terms, terminated with $nil. Abort on
52 //   not well-formed lists (no cons pairs!).
53 //
54 // Global Variables: -
55 //
56 // Side Effects    : Output
57 //
58 /----------------------------------------------------------------------*/
59 
print_cons_list(FILE * out,Term_p list,Sig_p sig,DerefType deref)60 static void print_cons_list(FILE* out, Term_p list, Sig_p sig, DerefType deref)
61 {
62    assert(SigSupportLists);
63    putc('[', out);
64    if(list->f_code == SIG_CONS_CODE)
65    {
66       assert(list->args);
67       TermPrint(out, list->args[0], sig, deref);
68       list = list->args[1];
69       while(list->f_code == SIG_CONS_CODE)
70       {
71          putc(',', out);
72          /* putc(' ', out); */
73          assert(list->args);
74          TermPrint(out, list->args[0], sig, deref);
75          list = list->args[1];
76       }
77       assert(list->f_code == SIG_NIL_CODE);
78    }
79    putc(']', out);
80 }
81 
82 
83 /*-----------------------------------------------------------------------
84 //
85 // Function: parse_cons_list()
86 //
87 //   Parse a LOP list into an internal $cons list.
88 //
89 // Global Variables: -
90 //
91 // Side Effects    : Input, Memory operations
92 //
93 /----------------------------------------------------------------------*/
94 
parse_cons_list(Scanner_p in,Sig_p sig,VarBank_p vars)95 static Term_p parse_cons_list(Scanner_p in, Sig_p sig, VarBank_p vars)
96 {
97    Term_p handle;
98    Term_p current;
99 
100    assert(SigSupportLists);
101 
102    AcceptInpTok(in, OpenSquare);
103 
104    handle = TermDefaultCellAlloc();
105 
106    current = handle;
107 
108    if(!TestInpTok(in, CloseSquare))
109    {
110 
111       current->f_code = SIG_CONS_CODE;
112       current->arity = 2;
113       current->sort = SigDefaultSort(sig);
114       current->args = TermArgArrayAlloc(2);
115       current->args[0] = TermParse(in, sig, vars);
116       current->args[1] = TermDefaultCellAlloc();
117       current = current->args[1];
118 
119       while(TestInpTok(in, Comma))
120       {
121          NextToken(in);
122          current->f_code = SIG_CONS_CODE;
123          current->arity = 2;
124          current->sort = SigDefaultSort(sig);
125          current->args = TermArgArrayAlloc(2);
126          current->args[0] = TermParse(in, sig, vars);
127          TermCellDelProp(current->args[0], TPTopPos);
128          current->args[1] = TermDefaultCellAlloc();
129          current = current->args[1];
130       }
131    }
132    AcceptInpTok(in, CloseSquare);
133    current->f_code = SIG_NIL_CODE;
134 
135    return handle;
136 }
137 
138 /*-----------------------------------------------------------------------
139 //
140 // Function: term_check_consistency_rek()
141 //
142 //   Traverse a tree and check if any one term cell occurs more than
143 //   once on any branch (which would make the term cyclic). Return the
144 //   first inconsistency found or NULL.
145 //
146 // Global Variables: -
147 //
148 // Side Effects    : Memory operations
149 //
150 /----------------------------------------------------------------------*/
151 
term_check_consistency_rek(Term_p term,PTree_p * branch,DerefType deref)152 static Term_p term_check_consistency_rek(Term_p term, PTree_p *branch,
153                                          DerefType deref)
154 {
155    int      i;
156    Term_p   res = NULL;
157 
158    term = TermDeref(term, &deref);
159    putc('.', stdout);
160 
161    if(!PTreeStore(branch, term))
162    {
163       return term;
164    }
165    for(i=0; i<term->arity; i++)
166    {
167       if((res = term_check_consistency_rek(term->args[i], branch, deref)))
168       {
169          break;
170       }
171    }
172    PTreeDeleteEntry(branch, term);
173    return res;
174 }
175 
176 
177 /*---------------------------------------------------------------------*/
178 /*                         Exported Functions                          */
179 /*---------------------------------------------------------------------*/
180 
181 
182 /*-----------------------------------------------------------------------
183 //
184 // Function: VarPrint()
185 //
186 //   Print a variable with FunCode var out.
187 //
188 // Global Variables: -
189 //
190 // Side Effects    : Output
191 //
192 /----------------------------------------------------------------------*/
193 
VarPrint(FILE * out,FunCode var)194 void VarPrint(FILE* out, FunCode var)
195 {
196    char id;
197 
198    assert(var<0);
199 
200    id = 'X';
201    if(var%2)
202    {
203       id = 'Y';
204    }
205    fprintf(out, "%c%ld", id, -((var-1)/2));
206 }
207 
208 
209 /*-----------------------------------------------------------------------
210 //
211 // Function: TermPrint()
212 //
213 //   Print a term to the given stream.
214 //
215 // Global Variables: TermPrintLists
216 //
217 // Side Effects    : Output
218 //
219 /----------------------------------------------------------------------*/
220 
TermPrint(FILE * out,Term_p term,Sig_p sig,DerefType deref)221 void TermPrint(FILE* out, Term_p term, Sig_p sig, DerefType deref)
222 {
223    assert(term);
224    assert(sig||TermIsVar(term));
225 
226    term = TermDeref(term, &deref);
227 
228 #ifdef NEVER_DEFINED
229    if(TermCellQueryProp(term, TPRestricted))
230    {
231       fprintf(out, "*");
232    }
233    if(TermCellQueryProp(term, TPIsRewritten))
234    {
235       if(TermIsTopRewritten(term))
236       {
237          fprintf(out, "=");
238       }
239       else
240       {
241          fprintf(out, "+");
242       }
243    }
244 #endif
245    if(SigSupportLists && TermPrintLists &&
246       ((term->f_code == SIG_NIL_CODE)||
247        (term->f_code == SIG_CONS_CODE)))
248    {
249       print_cons_list(out, term, sig, deref);
250    }
251    else
252    {
253       if(TermIsVar(term))
254       {
255          VarPrint(out, term->f_code);
256       }
257       else
258       {
259          fputs(SigFindName(sig, term->f_code), out);
260          if(!TermIsConst(term))
261          {
262             assert(term->args);
263             TermPrintArgList(out, term->args, term->arity, sig, deref);
264          }
265       }
266    }
267 
268    if(TermPrintTypes)
269    {
270       fputc(':', out);
271       SortPrintTSTP(out, sig->sort_table, term->sort);
272    }
273 }
274 
275 
276 /*--------------------------------------------------------------------
277 //
278 // Function: TermPrintArgList()
279 //
280 //   Print an argument list (i.e. an array with at least one term
281 //   element) to the given stream.
282 //
283 // Global Variables: -
284 //
285 // Side Effects    : Output
286 //
287 /----------------------------------------------------------------------*/
288 
TermPrintArgList(FILE * out,Term_p * args,int arity,Sig_p sig,DerefType deref)289 void TermPrintArgList(FILE* out, Term_p *args, int arity, Sig_p sig,
290                       DerefType deref)
291 {
292    int i;
293 
294    assert(arity>=1);
295    putc('(', out);
296 
297    TermPrint(out, args[0], sig, deref);
298 
299    for(i=1; i<arity; i++)
300    {
301       putc(',', out);
302       /* putc(' ', out); */
303       TermPrint(out, args[i], sig, deref);
304    }
305    putc(')', out);
306 }
307 
308 
309 /*-----------------------------------------------------------------------
310 //
311 // Function: TermParseOperator()
312 //
313 //   Parse an operator (i.e. an optional $, followed by an
314 //   identifier), store the representation into id and determine
315 //   the type.using the following rules:
316 //   - If it starts with a $, it's a TermIdentInterpreted (LOP global
317 //     variables are treated as interpreted constants).
318 //   - If it is a PosInt, it is a TermIdentNumber
319 //   - If its a String, it is a TermIdentObject
320 //   - If it is an upper-case or underscore Ident and no opening
321 //     bracket follows, its a TermIdentVariable
322 //   - Otherwise its a free function symbol (cases are SQString and
323 //     Identifier starting with lower-case letter.
324 //
325 //   Return value is the type
326 //
327 // Global Variables: SigIdentStartToken
328 //
329 // Side Effects    : Read input
330 //
331 /----------------------------------------------------------------------*/
332 
TermParseOperator(Scanner_p in,DStr_p id)333 FuncSymbType TermParseOperator(Scanner_p in, DStr_p id)
334 {
335    FuncSymbType res = FuncSymbParse(in, id);
336 
337 #ifndef STRICT_TPTP
338    if((isupper(DStrView(id)[0])
339        ||
340        (DStrView(id)[0] == '_'))
341       &&
342       TestInpTok(in,OpenBracket))
343    {
344       res = FSIdentFreeFun;
345    }
346 #endif
347 
348    return res;
349 }
350 
351 /*-----------------------------------------------------------------------
352 //
353 // Function: TermSigInsert()
354 //
355 //   Thin wrapper around SigInsertId that also sets corresponding
356 //   properties for different identifier types.
357 //
358 // Global Variables: -
359 //
360 // Side Effects    : -
361 //
362 /----------------------------------------------------------------------*/
363 
TermSigInsert(Sig_p sig,const char * name,int arity,bool special_id,FuncSymbType type)364 FunCode TermSigInsert(Sig_p sig, const char* name, int arity, bool
365                       special_id, FuncSymbType type)
366 {
367    FunCode res;
368 
369    res = SigInsertId(sig, name, arity, special_id);
370    switch(type)
371    {
372    case FSIdentInt:
373          SigSetFuncProp(sig, res, FPIsInteger);
374          break;
375    case FSIdentFloat:
376          SigSetFuncProp(sig, res, FPIsFloat);
377          break;
378    case FSIdentRational:
379          SigSetFuncProp(sig, res, FPIsRational);
380          break;
381    case FSIdentObject:
382          SigSetFuncProp(sig, res, FPIsObject);
383          break;
384    case FSIdentInterpreted:
385          SigSetFuncProp(sig, res, FPInterpreted);
386          break;
387    default:
388          /* Nothing */
389          break;
390    }
391    return res;
392 }
393 
394 
395 /*-----------------------------------------------------------------------
396 //
397 // Function: TermParse()
398 //
399 //   Parse a term from the given scanner object into the internal term
400 //   representation.
401 //
402 // Global Variables: -
403 //
404 // Side Effects    : Input, memory operations, may extend signature
405 //
406 /----------------------------------------------------------------------*/
407 
TermParse(Scanner_p in,Sig_p sig,VarBank_p vars)408 Term_p TermParse(Scanner_p in, Sig_p sig, VarBank_p vars)
409 {
410    Term_p        handle;
411    DStr_p        id;
412    FuncSymbType id_type;
413    DStr_p        source_name, errpos;
414    SortType      sort;
415    long          line, column;
416    StreamType    type;
417 
418    if(SigSupportLists && TestInpTok(in, OpenSquare))
419    {
420       handle =  parse_cons_list(in, sig, vars);
421    }
422    else
423    {
424       id = DStrAlloc();
425       line = AktToken(in)->line;
426       column = AktToken(in)->column;
427       source_name = DStrGetRef(AktToken(in)->source);
428       type = AktToken(in)->stream_type;
429 
430       if((id_type = TermParseOperator(in, id))==FSIdentVar)
431       {
432          /* A variable may be annotated with a sort */
433          if(TestInpTok(in, Colon))
434          {
435             AcceptInpTok(in, Colon);
436             sort = SortParseTSTP(in, vars->sort_table);
437             handle = VarBankExtNameAssertAllocSort(vars,
438                                                    DStrView(id), sort);
439          }
440          else
441          {
442             handle = VarBankExtNameAssertAlloc(vars, DStrView(id));
443          }
444       }
445       else
446       {
447          handle = TermDefaultCellAlloc();
448 
449          if(TestInpTok(in, OpenBracket))
450          {
451             if((id_type == FSIdentInt)
452                &&(sig->distinct_props & FPIsInteger))
453             {
454                AktTokenError(in,
455                              "Number cannot have argument list (consider --free-numbers)",
456                              false);
457             }
458             if((id_type == FSIdentObject)
459                &&(sig->distinct_props & FPIsObject))
460             {
461                AktTokenError(in,
462                              "Object cannot have argument list (consider --free-objects)",
463                              false);
464             }
465 
466             handle->arity = TermParseArgList(in, &(handle->args), sig,
467                                              vars);
468          }
469          else
470          {
471             handle->arity = 0;
472          }
473          handle->f_code = TermSigInsert(sig, DStrView(id),
474                                         handle->arity, false, id_type);
475          if(!handle->f_code)
476          {
477             errpos = DStrAlloc();
478 
479             DStrAppendStr(errpos, PosRep(type, source_name, line, column));
480             DStrAppendChar(errpos, ' ');
481             DStrAppendStr(errpos, DStrView(id));
482             DStrAppendStr(errpos, " used with arity ");
483             DStrAppendInt(errpos, (long)handle->arity);
484             DStrAppendStr(errpos, " but registered with arity ");
485             DStrAppendInt(errpos,
486                           (long)SigFindArity(sig, SigFindFCode(sig, DStrView(id))));
487             Error(DStrView(errpos), SYNTAX_ERROR);
488             DStrFree(errpos);
489          }
490       }
491       DStrReleaseRef(source_name);
492       DStrFree(id);
493    }
494    return handle;
495 }
496 
497 
498 /*-----------------------------------------------------------------------
499 //
500 // Function: TermParseArgList()
501 //
502 //   Parse a list of terms (comma-separated and enclosed in brackets)
503 //   into an array of term pointers. Return the number of terms
504 //   parsed, and make arg_anchor point to the array. Note: The array
505 //   has to have exactly the right size, as it will be handled by
506 //   Size[Malloc|Free] for efficiency reasons and may otherwise lead
507 //   to a memory leak. This leads to some complexity...
508 //   If the arglist is empty, return 0 and use the NULL pointer as
509 //   anchor.
510 //
511 // Global Variables: -
512 //
513 // Side Effects    : Input, memory operations
514 //
515 /----------------------------------------------------------------------*/
516 
TermParseArgList(Scanner_p in,Term_p ** arg_anchor,Sig_p sig,VarBank_p vars)517 int TermParseArgList(Scanner_p in, Term_p** arg_anchor, Sig_p sig,
518                      VarBank_p vars)
519 {
520    Term_p *handle;
521    int    arity;
522    int    size;
523    int    i;
524 
525    AcceptInpTok(in, OpenBracket);
526    if(TestInpTok(in, CloseBracket))
527    {
528       NextToken(in);
529       *arg_anchor = NULL;
530       return 0;
531    }
532    size = TERMS_INITIAL_ARGS;
533    handle = (Term_p*)SizeMalloc(size*sizeof(Term_p));
534    arity = 0;
535    handle[arity] = TermParse(in, sig, vars);
536    arity++;
537    while(TestInpTok(in, Comma))
538    {
539       NextToken(in);
540       if(arity==size)
541       {
542          size+=TERMS_INITIAL_ARGS;
543          handle = (Term_p*)SecureRealloc(handle, size*sizeof(Term_p));
544       }
545       handle[arity] = TermParse(in, sig, vars);
546       arity++;
547    }
548    AcceptInpTok(in, CloseBracket);
549    *arg_anchor = TermArgArrayAlloc(arity);
550    for(i=0;i<arity;i++)
551    {
552       (*arg_anchor)[i] = handle[i];
553    }
554    SizeFree(handle, size*sizeof(Term_p));
555 
556    return arity;
557 }
558 
559 
560 /*-----------------------------------------------------------------------
561 //
562 // Function: TermCopy()
563 //
564 //   Return a copy of a given term. The new term will be unshared
565 //   (except, of coure, for the variables) even if the original term
566 //   was shared. Variable cells will be allocated from the VarBank
567 //   given to the function.
568 //
569 // Global Variables: -
570 //
571 // Side Effects    : Memory operations
572 //
573 /----------------------------------------------------------------------*/
574 
TermCopy(Term_p source,VarBank_p vars,DerefType deref)575 Term_p TermCopy(Term_p source, VarBank_p vars, DerefType deref)
576 {
577    Term_p handle;
578    int i;
579 
580    assert(source);
581 
582    source = TermDeref(source, &deref);
583 
584    if(TermIsVar(source))
585    {
586       handle = VarBankVarAssertAlloc(vars, source->f_code, source->sort);
587    }
588    else
589    {
590       handle = TermTopCopyWithoutArgs(source);
591 
592       for(i=0; i<handle->arity; i++)
593       {
594          handle->args[i] = TermCopy(source->args[i], vars, deref);
595       }
596    }
597 
598    return handle;
599 }
600 
601 
602 /*-----------------------------------------------------------------------
603 //
604 // Function: TermCopyKeepVars()
605 //
606 //   Return a copy of a given term. The new term will be unshared
607 //   (except, of coure, for the variables) even if the original term
608 //   was shared. Variable cells will not be copied. Note that printing
609 //   such a term might be confusing, since two variables with the same
610 //   f_code may indeed be different!
611 //
612 // Global Variables: -
613 //
614 // Side Effects    : Memory operations
615 //
616 /----------------------------------------------------------------------*/
617 
TermCopyKeepVars(Term_p source,DerefType deref)618 Term_p TermCopyKeepVars(Term_p source, DerefType deref)
619 {
620    Term_p handle;
621    int i;
622 
623    assert(source);
624 
625    source = TermDeref(source, &deref);
626 
627    if(TermIsVar(source))
628    {
629       return source;
630    }
631 
632    handle = TermTopCopy(source);
633 
634    for(i=0; i<handle->arity; i++) /* Hack: Loop will not be entered if
635                                      arity = 0 */
636    {
637       handle->args[i] = TermCopyKeepVars(handle->args[i], deref);
638    }
639    return handle;
640 }
641 
642 
643 /*-----------------------------------------------------------------------
644 //
645 // Function: TermStructEqual()
646 //
647 //   Return true if the two terms have the same structure. Follows
648 //   bindings.
649 //
650 // Global Variables: -
651 //
652 // Side Effects    : -
653 //
654 /----------------------------------------------------------------------*/
655 
656 
TermStructEqual(Term_p t1,Term_p t2)657 bool TermStructEqual(Term_p t1, Term_p t2)
658 {
659    t1 = TermDerefAlways(t1);
660    t2 = TermDerefAlways(t2);
661 
662    if(t1==t2)
663    {
664       return true;
665    }
666 
667    if(t1->f_code != t2->f_code)
668    {
669       return false;
670    }
671 
672    assert(t1->sort == t2->sort);
673    assert(t1->arity == t2->arity);
674    for(int i=0; i<t1->arity; i++)
675    {
676       if(!TermStructEqual(t1->args[i], t2->args[i]))
677       {
678          return false;
679       }
680    }
681    return true;
682 }
683 
684 
685 
686 /*-----------------------------------------------------------------------
687 //
688 // Function: TermStructEqualNoDeref()
689 //
690 //   Return true if the two terms have the same structures. Ignores
691 //   bindings.
692 //
693 // Global Variables: -
694 //
695 // Side Effects    : -
696 //
697 /----------------------------------------------------------------------*/
698 
699 
TermStructEqualNoDeref(Term_p t1,Term_p t2)700 bool TermStructEqualNoDeref(Term_p t1, Term_p t2)
701 {
702    if(t1==t2)
703    {
704       return true;
705    }
706 
707    if(t1->f_code != t2->f_code)
708    {
709       return false;
710    }
711 
712    assert(t1->sort == t2->sort);
713    assert(t1->arity == t2->arity);
714    for(int i=0; i<t1->arity; i++)
715    {
716       if(!TermStructEqualNoDeref(t1->args[i], t2->args[i]))
717       {
718          return false;
719       }
720    }
721    return true;
722 }
723 
724 /*-----------------------------------------------------------------------
725 //
726 // Function: TermStructEqualDeref()
727 //
728 //   Return true if the two terms have the same
729 //   structures. Dereference both terms as designated by deref_1,
730 //   deref_2.
731 //
732 // Global Variables: -
733 //
734 // Side Effects    : -
735 //
736 /----------------------------------------------------------------------*/
737 
TermStructEqualDeref(Term_p t1,Term_p t2,DerefType deref_1,DerefType deref_2)738 bool TermStructEqualDeref(Term_p t1, Term_p t2, DerefType deref_1, DerefType deref_2)
739 {
740 
741    t1 = TermDeref(t1, &deref_1);
742    t2 = TermDeref(t2, &deref_2);
743 
744    if((t1==t2) && (deref_1==deref_2))
745    {
746       return true;
747    }
748 
749    if(t1->f_code != t2->f_code)
750    {
751       return false;
752    }
753 
754    assert(t1->sort == t2->sort);
755    assert(t1->arity == t2->arity);
756    for(int i=0; i<t1->arity; i++)
757    {
758       if(!TermStructEqualDeref(t1->args[i], t2->args[i], deref_1, deref_2))
759       {
760          return false;
761       }
762    }
763    return true;
764 }
765 
766 /*-----------------------------------------------------------------------
767 //
768 // Function: TermStructWeightCompare()
769 //
770 //   Compare two terms based on just structural criteria: First
771 //   compare standard-weight, then compare top-symbol arity, then
772 //   compare subterms lexicographically. $true is always minimal.
773 //
774 // Global Variables: -
775 //
776 // Side Effects    : -
777 //
778 /----------------------------------------------------------------------*/
779 
TermStructWeightCompare(Term_p t1,Term_p t2)780 long TermStructWeightCompare(Term_p t1, Term_p t2)
781 {
782    assert(t1);
783    assert(t2);
784 
785    if(t1->f_code == SIG_TRUE_CODE)
786    {
787       assert(t1->arity == 0);
788       if(t2->f_code == SIG_TRUE_CODE)
789       {
790          assert(t2->arity == 0);
791          return 0;
792       }
793       return -1;
794    }
795 
796    if(t2->f_code == SIG_TRUE_CODE)
797    {
798       assert(t2->arity == 0);
799       return 1;
800    }
801 
802    long res = TermStandardWeight(t1) - TermStandardWeight(t2);
803    if(res)
804    {
805       return res;
806    }
807 
808    if(TermIsVar(t1))
809    { /* Then t2 also is a variable due to equal weights! */
810       assert(TermIsVar(t2));
811       return t1->sort - t2->sort;
812    }
813 
814    res = t1->arity - t2->arity;
815    if(res)
816    {
817       return res;
818    }
819 
820    assert(t1->sort == t2->sort);
821    assert(t1->arity == t2->arity);
822    for(int i=0; i<t1->arity; i++)
823    {
824       res = TermStructWeightCompare(t1->args[i], t2->args[i]);
825       if(res)
826       {
827          return res;
828       }
829    }
830 
831    return 0;
832 }
833 
834 
835 /*-----------------------------------------------------------------------
836 //
837 // Function: TermLexCompare()
838 //
839 //   Compare two terms lexicographically by f_codes.
840 //
841 // Global Variables: -
842 //
843 // Side Effects    : -
844 //
845 /----------------------------------------------------------------------*/
846 
TermLexCompare(Term_p t1,Term_p t2)847 long TermLexCompare(Term_p t1, Term_p t2)
848 {
849    int i;
850 
851    long res = t1->f_code - t2->f_code;
852    if(res)
853    {
854       return res;
855    }
856 
857    assert(t1->sort == t2->sort);
858    assert(t1->arity == t2->arity);
859    for(i=0; i<t1->arity; i++)
860    {
861       res = TermLexCompare(t1->args[i], t2->args[i]);
862       if(res)
863       {
864          return res;
865       }
866    }
867    return res;
868 }
869 
870 
871 /*-----------------------------------------------------------------------
872 //
873 // Function: TermIsSubterm()
874 //
875 //   Return true if test is a subterm to super.
876 //
877 // Global Variables: -
878 //
879 // Side Effects    : -
880 //
881 /----------------------------------------------------------------------*/
882 
TermIsSubterm(Term_p super,Term_p test,DerefType deref)883 bool TermIsSubterm(Term_p super, Term_p test, DerefType deref)
884 {
885    int i;
886 
887    super = TermDeref(super, &deref);
888 
889    if(super == test)
890    {
891       return true;
892    }
893    for(i=0; i<super->arity; i++)
894    {
895       if(TermIsSubterm(super->args[i], test, deref))
896       {
897          return true;
898       }
899    }
900    return false;
901 }
902 
903 
904 /*-----------------------------------------------------------------------
905 //
906 // Function: TermIsSubtermDeref()
907 //
908 //   Return true if test is a subterm to super. Uses
909 //   TermStructEqualDeref() for equal test.
910 //
911 // Global Variables: -
912 //
913 // Side Effects    : -
914 //
915 /----------------------------------------------------------------------*/
916 
TermIsSubtermDeref(Term_p super,Term_p test,DerefType deref_super,DerefType deref_test)917 bool TermIsSubtermDeref(Term_p super, Term_p test, DerefType
918                         deref_super, DerefType deref_test)
919 {
920    int i;
921 
922    super = TermDeref(super, &deref_super);
923    if(TermStructEqualDeref(super, test, deref_super, deref_test))
924    {
925       return true;
926    }
927    for(i=0; i<super->arity; i++)
928    {
929       if(TermIsSubtermDeref(super->args[i], test, deref_super, deref_test))
930       {
931          return true;
932       }
933    }
934    return false;
935 }
936 
937 
938 /*-----------------------------------------------------------------------
939 //
940 // Function: TermWeightCompute()
941 //
942 //   Compute the weight of a term, counting variables as vweight and
943 //   function symbols as fweight.
944 //
945 // Global Variables: -
946 //
947 // Side Effects    : Memory operations for the stack used.
948 //
949 /----------------------------------------------------------------------*/
950 
TermWeightCompute(Term_p term,long vweight,long fweight)951 long TermWeightCompute(Term_p term, long vweight, long fweight)
952 {
953    long res = 0;
954 
955    if(TermIsVar(term))
956    {
957       res += vweight;
958    }
959    else
960    {
961       res += fweight;
962       for(int i=0; i<term->arity; i++)
963       {
964          res += TermWeight(term->args[i], vweight, fweight);
965       }
966    }
967 
968    return res;
969 }
970 
971 
972 /*-----------------------------------------------------------------------
973 //
974 // Function: TermFsumWeight()
975 //
976 //   Return a weighted sum of the function symbols weights (and
977 //   variable weights) in the term.
978 //
979 // Global Variables: -
980 //
981 // Side Effects    : Memory operations
982 //
983 /----------------------------------------------------------------------*/
984 
TermFsumWeight(Term_p term,long vweight,long flimit,long * fweights,long default_fweight)985 long TermFsumWeight(Term_p term, long vweight, long flimit,
986                     long *fweights, long default_fweight)
987 {
988    long res = 0;
989 
990    if(TermIsVar(term))
991    {
992       res += vweight;
993    }
994    else
995    {
996       if(term->f_code < flimit)
997       {
998          res += fweights[term->f_code];
999       }
1000       else
1001       {
1002          res += default_fweight;
1003       }
1004 
1005       for(int i = 0; i < term->arity; i++)
1006       {
1007          res += TermFsumWeight(term->args[i], vweight, flimit, fweights, default_fweight);
1008       }
1009    }
1010 
1011    return res;
1012 
1013 }
1014 
1015 
1016 
1017 /*-----------------------------------------------------------------------
1018 //
1019 // Function: TermNonLinearWeight()
1020 //
1021 //   Compute the weight of a term, counting variables that occur for
1022 //   the first time as vlweight, varaibes that reoccur as vweight, and
1023 //   function symbols as fweight.
1024 //
1025 // Global Variables: -
1026 //
1027 // Side Effects    : Memory operations for the stack used.
1028 //
1029 /----------------------------------------------------------------------*/
1030 
TermNonLinearWeight(Term_p term,long vlweight,long vweight,long fweight)1031 long TermNonLinearWeight(Term_p term, long vlweight, long vweight,
1032                          long fweight)
1033 {
1034    long     res = 0;
1035    PStack_p stack = PStackAlloc();
1036    Term_p   handle;
1037 
1038    assert(term);
1039 
1040    TermDelProp(term, DEREF_NEVER, TPOpFlag);
1041 
1042    PStackPushP(stack, term);
1043 
1044    while(!PStackEmpty(stack))
1045    {
1046       handle = PStackPopP(stack);
1047       if(TermIsVar(handle))
1048       {
1049          if(TermCellQueryProp(handle, TPOpFlag))
1050          {
1051             res += vweight;
1052          }
1053          else
1054          {
1055             TermCellSetProp(handle, TPOpFlag);
1056             res += vlweight;
1057          }
1058       }
1059       else
1060       {
1061          int i;
1062 
1063          res += fweight;
1064 
1065          for(i=0; i<handle->arity; i++)
1066          {
1067             PStackPushP(stack, handle->args[i]);
1068          }
1069       }
1070    }
1071    PStackFree(stack);
1072 
1073    return res;
1074 }
1075 
1076 
1077 /*-----------------------------------------------------------------------
1078 //
1079 // Function: TermSymTypeWeight()
1080 //
1081 //   Compute the weight of a term, giving different weight to
1082 //   variables, constants, function symbols and predicates.
1083 //
1084 // Global Variables: -
1085 //
1086 // Side Effects    : Memory operations for the stack.
1087 //
1088 /----------------------------------------------------------------------*/
1089 
TermSymTypeWeight(Term_p term,long vweight,long fweight,long cweight,long pweight)1090 long TermSymTypeWeight(Term_p term, long vweight, long fweight, long
1091                        cweight, long pweight)
1092 {
1093    long     res = 0;
1094    PStack_p stack = PStackAlloc();
1095    Term_p   handle;
1096 
1097    assert(term);
1098 
1099    PStackPushP(stack, term);
1100 
1101    while(!PStackEmpty(stack))
1102    {
1103       handle = PStackPopP(stack);
1104       if(TermIsVar(handle))
1105       {
1106          res += vweight;
1107       }
1108       else
1109       {
1110          int i;
1111 
1112          if(TermCellQueryProp(handle,TPPredPos))
1113          {
1114             res += pweight;
1115          }
1116          else if(handle->arity==0)
1117          {
1118             res += cweight;
1119          }
1120          else
1121          {
1122             res += fweight;
1123          }
1124          for(i=0; i<handle->arity; i++)
1125          {
1126             PStackPushP(stack, handle->args[i]);
1127          }
1128       }
1129    }
1130    PStackFree(stack);
1131 
1132    return res;
1133 }
1134 
1135 /*-----------------------------------------------------------------------
1136 //
1137 // Function: TermDepth()
1138 //
1139 //   Return the depth of a term.
1140 //
1141 // Global Variables: -
1142 //
1143 // Side Effects    : -
1144 //
1145 /----------------------------------------------------------------------*/
1146 
TermDepth(Term_p term)1147 long TermDepth(Term_p term)
1148 {
1149    long maxdepth = 0, ldepth;
1150    int  i;
1151 
1152    for(i=0; i<term->arity; i++)
1153    {
1154       ldepth = TermDepth(term->args[i]);
1155       maxdepth = MAX(maxdepth, ldepth);
1156    }
1157    return maxdepth+1;
1158 }
1159 
1160 /*-----------------------------------------------------------------------
1161 //
1162 // Function: TermIsDefTerm()
1163 //
1164 //   Return true if t is of the form f(X1...Xn) with n>=arity.
1165 //
1166 // Global Variables: -
1167 //
1168 // Side Effects    : Sets TPOpFlag
1169 //
1170 /----------------------------------------------------------------------*/
1171 
TermIsDefTerm(Term_p term,int min_arity)1172 bool TermIsDefTerm(Term_p term, int min_arity)
1173 {
1174    int i;
1175 
1176    assert(term);
1177 
1178    if(TermIsVar(term))
1179    {
1180       return false;
1181    }
1182    if(term->arity<min_arity)
1183    {
1184       return false;
1185    }
1186    if(TermStandardWeight(term)!=(DEFAULT_FWEIGHT+term->arity*DEFAULT_VWEIGHT))
1187    {
1188       return false;
1189    }
1190    for(i=0; i<term->arity; i++)
1191    {
1192       TermCellDelProp(term->args[i], TPOpFlag);
1193    }
1194    for(i=0; i<term->arity; i++)
1195    {
1196       if(TermCellQueryProp(term->args[i], TPOpFlag))
1197       {
1198          return false;
1199       }
1200       TermCellSetProp(term->args[i], TPOpFlag);
1201    }
1202    return true;
1203 }
1204 
1205 
1206 /*-----------------------------------------------------------------------
1207 //
1208 // Function: TermHasFCode()
1209 //
1210 //   Return true if f occurs in term, false otherwise.
1211 //
1212 // Global Variables: -
1213 //
1214 // Side Effects    : -
1215 //
1216 /----------------------------------------------------------------------*/
1217 
TermHasFCode(Term_p term,FunCode f)1218 bool TermHasFCode(Term_p term, FunCode f)
1219 {
1220    int i;
1221 
1222    assert(term);
1223 
1224    if(term->f_code == f)
1225    {
1226       return true;
1227    }
1228    for(i=0; i<term->arity; i++)
1229    {
1230       if(TermHasFCode(term->args[i], f))
1231       {
1232          return true;
1233       }
1234    }
1235    return false;
1236 }
1237 
1238 /*-----------------------------------------------------------------------
1239 //
1240 // Function: TermHasUnboundVariables()
1241 //
1242 //   Return if the term contains unbound variables.
1243 //   Does not follow bindings.
1244 //
1245 // Global Variables: -
1246 //
1247 // Side Effects    : -
1248 //
1249 /----------------------------------------------------------------------*/
1250 
TermHasUnboundVariables(Term_p term)1251 bool TermHasUnboundVariables(Term_p term)
1252 {
1253    bool res = false;
1254 
1255    if(TermIsVar(term))
1256    {
1257       if(!term->binding)
1258       {
1259          res = true;
1260       }
1261    }
1262    else
1263    {
1264       for(int i=0; i < term->arity; i++)
1265       {
1266          if(TermHasUnboundVariables(term->args[i]))
1267          {
1268             res = true;
1269             break;
1270          }
1271       }
1272    }
1273 
1274    return res;
1275 }
1276 
1277 /*-----------------------------------------------------------------------
1278 //
1279 // Function: TermIsGroundCompute()
1280 //
1281 //   Return if the term contains no variables.
1282 //   Does not follow bindings.
1283 //
1284 // Global Variables: -
1285 //
1286 // Side Effects    : -
1287 //
1288 /----------------------------------------------------------------------*/
1289 
TermIsGroundCompute(Term_p term)1290 bool TermIsGroundCompute(Term_p term)
1291 {
1292    bool res = true;
1293 
1294    if(TermIsVar(term))
1295    {
1296       res = false;
1297    }
1298    else
1299    {
1300       for(int i=0; i < term->arity; i++)
1301       {
1302          if(!TermIsGroundCompute(term->args[i]))
1303          {
1304             res = false;
1305             break;
1306          }
1307       }
1308    }
1309 
1310    return res;
1311 }
1312 
1313 /*-----------------------------------------------------------------------
1314 //
1315 // Function: TermFindMaxVarCode()
1316 //
1317 //   Return largest (absolute, i.e. largest negative) f_code of any
1318 //   variable in term.
1319 //
1320 // Global Variables:
1321 //
1322 // Side Effects    :
1323 //
1324 /----------------------------------------------------------------------*/
1325 
TermFindMaxVarCode(Term_p term)1326 FunCode TermFindMaxVarCode(Term_p term)
1327 {
1328    int i;
1329    long res, tmp;
1330 
1331    if(TermIsVar(term))
1332    {
1333       return term->f_code;
1334    }
1335    else
1336    {
1337       res = 0;
1338       for(i=0; i<term->arity; i++)
1339       {
1340          tmp = TermFindMaxVarCode(term->args[i]);
1341          res = MIN(res, tmp);
1342       }
1343    }
1344    return res;
1345 }
1346 
1347 
1348 /*-----------------------------------------------------------------------
1349 //
1350 // Function: VarBankCheckBindings()
1351 //
1352 //   For all variables in bank, check if they are bound. If sig!=0,
1353 //   print the variable and binding as a comment, otherwise just print
1354 //   variable number. Return number of bound variables.
1355 //
1356 // Global Variables: -
1357 //
1358 // Side Effects    : Output, Memory
1359 //
1360 /----------------------------------------------------------------------*/
1361 
VarBankCheckBindings(FILE * out,VarBank_p bank,Sig_p sig)1362 FunCode VarBankCheckBindings(FILE* out, VarBank_p bank, Sig_p sig)
1363 {
1364    Term_p    term;
1365    VarBankStack_p stack;
1366    long      res = 0;
1367    int       i,j;
1368 
1369    fprintf(out, "#  VarBankCheckBindings() started...\n");
1370    for(i=0; i<PDArraySize(bank->stacks); i++)
1371    {
1372       stack = (VarBankStack_p) PDArrayElementP(bank->stacks, i);
1373       if (!stack)
1374       {
1375          continue;
1376       }
1377 
1378       for(j=0; j < PDArraySize(stack); j++)
1379       {
1380          term = PDArrayElementP(stack, j);
1381          if(term)
1382          {
1383             assert(TermIsVar(term));
1384             if(term->binding)
1385             {
1386                res++;
1387                if(sig)
1388                {
1389                   fprintf(out, "# %ld: ", term->f_code);
1390                   TermPrint(out, term, sig, DEREF_NEVER);
1391                   fprintf(out, " <--- ");
1392                   TermPrint(out, term, sig, DEREF_ONCE);
1393                   fprintf(out, "\n");
1394                }
1395                else
1396                {
1397                   fprintf(out, "# Var%ld <---- %p\n",
1398                           term->f_code,
1399                           (void*)term->binding);
1400                }
1401             }
1402          }
1403       }
1404    }
1405    fprintf(out, "#  ...VarBankCheckBindings() completed\n");
1406    return res;
1407 }
1408 
1409 
1410 /*-----------------------------------------------------------------------
1411 //
1412 // Function: TermAddSymbolDistributionLimited()
1413 //
1414 //   Count occurences of function symbols with f_code<limit in
1415 //   dist_array. Terms are not dereferenced!
1416 //
1417 // Global Variables: -
1418 //
1419 // Side Effects    : -
1420 //
1421 /----------------------------------------------------------------------*/
1422 
TermAddSymbolDistributionLimited(Term_p term,long * dist_array,long limit)1423 void TermAddSymbolDistributionLimited(Term_p term, long *dist_array, long limit)
1424 {
1425    PStack_p stack = PStackAlloc();
1426    assert(term);
1427 
1428    PStackPushP(stack, term);
1429 
1430    while(!PStackEmpty(stack))
1431    {
1432       term = PStackPopP(stack);
1433       assert(term);
1434 
1435       if(!TermIsVar(term))
1436       {
1437          int i;
1438 
1439          assert(term->f_code > 0);
1440          if(term->f_code < limit)
1441          {
1442             dist_array[term->f_code]++;
1443          }
1444          for(i=0; i<term->arity; i++)
1445          {
1446             assert(term->args);
1447             PStackPushP(stack, term->args[i]);
1448          }
1449       }
1450    }
1451    PStackFree(stack);
1452 }
1453 
1454 /*-----------------------------------------------------------------------
1455 //
1456 // Function: TermAddSymbolDistribExist()
1457 //
1458 //   Compute the distribution of symbols in term. Push all occuring
1459 //   symbols onto exists (once ;-).
1460 //
1461 // Global Variables: -
1462 //
1463 // Side Effects    : -
1464 //
1465 /----------------------------------------------------------------------*/
1466 
TermAddSymbolDistExist(Term_p term,long * dist_array,PStack_p exists)1467 void TermAddSymbolDistExist(Term_p term, long *dist_array,
1468                             PStack_p exists)
1469 {
1470    PStack_p stack = PStackAlloc();
1471    assert(term);
1472 
1473    PStackPushP(stack, term);
1474 
1475    while(!PStackEmpty(stack))
1476    {
1477       term = PStackPopP(stack);
1478       assert(term);
1479 
1480       if(!TermIsVar(term))
1481       {
1482          int i;
1483 
1484          assert(term->f_code > 0);
1485          if(!dist_array[term->f_code])
1486          {
1487             PStackPushInt(exists, term->f_code);
1488          }
1489          dist_array[term->f_code]++;
1490 
1491          for(i=0; i<term->arity; i++)
1492          {
1493             assert(term->args);
1494             PStackPushP(stack, term->args[i]);
1495          }
1496       }
1497    }
1498    PStackFree(stack);
1499 }
1500 
1501 
1502 /*-----------------------------------------------------------------------
1503 //
1504 // Function: TermAddSymbolFeaturesLimited()
1505 //
1506 //   Add function symbol frequencies and deepest depth of a function
1507 //   symbol to the two arrays. This is an extension of the function
1508 //   above, this one does the extendet task in a single term
1509 //   traversal. Note that function symbols >=limit are counted in
1510 //   array[0] for both depth and frequency.
1511 //
1512 // Global Variables: -
1513 //
1514 // Side Effects    : Changes the arrays.
1515 //
1516 /----------------------------------------------------------------------*/
1517 
TermAddSymbolFeaturesLimited(Term_p term,long depth,long * freq_array,long * depth_array,long limit)1518 void TermAddSymbolFeaturesLimited(Term_p term, long depth,
1519                                   long *freq_array, long* depth_array,
1520                                   long limit)
1521 {
1522    if(!TermIsVar(term))
1523    {
1524       int i;
1525 
1526       if(term->f_code < limit)
1527       {
1528          freq_array[term->f_code]++;
1529          depth_array[term->f_code] = MAX(depth, depth_array[term->f_code]);
1530       }
1531       else
1532       {
1533          freq_array[0]++;
1534          depth_array[0] = MAX(depth, depth_array[0]);
1535       }
1536       for(i=0; i<term->arity; i++)
1537       {
1538          TermAddSymbolFeaturesLimited(term->args[i], depth+1,
1539                                       freq_array, depth_array,
1540                                       limit);
1541       }
1542    }
1543 }
1544 
1545 
1546 /*-----------------------------------------------------------------------
1547 //
1548 // Function: TermAddSymbolFeatures()
1549 //
1550 //   Add function symbol frequencies and deepest depth of a function
1551 //   symbol to the array. offset should be 0 for positive literals, 2
1552 //   for negative literals. Thus, the 4 features for a given f
1553 //   are stored at indices follows:
1554 //   - 4*f_code:   |C^+|_f
1555 //   - 4*f_code+1: d_f(C^+)
1556 //   - 4*f_code+2: |C^-|_f
1557 //   - 4*f_code+3: d_f(C^-)
1558 //
1559 // Global Variables: -
1560 //
1561 // Side Effects    : Changes the arrays.
1562 //
1563 /----------------------------------------------------------------------*/
1564 
TermAddSymbolFeatures(Term_p term,PStack_p mod_stack,long depth,long * feature_array,long offset)1565 void TermAddSymbolFeatures(Term_p term, PStack_p mod_stack, long depth,
1566                            long *feature_array, long offset)
1567 {
1568    if(!TermIsVar(term))
1569    {
1570       int i;
1571       long findex = 4*term->f_code+offset;
1572 
1573       if(feature_array[findex] == 0)
1574       {
1575          PStackPushInt(mod_stack, findex);
1576       }
1577 
1578       feature_array[findex]++;
1579       feature_array[findex+1] = MAX(depth, feature_array[findex+1]);
1580       for(i=0; i<term->arity; i++)
1581       {
1582          TermAddSymbolFeatures(term->args[i], mod_stack, depth+1,
1583                                feature_array, offset);
1584       }
1585    }
1586 }
1587 
1588 
1589 /*-----------------------------------------------------------------------
1590 //
1591 // Function: TermComputeFunctionRanks()
1592 //
1593 //   Assign an occurance rank to each symbol in term.
1594 //
1595 // Global Variables: -
1596 //
1597 // Side Effects    : -
1598 //
1599 /----------------------------------------------------------------------*/
1600 
TermComputeFunctionRanks(Term_p term,long * rank_array,long * count)1601 void TermComputeFunctionRanks(Term_p term, long *rank_array, long *count)
1602 {
1603    int i;
1604 
1605    if(TermIsVar(term))
1606    {
1607       return;
1608    }
1609    for(i=0; i < term->arity; i++)
1610    {
1611       TermComputeFunctionRanks(term->args[i], rank_array, count);
1612    }
1613    if(!rank_array[term->f_code])
1614    {
1615       rank_array[term->f_code] = (*count)++;
1616    }
1617 }
1618 
1619 
1620 /*-----------------------------------------------------------------------
1621 //
1622 // Function: TermCollectPropVariables()
1623 //
1624 //   Insert all variables with properties prop in term into
1625 //   tree. Return number of new variables.
1626 //
1627 // Global Variables: -
1628 //
1629 // Side Effects    : Memory operations
1630 //
1631 /----------------------------------------------------------------------*/
1632 
TermCollectPropVariables(Term_p term,PTree_p * tree,TermProperties prop)1633 long TermCollectPropVariables(Term_p term, PTree_p *tree,
1634                               TermProperties prop)
1635 {
1636    long res = 0;
1637    PStack_p stack = PStackAlloc();
1638    int      i;
1639 
1640    PStackPushP(stack,term);
1641 
1642    while(!PStackEmpty(stack))
1643    {
1644       term = PStackPopP(stack);
1645       if(TermIsVar(term) &&
1646          TermCellQueryProp(term,prop))
1647       {
1648          if(PTreeStore(tree, term))
1649          {
1650             res++;
1651          }
1652       }
1653       else
1654       {
1655          for(i=0; i<term->arity; i++)
1656          {
1657             PStackPushP(stack,term->args[i]);
1658          }
1659       }
1660    }
1661    PStackFree(stack);
1662 
1663    return res;
1664 }
1665 
1666 
1667 
1668 /*-----------------------------------------------------------------------
1669 //
1670 // Function: TermAddFunOcc()
1671 //
1672 //  Add all new occurences of function symbol to res_stack and mark
1673 //  them as no-longer-new in f_occur. Return number of new function
1674 //  symbols added.
1675 //
1676 // Global Variables: -
1677 //
1678 // Side Effects    : Memory operations
1679 //
1680 /----------------------------------------------------------------------*/
1681 
TermAddFunOcc(Term_p term,PDArray_p f_occur,PStack_p res_stack)1682 long TermAddFunOcc(Term_p term, PDArray_p f_occur, PStack_p res_stack)
1683 {
1684    long res = 0;
1685    PStack_p stack = PStackAlloc();
1686    int      i;
1687 
1688    PStackPushP(stack,term);
1689 
1690    while(!PStackEmpty(stack))
1691    {
1692       term = PStackPopP(stack);
1693       if(!TermIsVar(term))
1694       {
1695          if(!PDArrayElementInt(f_occur, term->f_code))
1696          {
1697             res++;
1698             PStackPushInt(res_stack, term->f_code);
1699             PDArrayAssignInt(f_occur, term->f_code, 1);
1700          }
1701          for(i=0; i<term->arity; i++)
1702          {
1703             PStackPushP(stack,term->args[i]);
1704          }
1705       }
1706    }
1707    PStackFree(stack);
1708 
1709    return res;
1710 }
1711 
1712 
1713 
1714 
1715 /*-----------------------------------------------------------------------
1716 //
1717 // Function: TermLinearize()
1718 //
1719 //   Put all subterms of term onto PStack in left-right preorder. Note
1720 //   that for an empty stack, that makes the index of s on the stack
1721 //   equal to its TermCPos. Returns number of subterms.
1722 //
1723 // Global Variables: -
1724 //
1725 // Side Effects    : Changes stack
1726 //
1727 /----------------------------------------------------------------------*/
1728 
TermLinearize(PStack_p stack,Term_p term)1729 long TermLinearize(PStack_p stack, Term_p term)
1730 {
1731    long res = 1;
1732    int i;
1733 
1734    PStackPushP(stack, term);
1735    for(i = 0; i<term->arity; i++)
1736    {
1737       res += TermLinearize(stack, term->args[i]);
1738    }
1739    return res;
1740 }
1741 
1742 
1743 /*-----------------------------------------------------------------------
1744 //
1745 // Function: TermCheckConsistency()
1746 //
1747 //   Traverse a tree and check if any one term cell occurs more than
1748 //   once on any branch (which would make the term cyclic). Return the
1749 //   first inconsistency found or NULL.
1750 //
1751 // Global Variables: -
1752 //
1753 // Side Effects    : Memory operations
1754 //
1755 /----------------------------------------------------------------------*/
1756 
TermCheckConsistency(Term_p term,DerefType deref)1757 Term_p TermCheckConsistency(Term_p term, DerefType deref)
1758 {
1759    Term_p   res;
1760    PTree_p  branch = NULL;
1761 
1762    printf("TermCheckConsistency...\n");
1763    res = term_check_consistency_rek(term, &branch, deref);
1764    assert(branch == 0);
1765    printf("...TermCheckConsistency\n");
1766    return res;
1767 }
1768 
1769 
1770 /*-----------------------------------------------------------------------
1771 //
1772 // Function: TermAssertSameSort
1773 //
1774 //  checks whether the two terms have the same sort. Prints a (verbose)
1775 //  message if it's not the case and exit.
1776 //
1777 // Global Variables: -
1778 //
1779 // Side Effects    : May exit
1780 //
1781 /----------------------------------------------------------------------*/
TermAssertSameSort(Sig_p sig,Term_p t1,Term_p t2)1782 void TermAssertSameSort(Sig_p sig, Term_p t1, Term_p t2)
1783 {
1784    if(t1->sort != t2->sort)
1785    {
1786       fprintf(stderr, "# Error: terms ");
1787       TermPrint(stderr, t1, sig, DEREF_NEVER);
1788       fprintf(stderr, ": ");
1789       SortPrintTSTP(stderr, sig->sort_table, t1->sort);
1790       fprintf(stderr, " and ");
1791       TermPrint(stderr, t2, sig, DEREF_NEVER);
1792       fprintf(stderr, ": ");
1793       SortPrintTSTP(stderr, sig->sort_table, t2->sort);
1794       fprintf(stderr, " should have same sort\n");
1795       Error("Type error", SYNTAX_ERROR);
1796    }
1797 }
1798 
1799 
1800 /*-----------------------------------------------------------------------
1801 //
1802 // Function: TermIsUntyped
1803 //
1804 //   check whether all sorts occurring in the term are either
1805 //   individual or boolean. In other words, whether the term
1806 //   belongs to regular untyped logic.
1807 //
1808 // Global Variables: -
1809 //
1810 // Side Effects    : Memory operations
1811 //
1812 /----------------------------------------------------------------------*/
TermIsUntyped(Term_p term)1813 bool TermIsUntyped(Term_p term)
1814 {
1815    bool res = true;
1816 
1817    PLocalStackInit(stack);
1818 
1819    PLocalStackPush(stack, term);
1820 
1821    while(!PLocalStackEmpty(stack))
1822    {
1823       term = PLocalStackPop(stack);
1824 
1825       if(term->sort == STIndividuals || term->sort == STBool)
1826       {
1827          PLocalStackPushTermArgs(stack, term);
1828       }
1829       else
1830       {
1831          res = false;
1832          break;
1833       }
1834    }
1835 
1836    PLocalStackFree(stack);
1837 
1838    return res;
1839 }
1840 
1841 
1842 /*---------------------------------------------------------------------*/
1843 /*                        End of File                                  */
1844 /*---------------------------------------------------------------------*/
1845