1
/**************************************************************/
2
/* ********************************************************** */
6
/* * $Module: DEFS * */
8
/* * Copyright (C) 1998, 1999, 2000, 2001 * */
9
/* * MPI fuer Informatik * */
11
/* * This program is free software; you can redistribute * */
12
/* * it and/or modify it under the terms of the FreeBSD * */
15
/* * This program is distributed in the hope that it will * */
16
/* * be useful, but WITHOUT ANY WARRANTY; without even * */
17
/* * the implied warranty of MERCHANTABILITY or FITNESS * */
18
/* * FOR A PARTICULAR PURPOSE. See the LICENCE file * */
19
/* * for more details. * */
22
/* $Revision: 1.3 $ * */
24
/* $Date: 2010-02-22 14:09:57 $ * */
25
/* $Author: weidenb $ * */
28
/* * Christoph Weidenbach * */
29
/* * MPI fuer Informatik * */
30
/* * Stuhlsatzenhausweg 85 * */
31
/* * 66123 Saarbruecken * */
32
/* * Email: spass@mpi-inf.mpg.de * */
35
/* ********************************************************** */
36
/**************************************************************/
39
/* $RCSfile: defs.c,v $ */
45
static void def_DeleteFromClauses(DEF);
46
static void def_DeleteFromTerm(DEF);
48
DEF def_CreateFromClauses(TERM ExpTerm, TERM PredTerm, LIST Clauses, LIST Lits,
50
/**********************************************************
51
INPUT: Two terms, a list of clausenumbers, a list of literal indices and
52
a boolean saying whether all clauses derived by expanding the
53
predicate should be conclauses.
54
RETURNS: A definition consisting of the 2 terms as expansion term and
55
predicate term and the list of parent clause numbers and a list
56
of the indices of the defined predicate in the parent clauses.
57
ToProve and label are set to NULL.
58
********************************************************/
63
if (!term_IsTerm(ExpTerm) || !term_IsTerm(PredTerm)) {
64
misc_StartErrorReport();
65
misc_ErrorReport("\n In def_CreateFromClause: Illegal input.");
66
misc_FinishErrorReport();
68
if (list_Empty(Clauses)) {
69
misc_StartErrorReport();
70
misc_ErrorReport("\n In def_CreateFromClause: No parent clause given.");
71
misc_FinishErrorReport();
75
result = (DEF) memory_Malloc(sizeof(DEF_NODE));
76
result->expansion = ExpTerm;
77
result->predicate = PredTerm;
78
result->toprove = (TERM) NULL;
79
result->parentclauses = list_PairCreate(Clauses, Lits);
80
result->label = (const char*) NULL;
81
result->conjecture = Con;
86
DEF def_CreateFromTerm(TERM ExpTerm, TERM PredTerm, TERM ToProve, const char* Label)
87
/**********************************************************
88
INPUT: 3 terms and a term label.
89
RETURNS: A definition consisting of the 3 terms as expansion term,
90
predicate term and term to prove before applying the
91
definition and the label of the parent term.
92
The list of clausenumbers is set to NULL.
93
********************************************************/
98
if (!term_IsTerm(ExpTerm) || !term_IsTerm(PredTerm)) {
99
misc_StartErrorReport();
100
misc_ErrorReport("\n In def_CreateFromTerm: Illegal input.");
101
misc_FinishErrorReport();
104
misc_StartErrorReport();
105
misc_ErrorReport("\n In def_CreateFromTerm: No parent clause given.");
106
misc_FinishErrorReport();
110
result = (DEF) memory_Malloc(sizeof(DEF_NODE));
111
result->expansion = ExpTerm;
112
result->predicate = PredTerm;
113
result->toprove = ToProve;
114
result->parentclauses = list_PairCreate(list_Nil(), list_Nil());
115
result->label = Label;
116
result->conjecture = FALSE;
121
static void def_DeleteFromClauses(DEF D)
122
/**********************************************************
123
INPUT: A definition derived from clauses.
124
EFFECT: The definition is deleted, INCLUDING THE TERMS AND
125
THE LIST OF CLAUSE NUMBERS.
126
********************************************************/
129
if (!term_IsTerm(def_Expansion(D)) || !term_IsTerm(def_Predicate(D))) {
130
misc_StartErrorReport();
131
misc_ErrorReport("\n In def_DeleteFormClauses: Illegal input.");
132
misc_FinishErrorReport();
136
/* ToProve and Label are NULL */
137
term_Delete(def_Expansion(D));
138
term_Delete(def_Predicate(D));
139
list_Delete(def_ClauseNumberList(D));
140
list_Delete(def_ClauseLitsList(D));
141
list_PairFree(D->parentclauses);
143
memory_Free(D, sizeof(DEF_NODE));
146
static void def_DeleteFromTerm(DEF D)
147
/**********************************************************
148
INPUT: A definition derived from a term.
149
EFFECT: The definition is deleted, INCLUDING THE TERMS.
150
THE LABEL IS NOT FREED.
151
********************************************************/
154
if (!term_IsTerm(def_Expansion(D)) || !term_IsTerm(def_Predicate(D))) {
155
misc_StartErrorReport();
156
misc_ErrorReport("\n In def_DeleteFromTerm: Illegal input.");
157
misc_FinishErrorReport();
161
/* List of clausenumbers is NULL */
162
term_Delete(def_Expansion(D));
163
term_Delete(def_Predicate(D));
164
if (def_ToProve(D) != (TERM) NULL)
165
term_Delete(def_ToProve(D));
166
list_PairFree(D->parentclauses);
167
memory_Free(D, sizeof(DEF_NODE));
170
void def_Delete(DEF D)
171
/**********************************************************
172
INPUT: A definition derived from a term.
173
EFFECT: The definition is deleted.
174
CAUTION: All elements of the definition except of the label are freed.
175
********************************************************/
177
if (!list_Empty(def_ClauseNumberList(D)))
178
def_DeleteFromClauses(D);
180
def_DeleteFromTerm(D);
183
int def_PredicateOccurrences(TERM Term, SYMBOL P)
184
/****************************************************
185
INPUT: A term and a predicate symbol.
186
RETURNS: The number of occurrences of the predicate symbol in Term
187
**************************************************/
190
if (fol_IsQuantifier(term_TopSymbol(Term)))
191
return def_PredicateOccurrences(term_SecondArgument(Term), P);
193
/* Junctors and NOT */
194
if (fol_IsJunctor(term_TopSymbol(Term)) ||
195
symbol_Equal(term_TopSymbol(Term),fol_Not())){
199
for (scan=term_ArgumentList(Term); !list_Empty(scan); scan=list_Cdr(scan)) {
200
count += def_PredicateOccurrences((TERM) list_Car(scan), P);
201
/* Only the cases count==1 and count>1 are important */
208
if (symbol_Equal(term_TopSymbol(Term), P))
213
LIST def_ExtractDefsFromTerm(TERM Term, const char* Label)
214
/**************************************************************
215
INPUT: A term and its label.
216
RETURNS: A list of definitions found in the term.
217
NOTE: The Term is not changed, the definitions contain copies.
218
***************************************************************/
223
LIST univars, termlist, defslist, scan;
225
/* First check if there is a top level and() so that the Term may
226
contain several definitions */
231
univars = list_Nil();
233
/* Traverse top down universal quantifiers */
235
if ((symbol_Equal(term_TopSymbol(andterm), fol_All()) && (pol == 1))
236
|| (symbol_Equal(term_TopSymbol(andterm), fol_Exist()) && (pol == -1))) {
237
univars = list_Nconc(univars, list_Copy(fol_QuantifierVariables(andterm)));
238
andterm = term_SecondArgument(andterm);
241
if (symbol_Equal(term_TopSymbol(andterm), fol_Not())) {
243
andterm = term_FirstArgument(andterm);
250
termlist = list_Nil();
251
/* Check if conjunction was found */
252
if ((symbol_Equal(term_TopSymbol(andterm), fol_And()) && (pol == 1))
253
|| (symbol_Equal(term_TopSymbol(andterm), fol_Or()) && (pol == -1))) {
255
/* Flatten nested and/or */
256
/* Make copy of relevant subterm */
257
andterm = cnf_Flatten(term_Copy(andterm), term_TopSymbol(andterm));
258
for (l=term_ArgumentList(andterm); !list_Empty(l); l=list_Cdr(l)) {
260
newterm = fol_CreateQuantifierAddFather(fol_All(), term_CopyTermList(univars),
261
list_List(list_Car(l)));
262
termlist = list_Cons(newterm, termlist);
264
/* Arguments are used in new terms */
265
list_Delete(term_ArgumentList(andterm));
269
termlist = list_List(term_Copy(Term));
271
list_Delete(univars);
273
/* Now we have a list of terms that may contain definitions */
274
defslist = list_Nil();
275
for (scan=termlist; !list_Empty(scan); scan=list_Cdr(scan)) {
277
TERM foundpred, toprove;
279
/* Candidate from list */
280
cand = (TERM) list_Car(scan);
281
term_AddFatherLinks(cand);
283
if (cnf_ContainsDefinition(cand, &foundpred)) {
286
if (!fol_CheckFormula(cand)) {
287
misc_StartErrorReport();
288
misc_ErrorReport("\n In def_ExtractDefsFromTerm: Illegal term cand");
289
misc_FinishErrorReport();
292
cand = cnf_DefConvert(cand, foundpred, &toprove);
294
if (!fol_CheckFormula(cand)) {
295
misc_StartErrorReport();
296
misc_ErrorReport("\n In def_ExtractDefsFromTerm: Illegal term cand");
297
misc_FinishErrorReport();
300
def = def_CreateFromTerm(term_Copy(term_SecondArgument(term_Superterm(foundpred))),
301
term_Copy(foundpred), toprove, Label);
303
if (def_PredicateOccurrences(cand, term_TopSymbol(foundpred)) > 1)
304
def_RemoveAttribute(def, PREDOCCURONCE);
306
def_AddAttribute(def, PREDOCCURONCE);
307
if (symbol_Equal(term_TopSymbol(foundpred), fol_Equality()))
308
def_AddAttribute(def, ISEQUALITY);
310
def_RemoveAttribute(def, ISEQUALITY);
312
defslist = list_Cons(def, defslist);
317
list_Delete(termlist);
321
void def_ExtractDefsFromClauselist(PROOFSEARCH Search, LIST Clauselist)
322
/**************************************************************
323
INPUT: A proofsearch object and a list of clauses
325
EFFECT: The definitions found in the clauselist object are stored in
326
the proofsearch object.
327
NOTE: The clause list is not changed.
328
The old list of definitions in the proofsearch object is
330
***************************************************************/
334
PRECEDENCE Precedence;
336
defslist = list_Nil();
337
FlagStore = prfs_Store(Search);
338
Precedence = prfs_Precedence(Search);
340
for (scan=Clauselist; !list_Empty(scan); scan=list_Cdr(scan)) {
345
Clause = (CLAUSE) list_Car(scan);
346
/* Check if clause contains a predicate that may be part of a definition */
347
if (clause_ContainsPotPredDef(Clause, FlagStore, Precedence, &literal_index, &pair)) {
348
LIST l, compl, compllits;
351
compl = compllits = list_Nil();
354
/* Search for complement clauses */
355
for (l=Clauselist; !list_Empty(l) && !done; l=list_Cdr(l)) {
357
if (clause_IsPartOfDefinition((CLAUSE) list_Car(l),
358
clause_GetLiteralTerm(Clause, literal_index),
360
compl = list_Cons(list_Car(l), compl);
361
compllits = list_Cons((POINTER) predindex, compllits);
363
if (list_Empty(list_PairFirst(pair)) &&
364
list_Empty(list_PairSecond(pair)))
369
/* All complements found ? */
371
LIST l2, clausenumbers, args;
374
TERM defterm, predterm;
377
clausenumbers = list_Nil();
378
con = clause_GetFlag(Clause, CONCLAUSE);
380
for (l2=compl; !list_Empty(l2); l2=list_Cdr(l2)) {
381
clausenumbers = list_Cons((POINTER) clause_Number((CLAUSE) list_Car(l2)),
383
if (clause_GetFlag((CLAUSE) list_Car(l2), CONCLAUSE))
386
clausenumbers = list_Cons((POINTER) clause_Number(Clause),
388
compllits = list_Cons((POINTER) literal_index, compllits);
390
/* Build definition term */
391
predterm = term_Copy(clause_GetLiteralTerm(Clause, literal_index));
393
for (i = 0; i < clause_Length(Clause); i++)
394
if (i != literal_index)
395
args = list_Cons(term_Copy(clause_GetLiteralTerm(Clause, i)), args);
396
defterm = term_CreateAddFather(fol_Or(), args);
397
/* The expansion is negative here, so it must be inverted */
398
defterm = term_Create(fol_Not(), list_List(defterm));
399
defterm = cnf_NegationNormalFormula(defterm);
400
def = def_CreateFromClauses(defterm, predterm, clausenumbers, compllits, con);
401
defslist = list_Cons(def, defslist);
402
if (flag_GetFlagIntValue(FlagStore, flag_PAPPLYDEFS)) {
403
fputs("\nNew definition found :", stdout);
408
list_Delete(compllits);
409
list_Delete(list_PairSecond(pair));
410
list_Delete(list_PairFirst(pair));
417
if (flag_GetFlagIntValue(FlagStore, flag_PAPPLYDEFS)) {
418
if (!list_Empty(defslist)) {
419
fputs("\nFound definitions :\n", stdout);
420
for (scan = defslist; !list_Empty(scan); scan = list_Cdr(scan)) {
421
def_Print((DEF) list_Car(scan));
422
fputs("\n---\n", stdout);
427
for (scan=defslist; !list_Empty(scan); scan=list_Cdr(scan))
428
symbol_AddProperty(term_TopSymbol(def_Predicate((DEF) list_Car(scan))), ISDEF);
430
prfs_SetDefinitions(Search, list_Nconc(prfs_Definitions(Search), defslist));
433
TERM def_ApplyDefToTermOnce(DEF Def, TERM Term, FLAGSTORE FlagStore,
434
PRECEDENCE Precedence, BOOL* Complete)
435
/**************************************************************
436
INPUT: A DEF structure, a term and a boolean that is set
437
to TRUE if no occurrences of the defined predicate
438
remain in the term. A flag store and a precedence.
439
RETURNS: A term where all occurrences of the definitions
440
predicate are expanded if possible.
441
NOTE: The Term is not changed.
442
***************************************************************/
444
TERM newtarget, oldtarget, targetpredicate, totoplevel, toprove;
445
LIST targettermvars, varsfortoplevel;
452
newtarget = term_Copy(oldtarget);
453
term_AddFatherLinks(newtarget);
454
targettermvars = varsfortoplevel = list_Nil();
456
if (cnf_ContainsPredicate(newtarget, term_TopSymbol(def_Predicate(Def)),
457
&targetpredicate, &totoplevel, &targettermvars,
461
/* Check if definition is not always applicable */
462
if (term_Equal(def_ToProve(Def), term_Null())) {
464
newtarget = cnf_ApplyDefinitionOnce(def_Predicate(Def), term_Copy(def_Expansion(Def)),
465
newtarget, targetpredicate, FlagStore);
466
if (oldtarget != Term)
467
term_Delete(oldtarget);
468
oldtarget = newtarget;
469
list_Delete(targettermvars);
470
list_Delete(varsfortoplevel);
473
toprove = term_Copy(def_ToProve(Def));
474
newtarget = cnf_DefTargetConvert(newtarget, totoplevel, toprove,
475
term_ArgumentList(def_Predicate(Def)),
476
term_ArgumentList(targetpredicate),
477
targettermvars, varsfortoplevel,
478
FlagStore, Precedence,
480
list_Delete(targettermvars);
481
list_Delete(varsfortoplevel);
483
newtarget = cnf_ApplyDefinitionOnce(def_Predicate(Def), term_Copy(def_Expansion(Def)),
484
newtarget, targetpredicate, FlagStore);
485
if (oldtarget != Term)
486
term_Delete(oldtarget);
487
oldtarget = newtarget;
490
/* Predicate still exists but cannot be expanded */
491
term_Delete(newtarget);
492
if (oldtarget == Term)
495
oldtarget = cnf_ObviousSimplifications(oldtarget);
503
/* Predicate does no longer exist */
504
term_Delete(newtarget);
505
/* No expansion possible */
506
if (oldtarget == Term)
509
oldtarget = cnf_ObviousSimplifications(oldtarget);
514
return NULL; /* Unreachable */
517
TERM def_ApplyDefToTermExhaustive(PROOFSEARCH Search, TERM Term)
518
/**************************************************************
519
INPUT: A proofsearch object and a term.
520
RETURNS: An expanded term.
521
NOTE: All occurences of defined predicates are expanded in the term,
522
until no further changes are possible.
523
CAUTION: If cyclic definitions exist, this will crash.
524
***************************************************************/
526
TERM oldterm, newterm;
529
PRECEDENCE Precedence;
533
FlagStore = prfs_Store(Search);
534
Precedence = prfs_Precedence(Search);
539
/* Apply all definitions to term until no more changes occur */
540
for (l=prfs_Definitions(Search); !list_Empty(l); l=list_Cdr(l)) {
541
newterm = def_ApplyDefToTermOnce((DEF) list_Car(l), oldterm,
542
FlagStore, Precedence, &complete);
543
if (newterm != NULL) {
545
term_Delete(oldterm);
557
LIST def_ApplyDefToClauseOnce(DEF Def, CLAUSE Clause,
558
FLAGSTORE FlagStore, PRECEDENCE Precedence)
559
/**************************************************************
560
INPUT: A DEF structure, a clause, a flag store and a
562
RETURNS: A list of new clauses.
563
NOTE: The clause is not changed.
564
All occurences of the defined predicate are expanded
565
in the clause and in the derived clauses.
566
***************************************************************/
570
result = list_List(Clause);
572
for (l = result; !list_Empty(l); l = list_Cdr(l)) {
573
if (clause_ContainsSymbol((CLAUSE) list_Car(l),
574
term_TopSymbol(def_Predicate(Def)))) {
575
result = list_Nconc(result,
576
cnf_ApplyDefinitionToClause((CLAUSE) list_Car(l),
579
FlagStore, Precedence));
580
/* Remove temporary clause */
581
if ((CLAUSE) list_Car(l) != Clause)
582
clause_Delete((CLAUSE) list_Car(l));
583
list_Rplaca(l, NULL);
586
result = list_PointerDeleteElement(result, NULL);
588
/* Make sure the original clause is no longer in the list */
589
if (!list_Empty(result))
590
if (list_First(result) == Clause)
591
result = list_Pop(result);
593
for (l = result; !list_Empty(l); l=list_Cdr(l)) {
595
c = (CLAUSE) list_Car(l);
596
if (def_Conjecture(Def))
597
clause_SetFlag((CLAUSE) list_Car(l), CONCLAUSE);
598
clause_SetFromDefApplication(c);
599
clause_SetParentClauses(c, list_Cons((POINTER) clause_Number(Clause),
600
list_Copy(def_ClauseNumberList(Def))));
601
/* Parent literal is not available, as the predicate may occur several
602
times in the target clause */
603
clause_SetParentLiterals(c, list_Cons((POINTER) 0,
604
list_Copy(def_ClauseLitsList(Def))));
609
LIST def_ApplyDefToClauseExhaustive(PROOFSEARCH Search, CLAUSE Clause)
610
/**************************************************************
611
INPUT: A proofsearch object and a clause.
612
RETURNS: A list of derived clauses.
613
NOTE: All occurences of defined predicates are expanded in the clause.
614
until no further changes are possible.
615
CAUTION: If cyclic definitions exist, this will crash.
616
***************************************************************/
618
LIST newclauses, scan, result;
621
PRECEDENCE Precedence;
623
orig = clause_Copy(Clause);
624
newclauses = list_List(orig);
626
FlagStore = prfs_Store(Search);
627
Precedence = prfs_Precedence(Search);
629
while (!list_Empty(newclauses)) {
630
/* Check all clauses */
633
/* List of clauses derived from newclauses by expanding predicates */
634
nextlist = list_Nil();
636
for (l=newclauses; !list_Empty(l); l=list_Cdr(l)) {
640
c = (CLAUSE) list_Car(l);
642
/* Apply all definitions to the clause */
644
/* List of clauses derived from one clause in newclauses by */
645
/* expanding all possible predicates */
646
clauses = list_Nil();
648
for (scan=prfs_Definitions(Search); !list_Empty(scan); scan=list_Cdr(scan))
649
clauses = list_Nconc(clauses, def_ApplyDefToClauseOnce((DEF) list_Car(scan), c, FlagStore, Precedence));
651
/* If expansions were made delete old clause */
652
if (!list_Empty(clauses)) {
655
if (flag_GetFlagIntValue(FlagStore, flag_DOCPROOF)) {
656
prfs_InsertDocProofClause(Search, c);
661
nextlist = list_Nconc(nextlist, clauses);
664
/* No more expansions possible for this clause */
665
/* If it is not the original clause, add it to the result list */
667
result = list_Cons(c, result);
670
list_Delete(newclauses);
671
newclauses = nextlist;
678
void def_Print(DEF D)
679
/**************************************************************
680
INPUT: A DEF structure.
682
EFFECT: Prints the definition to stdout.
683
***************************************************************/
686
fputs("\n\nAtom: ", stdout);
687
fol_PrettyPrint(def_Predicate(D));
688
fputs("\nExpansion: \n", stdout);
689
fol_PrettyPrint(def_Expansion(D));
690
if (!list_Empty(def_ClauseNumberList(D))) {
691
fputs("\nParent clauses: ", stdout);
692
for (scan = def_ClauseNumberList(D), scan2 = def_ClauseLitsList(D);
693
!list_Empty(scan); scan = list_Cdr(scan), scan2 = list_Cdr(scan2))
694
printf("%d.%d ", (NAT) list_Car(scan), (NAT) list_Car(scan2));
696
fputs("\nDerived from conjecture clauses.", stdout);
698
fputs("\nNot derived from conjecture clauses.", stdout);
701
fputs("\nLabel: ", stdout);
702
fputs(def_Label(D), stdout);
704
if (def_ToProve(D) != NULL)
705
fol_PrettyPrint(def_ToProve(D));
707
fputs("Nothing.", stdout);
710
fputs("\nAttributes: ", stdout);
711
if (def_HasAttribute(D, ISEQUALITY) || def_HasAttribute(D, PREDOCCURONCE)) {
712
if (def_HasAttribute(D, ISEQUALITY))
713
fputs(" Equality ", stdout);
714
if (def_HasAttribute(D, PREDOCCURONCE))
715
fputs(" No Multiple Occurrences ", stdout);
718
fputs(" None ", stdout);
722
LIST def_ApplyDefToClauselist(PROOFSEARCH Search, DEF Def,
723
LIST Clauselist, BOOL Destructive)
724
/**************************************************************
725
INPUT: A proofsearch object, a DEF structure, a list of unshared clauses
726
and a boolean saying whether the parent clause of an expansion
729
EFFECT: For each occurrence of the defined predicate in a clause in the list,
730
a new clause with expanded predicate is added to the list.
731
***************************************************************/
733
LIST l, newclauses, allnew;
735
PRECEDENCE Precedence;
738
FlagStore = prfs_Store(Search);
739
Precedence = prfs_Precedence(Search);
741
for (l = Clauselist; !list_Empty(l); l = list_Cdr(l)) {
742
newclauses = def_ApplyDefToClauseOnce(Def, (CLAUSE) list_Car(l),
743
FlagStore, Precedence);
744
/* Expansions were possible, delete the original clause */
745
if (Destructive && !list_Empty(newclauses)) {
746
if (flag_GetFlagIntValue(FlagStore, flag_DOCPROOF))
747
prfs_InsertDocProofClause(Search, (CLAUSE) list_Car(l));
749
clause_Delete((CLAUSE) list_Car(l));
750
list_Rplaca(l, NULL);
752
allnew = list_Nconc(allnew, newclauses);
755
Clauselist = list_PointerDeleteElement(Clauselist, NULL);
758
if (flag_GetFlagIntValue(FlagStore, flag_PAPPLYDEFS)) {
759
if (!list_Empty(allnew)) {
760
fputs("\nNew clauses after applying definitions : \n", stdout);
761
clause_ListPrint(allnew);
765
Clauselist = list_Nconc(Clauselist, allnew);
769
LIST def_ApplyDefToTermlist(DEF Def, LIST Termlist,
770
FLAGSTORE FlagStore, PRECEDENCE Precedence,
771
BOOL* Complete, BOOL Destructive)
772
/**************************************************************
773
INPUT: A DEF structure and a list of pairs (label, term),
774
a flag store, a precedence and a pointer to a
776
If Destructive is TRUE the father of an expanded
778
RETURNS: The changed list of terms.
779
EFFECT: For each occurrence of the defined predicate in a
780
term in the list, a new term with expanded predicate
781
is added to the list.
782
If every occurrence of the predicate could be
783
expanded, Complete is set to TRUE.
784
***************************************************************/
788
newterms = list_Nil();
791
for (l=Termlist; !list_Empty(l); l=list_Cdr(l)) {
795
oldterm = list_PairSecond(list_Car(l));
796
newterm = def_ApplyDefToTermOnce(Def, oldterm, FlagStore,
797
Precedence, &complete);
800
/* destructive part of function */
801
if (newterm != NULL) {
802
newterms = list_Cons(list_PairCreate(NULL, newterm),newterms);
804
/* Delete oldterm from Termlist */
805
term_Delete(list_PairSecond(list_Car(l)));
806
if (list_PairFirst(list_Car(l)) != NULL)
807
string_StringFree(list_PairFirst(list_Car(l)));
809
list_PairFree(list_Car(l));
810
list_Rplaca(l, NULL);
814
Termlist = list_PointerDeleteElement(Termlist, NULL);
816
if (flag_GetFlagIntValue(FlagStore, flag_PAPPLYDEFS)) {
817
if (!list_Empty(newterms)) {
818
fputs("\n\nNew terms after applying definitions : \n", stdout);
819
for (l=newterms; !list_Empty(l); l=list_Cdr(l)) {
821
fol_PrettyPrint(list_PairSecond(list_Car(l)));
826
Termlist = list_Nconc(Termlist, newterms);
830
void def_ExtractDefsFromTermlist(PROOFSEARCH Search, LIST Axioms, LIST Conj)
831
/**************************************************************
832
INPUT: A proofsearch object and 2 lists of pairs label/term.
834
EFFECT: Add all found definitions to the proofsearch object.
835
The old list of definitions in the proofsearch object is
837
***************************************************************/
842
deflist = list_Nil();
843
FlagStore = prfs_Store(Search);
845
for (l=Axioms; !list_Empty(l); l=list_Cdr(l)) {
846
fol_NormalizeVars(list_PairSecond(list_Car(l))); /* Is needed for proper variable match ! */
847
deflist = list_Nconc(deflist,
848
def_ExtractDefsFromTerm(list_PairSecond(list_Car(l)),
849
list_PairFirst(list_Car(l))));
851
for (l=Conj; !list_Empty(l); l=list_Cdr(l)) {
852
fol_NormalizeVars(list_PairSecond(list_Car(l))); /* Is needed for proper variable match ! */
853
deflist = list_Nconc(deflist,
854
def_ExtractDefsFromTerm(list_PairSecond(list_Car(l)),
855
list_PairFirst(list_Car(l))));
857
for (l=deflist; !list_Empty(l); l=list_Cdr(l))
858
symbol_AddProperty(term_TopSymbol(def_Predicate(list_Car(l))), ISDEF);
860
prfs_SetDefinitions(Search, list_Nconc(prfs_Definitions(Search), deflist));
862
if (flag_GetFlagIntValue(FlagStore, flag_PAPPLYDEFS)) {
863
if (!list_Empty(deflist)) {
864
fputs("\nFound definitions :\n", stdout);
865
for (l = prfs_Definitions(Search); !list_Empty(l); l = list_Cdr(l)) {
866
def_Print(list_Car(l));
867
fputs("\n---\n", stdout);
873
LIST def_FlattenWithOneDefinition(PROOFSEARCH Search, DEF Def)
874
/**************************************************************
875
INPUT: A proofsearch object and one definition.
876
RETURNS: The list of new definitions.
877
EFFECT: For every occurrence of the defined predicate among the other
878
definitions an expansion is attempted.
879
A new definition is only created if the result of the expansion is
881
The proofsearch object is not changed.
882
***************************************************************/
886
PRECEDENCE Precedence;
888
newdefinitions = list_Nil();
889
FlagStore = prfs_Store(Search);
890
Precedence = prfs_Precedence(Search);
892
if (def_ToProve(Def) == NULL) {
895
definitions = prfs_Definitions(Search);
897
for (l = definitions; !list_Empty(l); l=list_Cdr(l)) {
900
d = (DEF) list_Car(l);
902
/* Expansion possible */
903
if (term_ContainsSymbol(def_Expansion(d), term_TopSymbol(def_Predicate(Def)))) {
904
/* Resulting term is still a definition */
905
if (!term_ContainsSymbol(def_Expansion(Def), term_TopSymbol(def_Predicate(d)))) {
909
newexpansion = def_ApplyDefToTermOnce(Def, def_Expansion(d),
910
FlagStore, Precedence,
913
newdef = def_CreateFromTerm(newexpansion,
914
term_Copy(def_Predicate(d)),
915
term_Copy(def_ToProve(d)), def_Label(d));
916
newdefinitions = list_Cons(newdef, newdefinitions);
923
return newdefinitions;
927
void def_FlattenWithOneDefinitionDestructive(PROOFSEARCH Search, DEF Def)
928
/**************************************************************
929
INPUT: A proofsearch object and one definition.
931
EFFECT: If the definition is always applicable, every occurrence of the
932
defined predicate among the other definitions is expanded in place.
933
If the resulting term is no longer a definition, it is deleted from
934
the proofsearch object.
936
CAUTION: This function changes the list entries in the list of definitions
937
in the proofsearch object, so do not call it from a loop over
939
***************************************************************/
942
PRECEDENCE Precedence;
944
FlagStore = prfs_Store(Search);
945
Precedence = prfs_Precedence(Search);
947
if (def_ToProve(Def) == NULL) {
950
definitions = prfs_Definitions(Search);
951
for (l = definitions; !list_Empty(l); l = list_Cdr(l)) {
954
d = (DEF) list_Car(l);
956
/* Expansion possible */
957
if (term_ContainsSymbol(def_Expansion(d), term_TopSymbol(def_Predicate(Def)))) {
958
/* Resulting term is still a definition */
959
if (!term_ContainsSymbol(def_Expansion(Def), term_TopSymbol(def_Predicate(d)))) {
963
newexpansion = def_ApplyDefToTermOnce(Def, def_Expansion(d), FlagStore, Precedence, &complete);
964
term_Delete(def_Expansion(d));
965
def_RplacExp(d, newexpansion);
968
symbol_RemoveProperty(term_TopSymbol(def_Predicate(d)), ISDEF);
970
list_Rplaca(l, NULL);
975
/* Remove given definition */
976
list_Rplaca(l, NULL);
979
symbol_RemoveProperty(term_TopSymbol(def_Predicate(Def)), ISDEF);
981
definitions = list_PointerDeleteElement(definitions, NULL);
982
prfs_SetDefinitions(Search, definitions);
986
void def_FlattenWithOneDefinitionSemiDestructive(PROOFSEARCH Search, DEF Def)
987
/**************************************************************
988
INPUT: A proofsearch object and one definition.
990
EFFECT: If the definition can be applied to another definition
991
in the search object, that definition is destructively changed.
992
If the resulting term is no longer a definition, it is deleted to
994
The applied definition Def is NOT deleted.
995
CAUTION: After calling this function some entries of the definitions list
996
in the proofsearch object may be NULL.
997
***************************************************************/
1000
PRECEDENCE Precedence;
1002
FlagStore = prfs_Store(Search);
1003
Precedence = prfs_Precedence(Search);
1005
if (def_ToProve(Def) == NULL) {
1006
LIST definitions, l;
1008
definitions = prfs_Definitions(Search);
1009
for (l = definitions; !list_Empty(l); l=list_Cdr(l)) {
1012
d = (DEF) list_Car(l);
1014
/* Expansion possible */
1015
if (term_ContainsSymbol(def_Expansion(d), term_TopSymbol(def_Predicate(Def)))) {
1016
/* Resulting term is still a definition */
1017
if (!term_ContainsSymbol(def_Expansion(Def), term_TopSymbol(def_Predicate(d)))) {
1021
newexpansion = def_ApplyDefToTermOnce(Def, def_Expansion(d),
1022
FlagStore, Precedence,
1024
term_Delete(def_Expansion(d));
1025
def_RplacExp(d, newexpansion);
1028
symbol_RemoveProperty(term_TopSymbol(def_Predicate(d)), ISDEF);
1030
list_Rplaca(l, NULL);
1038
void def_FlattenDefinitionsDestructive(PROOFSEARCH Search)
1039
/**************************************************************
1040
INPUT: A proofsearch object.
1042
EFFECT: For every definition that is always applicable try to
1043
expand the predicate in other
1044
definitions if possible.
1045
***************************************************************/
1049
for (l = prfs_Definitions(Search); !list_Empty(l); l=list_Cdr(l)) {
1052
d = (DEF) list_Car(l);
1053
fol_PrettyPrintDFG(def_Predicate(d));
1055
def_FlattenWithOneDefinitionSemiDestructive(Search, d);
1057
prfs_SetDefinitions(Search, list_PointerDeleteElement(prfs_Definitions(Search), NULL));
1060
LIST def_GetTermsForProof(TERM Term, TERM SubTerm, int Polarity)
1061
/**************************************************************
1062
INPUT: Two formulas, <Term> and <SubTerm> which must be subformula
1063
of <Term>,an int which is the polarity of <SubTerm> in its
1064
superterm and a list of variables <Variables>.
1065
RETURN: A list of formulas that are used to prove the guard of Atom.
1066
COMMENT: Helpfunction of def_FindProofFor Guard.
1067
CAUTION: Father links must be set. Free variables may exist in terms of
1070
***************************************************************/
1072
TERM SuperTerm, AddToList;
1074
LIST Scan1, NewList;
1076
term_AddFatherLinks(Term);
1079
if (!fol_CheckFormula(Term)) {
1080
misc_StartErrorReport();
1081
misc_ErrorReport("\n In def_GetTermsForProof: Illegal input Term.");
1082
misc_FinishErrorReport();
1086
if (Term == SubTerm)
1089
SuperTerm = term_Superterm(SubTerm);
1090
Top = term_TopSymbol(SuperTerm);
1091
NewList = list_Nil();
1092
AddToList = term_Null();
1094
if (symbol_Equal(Top, fol_Not()))
1095
return def_GetTermsForProof(Term, SuperTerm, -1*Polarity);
1097
if (symbol_Equal(Top, fol_Or()) && Polarity == 1) {
1098
/* Get and store AddToList */
1099
for (Scan1 = term_ArgumentList(SuperTerm); !list_Empty(Scan1); Scan1 = list_Cdr(Scan1)) {
1100
if (!term_HasPointerSubterm(list_Car(Scan1), SubTerm))
1101
NewList = list_Cons(term_Create(fol_Not(),list_List(term_Copy(list_Car(Scan1)))), NewList);
1102
/* NewList's elements have the form not(term) */
1104
if (list_Length(NewList) == 1) {
1105
AddToList = list_Car(NewList);
1106
list_Delete(NewList);
1109
AddToList = term_Create(fol_And(), NewList);
1111
return list_Cons(AddToList, def_GetTermsForProof(Term, SuperTerm, Polarity));
1113
if (symbol_Equal(Top, fol_And()) && Polarity == -1) {
1114
/* Get and store AddToList */
1115
if (list_Length(term_ArgumentList(SuperTerm)) == 2) {
1116
if (!term_HasPointerSubterm(term_FirstArgument(SuperTerm), SubTerm)) {
1117
AddToList = term_Copy(term_FirstArgument(SuperTerm));
1120
AddToList = term_Copy(term_SecondArgument(SuperTerm));
1123
else if (list_Length(term_ArgumentList(SuperTerm)) > 2) {
1124
for (Scan1 = term_ArgumentList(SuperTerm); !list_Empty(Scan1); Scan1 = list_Cdr(Scan1)) {
1125
if (!term_HasPointerSubterm(list_Car(Scan1), SubTerm))
1126
NewList = list_Cons(term_Copy(list_Car(Scan1)), NewList);
1128
AddToList = term_Create(fol_And(), NewList);
1130
else { /* Only one argument */
1131
AddToList = term_Copy(term_FirstArgument(SuperTerm));
1133
return list_Cons(AddToList, def_GetTermsForProof(Term, SuperTerm, Polarity));
1135
if (symbol_Equal(Top, fol_Implies())) {
1136
if (term_HasPointerSubterm(term_SecondArgument(SuperTerm), SubTerm) && Polarity == 1) {
1137
AddToList = term_Copy(term_FirstArgument(SuperTerm));
1138
return list_Cons(AddToList, def_GetTermsForProof(Term, SuperTerm, Polarity));
1140
if (term_HasPointerSubterm(term_FirstArgument(SuperTerm), SubTerm) && Polarity == -1) {
1141
AddToList = term_Copy(term_SecondArgument(SuperTerm));
1142
AddToList = term_Create(fol_Not(), list_List(AddToList));
1143
return list_Cons(AddToList, def_GetTermsForProof(Term, SuperTerm, -1*Polarity));
1146
if (symbol_Equal(Top, fol_Implied())) { /* symmetric to fol_Implies */
1147
if (term_HasPointerSubterm(term_SecondArgument(SuperTerm), SubTerm) && Polarity == -1) {
1148
AddToList = term_Copy(term_FirstArgument(SuperTerm));
1149
AddToList = term_Create(fol_Not(), list_List(AddToList));
1150
return list_Cons(AddToList, def_GetTermsForProof(Term, SuperTerm, -1*Polarity));
1152
if (term_HasPointerSubterm(term_FirstArgument(SuperTerm), SubTerm) && Polarity == 1) {
1153
AddToList = term_Copy(term_SecondArgument(SuperTerm));
1154
return list_Cons(AddToList, def_GetTermsForProof(Term, SuperTerm, Polarity));
1157
if (fol_IsQuantifier(Top))
1158
return def_GetTermsForProof(Term, SuperTerm, Polarity);
1160
/* In all other cases, SubTerm is the top level term in which Atom occurs disjunctively */
1165
BOOL def_FindProofForGuard(TERM Term, TERM Atom, TERM Guard, FLAGSTORE FlagStore, PRECEDENCE Precedence)
1166
/**************************************************************************
1167
INPUT: A formula Term, an atom Atom, a term Guard a flag store and a
1169
RETURNS: True iff a proof can be found for Guard in Term.
1170
***************************************************************************/
1173
TERM ToProve, Conjecture;
1174
LIST ArgList, FreeVars;
1176
ArgList = list_Nil();
1177
FreeVars = list_Nil();
1178
ToProve = term_Null();
1179
Conjecture = term_Copy(Term);
1182
if (!fol_CheckFormula(Term)) {
1183
misc_StartErrorReport();
1184
misc_ErrorReport("\n In def_FindProofForGuard: No correct formula term.");
1185
misc_FinishErrorReport();
1187
if (!term_HasPointerSubterm(Term, Atom)) {
1188
misc_StartErrorReport();
1189
misc_ErrorReport("\n In def_FindProofForGuard: Illegal input.");
1190
misc_FinishErrorReport();
1194
ArgList = def_GetTermsForProof(Term, Atom, 1);
1196
if (!list_Empty(ArgList)) {
1197
ToProve = term_Create(fol_And(), ArgList);
1198
FreeVars = list_Nconc(fol_FreeVariables(ToProve), fol_FreeVariables(Guard));
1199
FreeVars = term_DeleteDuplicatesFromList(FreeVars);
1200
term_CopyTermsInList(FreeVars);
1202
ArgList = list_List(term_Copy(Guard));
1203
ArgList = list_Cons(ToProve, ArgList);
1204
ToProve = term_Create(fol_Implies(), ArgList);
1205
ToProve = fol_CreateQuantifier(fol_All(), FreeVars, list_List(ToProve));
1207
/* Now ToProve has the form <forall[]: A implies Guard> */
1208
/* puts("\n*ToProve: "); fol_PrettyPrintDFG(ToProve); */
1211
if (!fol_CheckFormula(ToProve)) {
1212
misc_StartErrorReport();
1213
misc_ErrorReport("\n In def_FindProofForGuard: No correct formula ToProve.");
1214
misc_FinishErrorReport();
1218
LocallyTrue = cnf_HaveProof(list_Nil(), ToProve, FlagStore, Precedence);
1219
term_Delete(ToProve);
1220
term_Delete(Conjecture);
1224
else { /* empty list */
1225
term_DeleteTermList(ArgList);
1226
term_Delete(Conjecture);
1232
LIST def_ApplyDefinitionToTermList(LIST Defs, LIST Terms,
1233
FLAGSTORE Flags, PRECEDENCE Precedence)
1234
/**************************************************************************
1235
INPUT: A list of definitions <Defs> and a list of pairs (Label.Formula),
1236
the maximal number <Applics> of expansions, a flag store and a
1238
RETURNS: The possibly destructively changed list <Terms>.
1239
EFFECT: In all formulas of Terms any definition of Defs is applied exactly
1241
The terms are changed destructively if the expanded def_predicate
1243
**************************************************************************/
1245
TERM ActTerm; /* Actual term in Terms */
1246
TERM DefPredicate; /* Actual definition predicate out of Defs */
1247
TERM Expansion; /* Expansion term of the definition */
1248
TERM Target; /* Target predicate to be replaced */
1249
LIST TargetList, Scan1, Scan2, Scan3;
1254
TargetList = list_Nil();
1255
Applics = flag_GetFlagIntValue(Flags, flag_APPLYDEFS);
1257
while (Apply && Applics != 0) {
1260
for (Scan1=Defs; !list_Empty(Scan1) && Applics != 0; Scan1=list_Cdr(Scan1)) {
1261
DefPredicate = term_Copy(def_Predicate(list_Car(Scan1)));
1263
/* puts("\n----\nDefPred:"); fol_PrettyPrintDFG(DefPredicate);*/
1265
for (Scan2=Terms; !list_Empty(Scan2) && Applics != 0; Scan2=list_Cdr(Scan2)) {
1266
ActTerm = list_PairSecond(list_Car(Scan2));
1267
TargetList = term_FindAllAtoms(ActTerm, term_TopSymbol(DefPredicate));
1268
term_AddFatherLinks(ActTerm);
1270
/* puts("\nActTerm:"); fol_PrettyPrintDFG(ActTerm);*/
1272
for (Scan3=TargetList; !list_Empty(Scan3) && Applics != 0; Scan3=list_Cdr(Scan3)) {
1273
Target = list_Car(Scan3);
1274
cont_StartBinding();
1276
/* puts("\nTarget:"); fol_PrettyPrintDFG(Target);*/
1278
if (unify_Match(cont_LeftContext(), DefPredicate, Target)) {
1280
Expansion = term_Copy(def_Expansion(list_Car(Scan1)));
1281
fol_NormalizeVarsStartingAt(ActTerm, term_MaxVar(Expansion));
1282
unify_Match(cont_LeftContext(), DefPredicate, Target);
1284
if (fol_ApplyContextToTerm(cont_LeftContext(), Expansion)) { /* Matcher applied on Expansion */
1285
if (!def_HasGuard(list_Car(Scan1))) {
1288
/* puts("\n*no Guard!");*/
1289
term_RplacTop(Target, term_TopSymbol(Expansion));
1290
term_DeleteTermList(term_ArgumentList(Target));
1291
term_RplacArgumentList(Target, term_ArgumentList(Expansion));
1292
term_RplacArgumentList(Expansion, list_Nil());
1293
term_AddFatherLinks(ActTerm);
1295
if (!fol_CheckFormula(ActTerm)) {
1296
misc_StartErrorReport();
1297
misc_ErrorReport("\n In def_ApplyDefinitionToTermList:");
1298
misc_ErrorReport(" No correct formula ActTerm.");
1299
misc_FinishErrorReport();
1302
if (flag_GetFlagIntValue(Flags, flag_PAPPLYDEFS)) {
1303
puts("\nApplied definition for");
1304
fol_PrettyPrintDFG(def_Predicate(list_Car(Scan1)));
1305
puts("\nNew formula:");
1306
fol_PrettyPrintDFG(ActTerm);
1309
else { /* check guard */
1311
Guard = term_Copy(def_ToProve(list_Car(Scan1)));
1312
if (fol_ApplyContextToTerm(cont_LeftContext(), Guard)) {
1314
if (def_FindProofForGuard(ActTerm, Target,Guard,
1315
Flags, Precedence)) {
1318
term_RplacTop(Target, term_TopSymbol(Expansion));
1319
term_DeleteTermList(term_ArgumentList(Target));
1320
term_RplacArgumentList(Target, term_ArgumentList(Expansion));
1321
term_RplacArgumentList(Expansion, list_Nil());
1322
term_AddFatherLinks(ActTerm);
1324
if (!fol_CheckFormula(ActTerm)) {
1325
misc_StartErrorReport();
1326
misc_ErrorReport("\n In def_ApplyDefinitionToTermList:");
1327
misc_ErrorReport(" No correct formula ActTerm");
1328
misc_FinishErrorReport();
1331
if (flag_GetFlagIntValue(Flags, flag_PAPPLYDEFS)) {
1332
puts("\nApplied definition for");
1333
fol_PrettyPrintDFG(def_Predicate(list_Car(Scan1)));
1334
puts("\nNew formula:");
1335
fol_PrettyPrintDFG(ActTerm);
1342
term_Delete(Expansion);
1346
list_Delete(TargetList);
1348
term_Delete(DefPredicate);