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