| /**************************************************************/ |
| /* ********************************************************** */ |
| /* * * */ |
| /* * DEFINITIONS * */ |
| /* * * */ |
| /* * $Module: DEFS * */ |
| /* * * */ |
| /* * Copyright (C) 1998, 1999, 2000, 2001 * */ |
| /* * MPI fuer Informatik * */ |
| /* * * */ |
| /* * This program is free software; you can redistribute * */ |
| /* * it and/or modify it under the terms of the GNU * */ |
| /* * General Public License as published by the Free * */ |
| /* * Software Foundation; either version 2 of the License, * */ |
| /* * or (at your option) any later version. * */ |
| /* * * */ |
| /* * This program is distributed in the hope that it will * */ |
| /* * be useful, but WITHOUT ANY WARRANTY; without even * */ |
| /* * the implied warranty of MERCHANTABILITY or FITNESS * */ |
| /* * FOR A PARTICULAR PURPOSE. See the GNU General Public * */ |
| /* * License for more details. * */ |
| /* * * */ |
| /* * You should have received a copy of the GNU General * */ |
| /* * Public License along with this program; if not, write * */ |
| /* * to the Free Software Foundation, Inc., 59 Temple * */ |
| /* * Place, Suite 330, Boston, MA 02111-1307 USA * */ |
| /* * * */ |
| /* * * */ |
| /* $Revision$ * */ |
| /* $State$ * */ |
| /* $Date$ * */ |
| /* $Author$ * */ |
| /* * * */ |
| /* * Contact: * */ |
| /* * Christoph Weidenbach * */ |
| /* * MPI fuer Informatik * */ |
| /* * Stuhlsatzenhausweg 85 * */ |
| /* * 66123 Saarbruecken * */ |
| /* * Email: weidenb@mpi-sb.mpg.de * */ |
| /* * Germany * */ |
| /* * * */ |
| /* ********************************************************** */ |
| /**************************************************************/ |
| |
| |
| /* $RCSfile$ */ |
| |
| #include "cnf.h" |
| #include "defs.h" |
| #include "foldfg.h" |
| |
| static void def_DeleteFromClauses(DEF); |
| static void def_DeleteFromTerm(DEF); |
| |
| DEF def_CreateFromClauses(TERM ExpTerm, TERM PredTerm, LIST Clauses, LIST Lits, |
| BOOL Con) |
| /********************************************************** |
| INPUT: Two terms, a list of clausenumbers, a list of literal indices and |
| a boolean saying whether all clauses derived by expanding the |
| predicate should be conclauses. |
| RETURNS: A definition consisting of the 2 terms as expansion term and |
| predicate term and the list of parent clause numbers and a list |
| of the indices of the defined predicate in the parent clauses. |
| ToProve and label are set to NULL. |
| ********************************************************/ |
| { |
| DEF result; |
| |
| #ifdef CHECK |
| if (!term_IsTerm(ExpTerm) || !term_IsTerm(PredTerm)) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In def_CreateFromClause: Illegal input."); |
| misc_FinishErrorReport(); |
| } |
| if (list_Empty(Clauses)) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In def_CreateFromClause: No parent clause given."); |
| misc_FinishErrorReport(); |
| } |
| #endif |
| |
| result = (DEF) memory_Malloc(sizeof(DEF_NODE)); |
| result->expansion = ExpTerm; |
| result->predicate = PredTerm; |
| result->toprove = (TERM) NULL; |
| result->parentclauses = list_PairCreate(Clauses, Lits); |
| result->label = (const char*) NULL; |
| result->conjecture = Con; |
| |
| return result; |
| } |
| |
| DEF def_CreateFromTerm(TERM ExpTerm, TERM PredTerm, TERM ToProve, const char* Label) |
| /********************************************************** |
| INPUT: 3 terms and a term label. |
| RETURNS: A definition consisting of the 3 terms as expansion term, |
| predicate term and term to prove before applying the |
| definition and the label of the parent term. |
| The list of clausenumbers is set to NULL. |
| ********************************************************/ |
| { |
| DEF result; |
| |
| #ifdef CHECK |
| if (!term_IsTerm(ExpTerm) || !term_IsTerm(PredTerm)) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In def_CreateFromTerm: Illegal input."); |
| misc_FinishErrorReport(); |
| } |
| if (Label == NULL) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In def_CreateFromTerm: No parent clause given."); |
| misc_FinishErrorReport(); |
| } |
| #endif |
| |
| result = (DEF) memory_Malloc(sizeof(DEF_NODE)); |
| result->expansion = ExpTerm; |
| result->predicate = PredTerm; |
| result->toprove = ToProve; |
| result->parentclauses = list_PairCreate(list_Nil(), list_Nil()); |
| result->label = Label; |
| result->conjecture = FALSE; |
| |
| return result; |
| } |
| |
| static void def_DeleteFromClauses(DEF D) |
| /********************************************************** |
| INPUT: A definition derived from clauses. |
| EFFECT: The definition is deleted, INCLUDING THE TERMS AND |
| THE LIST OF CLAUSE NUMBERS. |
| ********************************************************/ |
| { |
| #ifdef CHECK |
| if (!term_IsTerm(def_Expansion(D)) || !term_IsTerm(def_Predicate(D))) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In def_DeleteFormClauses: Illegal input."); |
| misc_FinishErrorReport(); |
| } |
| #endif |
| |
| /* ToProve and Label are NULL */ |
| term_Delete(def_Expansion(D)); |
| term_Delete(def_Predicate(D)); |
| list_Delete(def_ClauseNumberList(D)); |
| list_Delete(def_ClauseLitsList(D)); |
| list_PairFree(D->parentclauses); |
| |
| memory_Free(D, sizeof(DEF_NODE)); |
| } |
| |
| static void def_DeleteFromTerm(DEF D) |
| /********************************************************** |
| INPUT: A definition derived from a term. |
| EFFECT: The definition is deleted, INCLUDING THE TERMS. |
| THE LABEL IS NOT FREED. |
| ********************************************************/ |
| { |
| #ifdef CHECK |
| if (!term_IsTerm(def_Expansion(D)) || !term_IsTerm(def_Predicate(D))) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In def_DeleteFromTerm: Illegal input."); |
| misc_FinishErrorReport(); |
| } |
| #endif |
| |
| /* List of clausenumbers is NULL */ |
| term_Delete(def_Expansion(D)); |
| term_Delete(def_Predicate(D)); |
| if (def_ToProve(D) != (TERM) NULL) |
| term_Delete(def_ToProve(D)); |
| list_PairFree(D->parentclauses); |
| memory_Free(D, sizeof(DEF_NODE)); |
| } |
| |
| void def_Delete(DEF D) |
| /********************************************************** |
| INPUT: A definition derived from a term. |
| EFFECT: The definition is deleted. |
| CAUTION: All elements of the definition except of the label are freed. |
| ********************************************************/ |
| { |
| if (!list_Empty(def_ClauseNumberList(D))) |
| def_DeleteFromClauses(D); |
| else |
| def_DeleteFromTerm(D); |
| } |
| |
| int def_PredicateOccurrences(TERM Term, SYMBOL P) |
| /**************************************************** |
| INPUT: A term and a predicate symbol. |
| RETURNS: The number of occurrences of the predicate symbol in Term |
| **************************************************/ |
| { |
| /* Quantifiers */ |
| if (fol_IsQuantifier(term_TopSymbol(Term))) |
| return def_PredicateOccurrences(term_SecondArgument(Term), P); |
| |
| /* Junctors and NOT */ |
| if (fol_IsJunctor(term_TopSymbol(Term)) || |
| symbol_Equal(term_TopSymbol(Term),fol_Not())){ |
| LIST scan; |
| int count; |
| count = 0; |
| for (scan=term_ArgumentList(Term); !list_Empty(scan); scan=list_Cdr(scan)) { |
| count += def_PredicateOccurrences((TERM) list_Car(scan), P); |
| /* Only the cases count==1 and count>1 are important */ |
| if (count > 1) |
| return count; |
| } |
| return count; |
| } |
| |
| if (symbol_Equal(term_TopSymbol(Term), P)) |
| return 1; |
| return 0; |
| } |
| |
| LIST def_ExtractDefsFromTerm(TERM Term, const char* Label) |
| /************************************************************** |
| INPUT: A term and its label. |
| RETURNS: A list of definitions found in the term. |
| NOTE: The Term is not changed, the definitions contain copies. |
| ***************************************************************/ |
| { |
| TERM andterm; |
| BOOL found; |
| int pol; |
| LIST univars, termlist, defslist, scan; |
| |
| /* First check if there is a top level and() so that the Term may |
| contain several definitions */ |
| |
| andterm = Term; |
| found = FALSE; |
| pol = 1; |
| univars = list_Nil(); |
| |
| /* Traverse top down universal quantifiers */ |
| while (!found) { |
| if ((symbol_Equal(term_TopSymbol(andterm), fol_All()) && (pol == 1)) |
| || (symbol_Equal(term_TopSymbol(andterm), fol_Exist()) && (pol == -1))) { |
| univars = list_Nconc(univars, list_Copy(fol_QuantifierVariables(andterm))); |
| andterm = term_SecondArgument(andterm); |
| } |
| else { |
| if (symbol_Equal(term_TopSymbol(andterm), fol_Not())) { |
| pol = -pol; |
| andterm = term_FirstArgument(andterm); |
| } |
| else |
| found = TRUE; |
| } |
| } |
| |
| termlist = list_Nil(); |
| /* Check if conjunction was found */ |
| if ((symbol_Equal(term_TopSymbol(andterm), fol_And()) && (pol == 1)) |
| || (symbol_Equal(term_TopSymbol(andterm), fol_Or()) && (pol == -1))) { |
| LIST l; |
| /* Flatten nested and/or */ |
| /* Make copy of relevant subterm */ |
| andterm = cnf_Flatten(term_Copy(andterm), term_TopSymbol(andterm)); |
| for (l=term_ArgumentList(andterm); !list_Empty(l); l=list_Cdr(l)) { |
| TERM newterm; |
| newterm = fol_CreateQuantifierAddFather(fol_All(), term_CopyTermList(univars), |
| list_List(list_Car(l))); |
| termlist = list_Cons(newterm, termlist); |
| } |
| /* Arguments are used in new terms */ |
| list_Delete(term_ArgumentList(andterm)); |
| term_Free(andterm); |
| } |
| else |
| termlist = list_List(term_Copy(Term)); |
| |
| list_Delete(univars); |
| |
| /* Now we have a list of terms that may contain definitions */ |
| defslist = list_Nil(); |
| for (scan=termlist; !list_Empty(scan); scan=list_Cdr(scan)) { |
| TERM cand; |
| TERM foundpred, toprove; |
| |
| /* Candidate from list */ |
| cand = (TERM) list_Car(scan); |
| term_AddFatherLinks(cand); |
| |
| if (cnf_ContainsDefinition(cand, &foundpred)) { |
| DEF def; |
| #ifdef CHECK |
| if (!fol_CheckFormula(cand)) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In def_ExtractDefsFromTerm: Illegal term cand"); |
| misc_FinishErrorReport(); |
| } |
| #endif |
| cand = cnf_DefConvert(cand, foundpred, &toprove); |
| #ifdef CHECK |
| if (!fol_CheckFormula(cand)) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In def_ExtractDefsFromTerm: Illegal term cand"); |
| misc_FinishErrorReport(); |
| } |
| #endif |
| def = def_CreateFromTerm(term_Copy(term_SecondArgument(term_Superterm(foundpred))), |
| term_Copy(foundpred), toprove, Label); |
| |
| if (def_PredicateOccurrences(cand, term_TopSymbol(foundpred)) > 1) |
| def_RemoveAttribute(def, PREDOCCURONCE); |
| else |
| def_AddAttribute(def, PREDOCCURONCE); |
| if (symbol_Equal(term_TopSymbol(foundpred), fol_Equality())) |
| def_AddAttribute(def, ISEQUALITY); |
| else |
| def_RemoveAttribute(def, ISEQUALITY); |
| |
| defslist = list_Cons(def, defslist); |
| } |
| term_Delete(cand); |
| } |
| |
| list_Delete(termlist); |
| return defslist; |
| } |
| |
| void def_ExtractDefsFromClauselist(PROOFSEARCH Search, LIST Clauselist) |
| /************************************************************** |
| INPUT: A proofsearch object and a list of clauses |
| RETURNS: Nothing. |
| EFFECT: The definitions found in the clauselist object are stored in |
| the proofsearch object. |
| NOTE: The clause list is not changed. |
| The old list of definitions in the proofsearch object is |
| overwritten. |
| ***************************************************************/ |
| { |
| LIST scan, defslist; |
| FLAGSTORE FlagStore; |
| PRECEDENCE Precedence; |
| |
| defslist = list_Nil(); |
| FlagStore = prfs_Store(Search); |
| Precedence = prfs_Precedence(Search); |
| |
| for (scan=Clauselist; !list_Empty(scan); scan=list_Cdr(scan)) { |
| CLAUSE Clause; |
| NAT index; |
| LIST pair; |
| |
| Clause = (CLAUSE) list_Car(scan); |
| /* Check if clause contains a predicate that may be part of a definition */ |
| if (clause_ContainsPotPredDef(Clause, FlagStore, Precedence, &index, &pair)) { |
| LIST l, compl, compllits; |
| BOOL done; |
| |
| compl = compllits = list_Nil(); |
| done = FALSE; |
| |
| /* Search for complement clauses */ |
| for (l=Clauselist; !list_Empty(l) && !done; l=list_Cdr(l)) { |
| int predindex; |
| if (clause_IsPartOfDefinition((CLAUSE) list_Car(l), |
| clause_GetLiteralTerm(Clause, index), |
| &predindex, pair)) { |
| compl = list_Cons(list_Car(l), compl); |
| compllits = list_Cons((POINTER) predindex, compllits); |
| |
| if (list_Empty(list_PairFirst(pair)) && |
| list_Empty(list_PairSecond(pair))) |
| done = TRUE; |
| } |
| } |
| |
| /* All complements found ? */ |
| if (done) { |
| LIST l2, clausenumbers, args; |
| DEF def; |
| NAT i; |
| TERM defterm, predterm; |
| BOOL con; |
| |
| clausenumbers = list_Nil(); |
| con = clause_GetFlag(Clause, CONCLAUSE); |
| |
| for (l2=compl; !list_Empty(l2); l2=list_Cdr(l2)) { |
| clausenumbers = list_Cons((POINTER) clause_Number((CLAUSE) list_Car(l2)), |
| clausenumbers); |
| if (clause_GetFlag((CLAUSE) list_Car(l2), CONCLAUSE)) |
| con = TRUE; |
| } |
| clausenumbers = list_Cons((POINTER) clause_Number(Clause), |
| clausenumbers); |
| compllits = list_Cons((POINTER) index, compllits); |
| |
| /* Build definition term */ |
| predterm = term_Copy(clause_GetLiteralTerm(Clause, index)); |
| args = list_Nil(); |
| for (i = 0; i < clause_Length(Clause); i++) |
| if (i != index) |
| args = list_Cons(term_Copy(clause_GetLiteralTerm(Clause, i)), args); |
| defterm = term_CreateAddFather(fol_Or(), args); |
| /* The expansion is negative here, so it must be inverted */ |
| defterm = term_Create(fol_Not(), list_List(defterm)); |
| defterm = cnf_NegationNormalFormula(defterm); |
| def = def_CreateFromClauses(defterm, predterm, clausenumbers, compllits, con); |
| defslist = list_Cons(def, defslist); |
| if (flag_GetFlagValue(FlagStore, flag_PAPPLYDEFS)) { |
| fputs("\nNew definition found :", stdout); |
| def_Print(def); |
| } |
| } |
| else { |
| list_Delete(compllits); |
| list_Delete(list_PairSecond(pair)); |
| list_Delete(list_PairFirst(pair)); |
| } |
| list_Delete(compl); |
| list_PairFree(pair); |
| } |
| } |
| |
| if (flag_GetFlagValue(FlagStore, flag_PAPPLYDEFS)) { |
| if (!list_Empty(defslist)) { |
| fputs("\nFound definitions :\n", stdout); |
| for (scan = defslist; !list_Empty(scan); scan = list_Cdr(scan)) { |
| def_Print((DEF) list_Car(scan)); |
| fputs("\n---\n", stdout); |
| } |
| } |
| } |
| |
| for (scan=defslist; !list_Empty(scan); scan=list_Cdr(scan)) |
| symbol_AddProperty(term_TopSymbol(def_Predicate((DEF) list_Car(scan))), ISDEF); |
| |
| prfs_SetDefinitions(Search, list_Nconc(prfs_Definitions(Search), defslist)); |
| } |
| |
| TERM def_ApplyDefToTermOnce(DEF Def, TERM Term, FLAGSTORE FlagStore, |
| PRECEDENCE Precedence, BOOL* Complete) |
| /************************************************************** |
| INPUT: A DEF structure, a term and a boolean that is set |
| to TRUE if no occurrences of the defined predicate |
| remain in the term. A flag store and a precedence. |
| RETURNS: A term where all occurrences of the definitions |
| predicate are expanded if possible. |
| NOTE: The Term is not changed. |
| ***************************************************************/ |
| { |
| TERM newtarget, oldtarget, targetpredicate, totoplevel, toprove; |
| LIST targettermvars, varsfortoplevel; |
| BOOL applicable; |
| |
| oldtarget = Term; |
| *Complete = TRUE; |
| |
| while (TRUE) { |
| newtarget = term_Copy(oldtarget); |
| term_AddFatherLinks(newtarget); |
| targettermvars = varsfortoplevel = list_Nil(); |
| |
| if (cnf_ContainsPredicate(newtarget, term_TopSymbol(def_Predicate(Def)), |
| &targetpredicate, &totoplevel, &targettermvars, |
| &varsfortoplevel)) { |
| *Complete = FALSE; |
| applicable = FALSE; |
| /* Check if definition is not always applicable */ |
| if (term_Equal(def_ToProve(Def), term_Null())) { |
| applicable = TRUE; |
| newtarget = cnf_ApplyDefinitionOnce(def_Predicate(Def), term_Copy(def_Expansion(Def)), |
| newtarget, targetpredicate, FlagStore); |
| if (oldtarget != Term) |
| term_Delete(oldtarget); |
| oldtarget = newtarget; |
| list_Delete(targettermvars); |
| list_Delete(varsfortoplevel); |
| } |
| else { |
| toprove = term_Copy(def_ToProve(Def)); |
| newtarget = cnf_DefTargetConvert(newtarget, totoplevel, toprove, |
| term_ArgumentList(def_Predicate(Def)), |
| term_ArgumentList(targetpredicate), |
| targettermvars, varsfortoplevel, |
| FlagStore, Precedence, |
| &applicable); |
| list_Delete(targettermvars); |
| list_Delete(varsfortoplevel); |
| if (applicable) { |
| newtarget = cnf_ApplyDefinitionOnce(def_Predicate(Def), term_Copy(def_Expansion(Def)), |
| newtarget, targetpredicate, FlagStore); |
| if (oldtarget != Term) |
| term_Delete(oldtarget); |
| oldtarget = newtarget; |
| } |
| else { |
| /* Predicate still exists but cannot be expanded */ |
| term_Delete(newtarget); |
| if (oldtarget == Term) |
| return NULL; |
| else { |
| oldtarget = cnf_ObviousSimplifications(oldtarget); |
| return oldtarget; |
| } |
| } |
| } |
| } |
| else { |
| *Complete = TRUE; |
| /* Predicate does no longer exist */ |
| term_Delete(newtarget); |
| /* No expansion possible */ |
| if (oldtarget == Term) |
| return NULL; |
| else { |
| oldtarget = cnf_ObviousSimplifications(oldtarget); |
| return oldtarget; |
| } |
| } |
| } |
| return NULL; /* Unreachable */ |
| } |
| |
| TERM def_ApplyDefToTermExhaustive(PROOFSEARCH Search, TERM Term) |
| /************************************************************** |
| INPUT: A proofsearch object and a term. |
| RETURNS: An expanded term. |
| NOTE: All occurences of defined predicates are expanded in the term, |
| until no further changes are possible. |
| CAUTION: If cyclic definitions exist, this will crash. |
| ***************************************************************/ |
| { |
| TERM oldterm, newterm; |
| BOOL done, complete; |
| FLAGSTORE FlagStore; |
| PRECEDENCE Precedence; |
| |
| done = FALSE; |
| oldterm = Term; |
| FlagStore = prfs_Store(Search); |
| Precedence = prfs_Precedence(Search); |
| |
| while (!done) { |
| LIST l; |
| done = TRUE; |
| /* Apply all definitions to term until no more changes occur */ |
| for (l=prfs_Definitions(Search); !list_Empty(l); l=list_Cdr(l)) { |
| newterm = def_ApplyDefToTermOnce((DEF) list_Car(l), oldterm, |
| FlagStore, Precedence, &complete); |
| if (newterm != NULL) { |
| if (oldterm != Term) |
| term_Delete(oldterm); |
| oldterm = newterm; |
| done = FALSE; |
| } |
| } |
| } |
| if (oldterm == Term) |
| return NULL; |
| else |
| return oldterm; |
| } |
| |
| LIST def_ApplyDefToClauseOnce(DEF Def, CLAUSE Clause, |
| FLAGSTORE FlagStore, PRECEDENCE Precedence) |
| /************************************************************** |
| INPUT: A DEF structure, a clause, a flag store and a |
| precedence. |
| RETURNS: A list of new clauses. |
| NOTE: The clause is not changed. |
| All occurences of the defined predicate are expanded |
| in the clause and in the derived clauses. |
| ***************************************************************/ |
| { |
| LIST result, l; |
| |
| result = list_List(Clause); |
| |
| for (l = result; !list_Empty(l); l = list_Cdr(l)) { |
| if (clause_ContainsSymbol((CLAUSE) list_Car(l), |
| term_TopSymbol(def_Predicate(Def)))) { |
| result = list_Nconc(result, |
| cnf_ApplyDefinitionToClause((CLAUSE) list_Car(l), |
| def_Predicate(Def), |
| def_Expansion(Def), |
| FlagStore, Precedence)); |
| /* Remove temporary clause */ |
| if ((CLAUSE) list_Car(l) != Clause) |
| clause_Delete((CLAUSE) list_Car(l)); |
| list_Rplaca(l, NULL); |
| } |
| } |
| result = list_PointerDeleteElement(result, NULL); |
| |
| /* Make sure the original clause is no longer in the list */ |
| if (!list_Empty(result)) |
| if (list_First(result) == Clause) |
| result = list_Pop(result); |
| |
| for (l = result; !list_Empty(l); l=list_Cdr(l)) { |
| CLAUSE c; |
| c = (CLAUSE) list_Car(l); |
| if (def_Conjecture(Def)) |
| clause_SetFlag((CLAUSE) list_Car(l), CONCLAUSE); |
| clause_SetFromDefApplication(c); |
| clause_SetParentClauses(c, list_Cons((POINTER) clause_Number(Clause), |
| list_Copy(def_ClauseNumberList(Def)))); |
| /* Parent literal is not available, as the predicate may occur several |
| times in the target clause */ |
| clause_SetParentLiterals(c, list_Cons((POINTER) 0, |
| list_Copy(def_ClauseLitsList(Def)))); |
| } |
| return result; |
| } |
| |
| LIST def_ApplyDefToClauseExhaustive(PROOFSEARCH Search, CLAUSE Clause) |
| /************************************************************** |
| INPUT: A proofsearch object and a clause. |
| RETURNS: A list of derived clauses. |
| NOTE: All occurences of defined predicates are expanded in the clause. |
| until no further changes are possible. |
| CAUTION: If cyclic definitions exist, this will crash. |
| ***************************************************************/ |
| { |
| LIST newclauses, scan, result; |
| CLAUSE orig; |
| FLAGSTORE FlagStore; |
| PRECEDENCE Precedence; |
| |
| orig = clause_Copy(Clause); |
| newclauses = list_List(orig); |
| result = list_Nil(); |
| FlagStore = prfs_Store(Search); |
| Precedence = prfs_Precedence(Search); |
| |
| while (!list_Empty(newclauses)) { |
| /* Check all clauses */ |
| LIST l, nextlist; |
| |
| /* List of clauses derived from newclauses by expanding predicates */ |
| nextlist = list_Nil(); |
| |
| for (l=newclauses; !list_Empty(l); l=list_Cdr(l)) { |
| LIST clauses; |
| CLAUSE c; |
| |
| c = (CLAUSE) list_Car(l); |
| |
| /* Apply all definitions to the clause */ |
| |
| /* List of clauses derived from one clause in newclauses by */ |
| /* expanding all possible predicates */ |
| clauses = list_Nil(); |
| |
| for (scan=prfs_Definitions(Search); !list_Empty(scan); scan=list_Cdr(scan)) |
| clauses = list_Nconc(clauses, def_ApplyDefToClauseOnce((DEF) list_Car(scan), c, FlagStore, Precedence)); |
| |
| /* If expansions were made delete old clause */ |
| if (!list_Empty(clauses)) { |
| /* DOCPROOF ? */ |
| if (c != Clause) { |
| if (flag_GetFlagValue(FlagStore, flag_DOCPROOF)) { |
| prfs_InsertDocProofClause(Search, c); |
| } |
| else |
| clause_Delete(c); |
| } |
| nextlist = list_Nconc(nextlist, clauses); |
| } |
| else { |
| /* No more expansions possible for this clause */ |
| /* If it is not the original clause, add it to the result list */ |
| if (c != Clause) |
| result = list_Cons(c, result); |
| } |
| } |
| list_Delete(newclauses); |
| newclauses = nextlist; |
| } |
| |
| return result; |
| } |
| |
| |
| void def_Print(DEF D) |
| /************************************************************** |
| INPUT: A DEF structure. |
| RETURNS: None. |
| EFFECT: Prints the definition to stdout. |
| ***************************************************************/ |
| { |
| LIST scan, scan2; |
| fputs("\n\nAtom: ", stdout); |
| fol_PrettyPrint(def_Predicate(D)); |
| fputs("\nExpansion: \n", stdout); |
| fol_PrettyPrint(def_Expansion(D)); |
| if (!list_Empty(def_ClauseNumberList(D))) { |
| fputs("\nParent clauses: ", stdout); |
| for (scan = def_ClauseNumberList(D), scan2 = def_ClauseLitsList(D); |
| !list_Empty(scan); scan = list_Cdr(scan), scan2 = list_Cdr(scan2)) |
| printf("%d.%d ", (NAT) list_Car(scan), (NAT) list_Car(scan2)); |
| if (D->conjecture) |
| fputs("\nDerived from conjecture clauses.", stdout); |
| else |
| fputs("\nNot derived from conjecture clauses.", stdout); |
| } |
| else { |
| fputs("\nLabel: ", stdout); |
| fputs(def_Label(D), stdout); |
| puts("\nGuard:"); |
| if (def_ToProve(D) != NULL) |
| fol_PrettyPrint(def_ToProve(D)); |
| else |
| fputs("Nothing.", stdout); |
| } |
| |
| fputs("\nAttributes: ", stdout); |
| if (def_HasAttribute(D, ISEQUALITY) || def_HasAttribute(D, PREDOCCURONCE)) { |
| if (def_HasAttribute(D, ISEQUALITY)) |
| fputs(" Equality ", stdout); |
| if (def_HasAttribute(D, PREDOCCURONCE)) |
| fputs(" No Multiple Occurrences ", stdout); |
| } |
| else { |
| fputs(" None ", stdout); |
| } |
| } |
| |
| LIST def_ApplyDefToClauselist(PROOFSEARCH Search, DEF Def, |
| LIST Clauselist, BOOL Destructive) |
| /************************************************************** |
| INPUT: A proofsearch object, a DEF structure, a list of unshared clauses |
| and a boolean saying whether the parent clause of an expansion |
| should be deleted. |
| RETURNS: None. |
| EFFECT: For each occurrence of the defined predicate in a clause in the list, |
| a new clause with expanded predicate is added to the list. |
| ***************************************************************/ |
| { |
| LIST l, newclauses, allnew; |
| FLAGSTORE FlagStore; |
| PRECEDENCE Precedence; |
| |
| allnew = list_Nil(); |
| FlagStore = prfs_Store(Search); |
| Precedence = prfs_Precedence(Search); |
| |
| for (l = Clauselist; !list_Empty(l); l = list_Cdr(l)) { |
| newclauses = def_ApplyDefToClauseOnce(Def, (CLAUSE) list_Car(l), |
| FlagStore, Precedence); |
| /* Expansions were possible, delete the original clause */ |
| if (Destructive && !list_Empty(newclauses)) { |
| if (flag_GetFlagValue(FlagStore, flag_DOCPROOF)) |
| prfs_InsertDocProofClause(Search, (CLAUSE) list_Car(l)); |
| else |
| clause_Delete((CLAUSE) list_Car(l)); |
| list_Rplaca(l, NULL); |
| } |
| allnew = list_Nconc(allnew, newclauses); |
| } |
| if (Destructive) |
| Clauselist = list_PointerDeleteElement(Clauselist, NULL); |
| |
| |
| if (flag_GetFlagValue(FlagStore, flag_PAPPLYDEFS)) { |
| if (!list_Empty(allnew)) { |
| fputs("\nNew clauses after applying definitions : \n", stdout); |
| clause_ListPrint(allnew); |
| } |
| } |
| |
| Clauselist = list_Nconc(Clauselist, allnew); |
| return Clauselist; |
| } |
| |
| LIST def_ApplyDefToTermlist(DEF Def, LIST Termlist, |
| FLAGSTORE FlagStore, PRECEDENCE Precedence, |
| BOOL* Complete, BOOL Destructive) |
| /************************************************************** |
| INPUT: A DEF structure and a list of pairs (label, term), |
| a flag store, a precedence and a pointer to a |
| boolean. |
| If Destructive is TRUE the father of an expanded |
| term is deleted. |
| RETURNS: The changed list of terms. |
| EFFECT: For each occurrence of the defined predicate in a |
| term in the list, a new term with expanded predicate |
| is added to the list. |
| If every occurrence of the predicate could be |
| expanded, Complete is set to TRUE. |
| ***************************************************************/ |
| { |
| LIST l, newterms; |
| |
| newterms = list_Nil(); |
| |
| *Complete = TRUE; |
| for (l=Termlist; !list_Empty(l); l=list_Cdr(l)) { |
| TERM newterm; |
| TERM oldterm; |
| BOOL complete; |
| oldterm = list_PairSecond(list_Car(l)); |
| newterm = def_ApplyDefToTermOnce(Def, oldterm, FlagStore, |
| Precedence, &complete); |
| if (!complete) |
| *Complete = FALSE; |
| /* destructive part of function */ |
| if (newterm != NULL) { |
| newterms = list_Cons(list_PairCreate(NULL, newterm),newterms); |
| if (Destructive) { |
| /* Delete oldterm from Termlist */ |
| term_Delete(list_PairSecond(list_Car(l))); |
| if (list_PairFirst(list_Car(l)) != NULL) |
| string_StringFree(list_PairFirst(list_Car(l))); |
| |
| list_PairFree(list_Car(l)); |
| list_Rplaca(l, NULL); |
| } |
| } |
| } |
| Termlist = list_PointerDeleteElement(Termlist, NULL); |
| |
| if (flag_GetFlagValue(FlagStore, flag_PAPPLYDEFS)) { |
| if (!list_Empty(newterms)) { |
| fputs("\n\nNew terms after applying definitions : \n", stdout); |
| for (l=newterms; !list_Empty(l); l=list_Cdr(l)) { |
| fputs("\n", stdout); |
| fol_PrettyPrint(list_PairSecond(list_Car(l))); |
| } |
| } |
| } |
| |
| Termlist = list_Nconc(Termlist, newterms); |
| return Termlist; |
| } |
| |
| void def_ExtractDefsFromTermlist(PROOFSEARCH Search, LIST Axioms, LIST Conj) |
| /************************************************************** |
| INPUT: A proofsearch object and 2 lists of pairs label/term. |
| RETURNS: None. |
| EFFECT: Add all found definitions to the proofsearch object. |
| The old list of definitions in the proofsearch object is |
| overwritten. |
| ***************************************************************/ |
| { |
| LIST l, deflist; |
| FLAGSTORE FlagStore; |
| |
| deflist = list_Nil(); |
| FlagStore = prfs_Store(Search); |
| |
| for (l=Axioms; !list_Empty(l); l=list_Cdr(l)) { |
| fol_NormalizeVars(list_PairSecond(list_Car(l))); /* Is needed for proper variable match ! */ |
| deflist = list_Nconc(deflist, |
| def_ExtractDefsFromTerm(list_PairSecond(list_Car(l)), |
| list_PairFirst(list_Car(l)))); |
| } |
| for (l=Conj; !list_Empty(l); l=list_Cdr(l)) { |
| fol_NormalizeVars(list_PairSecond(list_Car(l))); /* Is needed for proper variable match ! */ |
| deflist = list_Nconc(deflist, |
| def_ExtractDefsFromTerm(list_PairSecond(list_Car(l)), |
| list_PairFirst(list_Car(l)))); |
| } |
| for (l=deflist; !list_Empty(l); l=list_Cdr(l)) |
| symbol_AddProperty(term_TopSymbol(def_Predicate(list_Car(l))), ISDEF); |
| |
| prfs_SetDefinitions(Search, list_Nconc(prfs_Definitions(Search), deflist)); |
| |
| if (flag_GetFlagValue(FlagStore, flag_PAPPLYDEFS)) { |
| if (!list_Empty(deflist)) { |
| fputs("\nFound definitions :\n", stdout); |
| for (l = prfs_Definitions(Search); !list_Empty(l); l = list_Cdr(l)) { |
| def_Print(list_Car(l)); |
| fputs("\n---\n", stdout); |
| } |
| } |
| } |
| } |
| |
| LIST def_FlattenWithOneDefinition(PROOFSEARCH Search, DEF Def) |
| /************************************************************** |
| INPUT: A proofsearch object and one definition. |
| RETURNS: The list of new definitions. |
| EFFECT: For every occurrence of the defined predicate among the other |
| definitions an expansion is attempted. |
| A new definition is only created if the result of the expansion is |
| again a definition. |
| The proofsearch object is not changed. |
| ***************************************************************/ |
| { |
| LIST newdefinitions; |
| FLAGSTORE FlagStore; |
| PRECEDENCE Precedence; |
| |
| newdefinitions = list_Nil(); |
| FlagStore = prfs_Store(Search); |
| Precedence = prfs_Precedence(Search); |
| |
| if (def_ToProve(Def) == NULL) { |
| LIST definitions, l; |
| |
| definitions = prfs_Definitions(Search); |
| |
| for (l = definitions; !list_Empty(l); l=list_Cdr(l)) { |
| DEF d; |
| |
| d = (DEF) list_Car(l); |
| if (d != Def) { |
| /* Expansion possible */ |
| if (term_ContainsSymbol(def_Expansion(d), term_TopSymbol(def_Predicate(Def)))) { |
| /* Resulting term is still a definition */ |
| if (!term_ContainsSymbol(def_Expansion(Def), term_TopSymbol(def_Predicate(d)))) { |
| TERM newexpansion; |
| BOOL complete; |
| DEF newdef; |
| newexpansion = def_ApplyDefToTermOnce(Def, def_Expansion(d), |
| FlagStore, Precedence, |
| &complete); |
| |
| newdef = def_CreateFromTerm(newexpansion, |
| term_Copy(def_Predicate(d)), |
| term_Copy(def_ToProve(d)), def_Label(d)); |
| newdefinitions = list_Cons(newdef, newdefinitions); |
| } |
| } |
| } |
| |
| } |
| } |
| return newdefinitions; |
| } |
| |
| |
| void def_FlattenWithOneDefinitionDestructive(PROOFSEARCH Search, DEF Def) |
| /************************************************************** |
| INPUT: A proofsearch object and one definition. |
| RETURNS: None. |
| EFFECT: If the definition is always applicable, every occurrence of the |
| defined predicate among the other definitions is expanded in place. |
| If the resulting term is no longer a definition, it is deleted from |
| the proofsearch object. |
| Def is deleted. |
| CAUTION: This function changes the list entries in the list of definitions |
| in the proofsearch object, so do not call it from a loop over |
| all definitions. |
| ***************************************************************/ |
| { |
| FLAGSTORE FlagStore; |
| PRECEDENCE Precedence; |
| |
| FlagStore = prfs_Store(Search); |
| Precedence = prfs_Precedence(Search); |
| |
| if (def_ToProve(Def) == NULL) { |
| LIST definitions, l; |
| |
| definitions = prfs_Definitions(Search); |
| for (l = definitions; !list_Empty(l); l = list_Cdr(l)) { |
| DEF d; |
| |
| d = (DEF) list_Car(l); |
| if (d != Def) { |
| /* Expansion possible */ |
| if (term_ContainsSymbol(def_Expansion(d), term_TopSymbol(def_Predicate(Def)))) { |
| /* Resulting term is still a definition */ |
| if (!term_ContainsSymbol(def_Expansion(Def), term_TopSymbol(def_Predicate(d)))) { |
| TERM newexpansion; |
| BOOL complete; |
| |
| newexpansion = def_ApplyDefToTermOnce(Def, def_Expansion(d), FlagStore, Precedence, &complete); |
| term_Delete(def_Expansion(d)); |
| def_RplacExp(d, newexpansion); |
| } |
| else { |
| symbol_RemoveProperty(term_TopSymbol(def_Predicate(d)), ISDEF); |
| def_Delete(d); |
| list_Rplaca(l, NULL); |
| } |
| } |
| } |
| else { |
| /* Remove given definition */ |
| list_Rplaca(l, NULL); |
| } |
| } |
| symbol_RemoveProperty(term_TopSymbol(def_Predicate(Def)), ISDEF); |
| def_Delete(Def); |
| definitions = list_PointerDeleteElement(definitions, NULL); |
| prfs_SetDefinitions(Search, definitions); |
| } |
| } |
| |
| void def_FlattenWithOneDefinitionSemiDestructive(PROOFSEARCH Search, DEF Def) |
| /************************************************************** |
| INPUT: A proofsearch object and one definition. |
| RETURNS: Nothing. |
| EFFECT: If the definition can be applied to another definition |
| in the search object, that definition is destructively changed. |
| If the resulting term is no longer a definition, it is deleted to |
| prevent cycles. |
| The applied definition Def is NOT deleted. |
| CAUTION: After calling this function some entries of the definitions list |
| in the proofsearch object may be NULL. |
| ***************************************************************/ |
| { |
| FLAGSTORE FlagStore; |
| PRECEDENCE Precedence; |
| |
| FlagStore = prfs_Store(Search); |
| Precedence = prfs_Precedence(Search); |
| |
| if (def_ToProve(Def) == NULL) { |
| LIST definitions, l; |
| |
| definitions = prfs_Definitions(Search); |
| for (l = definitions; !list_Empty(l); l=list_Cdr(l)) { |
| DEF d; |
| |
| d = (DEF) list_Car(l); |
| if (d != Def) { |
| /* Expansion possible */ |
| if (term_ContainsSymbol(def_Expansion(d), term_TopSymbol(def_Predicate(Def)))) { |
| /* Resulting term is still a definition */ |
| if (!term_ContainsSymbol(def_Expansion(Def), term_TopSymbol(def_Predicate(d)))) { |
| TERM newexpansion; |
| BOOL complete; |
| |
| newexpansion = def_ApplyDefToTermOnce(Def, def_Expansion(d), |
| FlagStore, Precedence, |
| &complete); |
| term_Delete(def_Expansion(d)); |
| def_RplacExp(d, newexpansion); |
| } |
| else { |
| symbol_RemoveProperty(term_TopSymbol(def_Predicate(d)), ISDEF); |
| def_Delete(d); |
| list_Rplaca(l, NULL); |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| void def_FlattenDefinitionsDestructive(PROOFSEARCH Search) |
| /************************************************************** |
| INPUT: A proofsearch object. |
| RETURNS: None. |
| EFFECT: For every definition that is always applicable try to |
| expand the predicate in other |
| definitions if possible. |
| ***************************************************************/ |
| { |
| LIST l; |
| |
| for (l = prfs_Definitions(Search); !list_Empty(l); l=list_Cdr(l)) { |
| DEF d; |
| |
| d = (DEF) list_Car(l); |
| fol_PrettyPrintDFG(def_Predicate(d)); |
| if (d != NULL) |
| def_FlattenWithOneDefinitionSemiDestructive(Search, d); |
| } |
| prfs_SetDefinitions(Search, list_PointerDeleteElement(prfs_Definitions(Search), NULL)); |
| } |
| |
| LIST def_GetTermsForProof(TERM Term, TERM SubTerm, int Polarity) |
| /************************************************************** |
| INPUT: Two formulas, <Term> and <SubTerm> which must be subformula |
| of <Term>,an int which is the polarity of <SubTerm> in its |
| superterm and a list of variables <Variables>. |
| RETURN: A list of formulas that are used to prove the guard of Atom. |
| COMMENT: Helpfunction of def_FindProofFor Guard. |
| CAUTION: Father links must be set. Free variables may exist in terms of |
| return list. |
| Terms are copied. |
| ***************************************************************/ |
| { |
| TERM SuperTerm, AddToList; |
| SYMBOL Top; |
| LIST Scan1, NewList; |
| |
| term_AddFatherLinks(Term); |
| |
| #ifdef CHECK |
| if (!fol_CheckFormula(Term)) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In def_GetTermsForProof: Illegal input Term."); |
| misc_FinishErrorReport(); |
| } |
| #endif |
| |
| if (Term == SubTerm) |
| return list_Nil(); |
| |
| SuperTerm = term_Superterm(SubTerm); |
| Top = term_TopSymbol(SuperTerm); |
| NewList = list_Nil(); |
| AddToList = term_Null(); |
| |
| if (symbol_Equal(Top, fol_Not())) |
| return def_GetTermsForProof(Term, SuperTerm, -1*Polarity); |
| |
| if (symbol_Equal(Top, fol_Or()) && Polarity == 1) { |
| /* Get and store AddToList */ |
| for (Scan1 = term_ArgumentList(SuperTerm); !list_Empty(Scan1); Scan1 = list_Cdr(Scan1)) { |
| if (!term_HasPointerSubterm(list_Car(Scan1), SubTerm)) |
| NewList = list_Cons(term_Create(fol_Not(),list_List(term_Copy(list_Car(Scan1)))), NewList); |
| /* NewList's elements have the form not(term) */ |
| } |
| if (list_Length(NewList) == 1) { |
| AddToList = list_Car(NewList); |
| list_Delete(NewList); |
| } |
| else { |
| AddToList = term_Create(fol_And(), NewList); |
| } |
| return list_Cons(AddToList, def_GetTermsForProof(Term, SuperTerm, Polarity)); |
| } |
| if (symbol_Equal(Top, fol_And()) && Polarity == -1) { |
| /* Get and store AddToList */ |
| if (list_Length(term_ArgumentList(SuperTerm)) == 2) { |
| if (!term_HasPointerSubterm(term_FirstArgument(SuperTerm), SubTerm)) { |
| AddToList = term_Copy(term_FirstArgument(SuperTerm)); |
| } |
| else { |
| AddToList = term_Copy(term_SecondArgument(SuperTerm)); |
| } |
| } |
| else if (list_Length(term_ArgumentList(SuperTerm)) > 2) { |
| for (Scan1 = term_ArgumentList(SuperTerm); !list_Empty(Scan1); Scan1 = list_Cdr(Scan1)) { |
| if (!term_HasPointerSubterm(list_Car(Scan1), SubTerm)) |
| NewList = list_Cons(term_Copy(list_Car(Scan1)), NewList); |
| } |
| AddToList = term_Create(fol_And(), NewList); |
| } |
| else { /* Only one argument */ |
| AddToList = term_Copy(term_FirstArgument(SuperTerm)); |
| } |
| return list_Cons(AddToList, def_GetTermsForProof(Term, SuperTerm, Polarity)); |
| } |
| if (symbol_Equal(Top, fol_Implies())) { |
| if (term_HasPointerSubterm(term_SecondArgument(SuperTerm), SubTerm) && Polarity == 1) { |
| AddToList = term_Copy(term_FirstArgument(SuperTerm)); |
| return list_Cons(AddToList, def_GetTermsForProof(Term, SuperTerm, Polarity)); |
| } |
| if (term_HasPointerSubterm(term_FirstArgument(SuperTerm), SubTerm) && Polarity == -1) { |
| AddToList = term_Copy(term_SecondArgument(SuperTerm)); |
| AddToList = term_Create(fol_Not(), list_List(AddToList)); |
| return list_Cons(AddToList, def_GetTermsForProof(Term, SuperTerm, -1*Polarity)); |
| } |
| } |
| if (symbol_Equal(Top, fol_Implied())) { /* symmetric to fol_Implies */ |
| if (term_HasPointerSubterm(term_SecondArgument(SuperTerm), SubTerm) && Polarity == -1) { |
| AddToList = term_Copy(term_FirstArgument(SuperTerm)); |
| AddToList = term_Create(fol_Not(), list_List(AddToList)); |
| return list_Cons(AddToList, def_GetTermsForProof(Term, SuperTerm, -1*Polarity)); |
| } |
| if (term_HasPointerSubterm(term_FirstArgument(SuperTerm), SubTerm) && Polarity == 1) { |
| AddToList = term_Copy(term_SecondArgument(SuperTerm)); |
| return list_Cons(AddToList, def_GetTermsForProof(Term, SuperTerm, Polarity)); |
| } |
| } |
| if (fol_IsQuantifier(Top)) |
| return def_GetTermsForProof(Term, SuperTerm, Polarity); |
| |
| /* In all other cases, SubTerm is the top level term in which Atom occurs disjunctively */ |
| |
| return list_Nil(); |
| } |
| |
| BOOL def_FindProofForGuard(TERM Term, TERM Atom, TERM Guard, FLAGSTORE FlagStore, PRECEDENCE Precedence) |
| /************************************************************************** |
| INPUT: A formula Term, an atom Atom, a term Guard a flag store and a |
| precedence. |
| RETURNS: True iff a proof can be found for Guard in Term. |
| ***************************************************************************/ |
| { |
| BOOL LocallyTrue; |
| TERM ToProve, Conjecture; |
| LIST ArgList, FreeVars; |
| |
| ArgList = list_Nil(); |
| FreeVars = list_Nil(); |
| ToProve = term_Null(); |
| Conjecture = term_Copy(Term); |
| |
| #ifdef CHECK |
| if (!fol_CheckFormula(Term)) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In def_FindProofForGuard: No correct formula term."); |
| misc_FinishErrorReport(); |
| } |
| if (!term_HasPointerSubterm(Term, Atom)) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In def_FindProofForGuard: Illegal input."); |
| misc_FinishErrorReport(); |
| } |
| #endif |
| |
| ArgList = def_GetTermsForProof(Term, Atom, 1); |
| |
| if (!list_Empty(ArgList)) { |
| ToProve = term_Create(fol_And(), ArgList); |
| FreeVars = list_Nconc(fol_FreeVariables(ToProve), fol_FreeVariables(Guard)); |
| FreeVars = term_DeleteDuplicatesFromList(FreeVars); |
| term_CopyTermsInList(FreeVars); |
| |
| ArgList = list_List(term_Copy(Guard)); |
| ArgList = list_Cons(ToProve, ArgList); |
| ToProve = term_Create(fol_Implies(), ArgList); |
| ToProve = fol_CreateQuantifier(fol_All(), FreeVars, list_List(ToProve)); |
| |
| /* Now ToProve has the form <forall[]: A implies Guard> */ |
| /* puts("\n*ToProve: "); fol_PrettyPrintDFG(ToProve); */ |
| |
| #ifdef CHECK |
| if (!fol_CheckFormula(ToProve)) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In def_FindProofForGuard: No correct formula ToProve."); |
| misc_FinishErrorReport(); |
| } |
| #endif |
| |
| LocallyTrue = cnf_HaveProof(list_Nil(), ToProve, FlagStore, Precedence); |
| term_Delete(ToProve); |
| term_Delete(Conjecture); |
| if (LocallyTrue) |
| return TRUE; |
| } |
| else { /* empty list */ |
| term_DeleteTermList(ArgList); |
| term_Delete(Conjecture); |
| } |
| |
| return FALSE; |
| } |
| |
| LIST def_ApplyDefinitionToTermList(LIST Defs, LIST Terms, |
| FLAGSTORE Flags, PRECEDENCE Precedence) |
| /************************************************************************** |
| INPUT: A list of definitions <Defs> and a list of pairs (Label.Formula), |
| the maximal number <Applics> of expansions, a flag store and a |
| precedence. |
| RETURNS: The possibly destructively changed list <Terms>. |
| EFFECT: In all formulas of Terms any definition of Defs is applied exactly |
| once if possible. |
| The terms are changed destructively if the expanded def_predicate |
| is not an equality. |
| **************************************************************************/ |
| { |
| TERM ActTerm; /* Actual term in Terms */ |
| TERM DefPredicate; /* Actual definition predicate out of Defs */ |
| TERM Expansion; /* Expansion term of the definition */ |
| TERM Target; /* Target predicate to be replaced */ |
| LIST TargetList, Scan1, Scan2, Scan3; |
| BOOL Apply; |
| int Applics; |
| |
| Apply = TRUE; |
| TargetList = list_Nil(); |
| Applics = flag_GetFlagValue(Flags, flag_APPLYDEFS); |
| |
| while (Apply && Applics != 0) { |
| Apply = FALSE; |
| |
| for (Scan1=Defs; !list_Empty(Scan1) && Applics != 0; Scan1=list_Cdr(Scan1)) { |
| DefPredicate = term_Copy(def_Predicate(list_Car(Scan1))); |
| |
| /* puts("\n----\nDefPred:"); fol_PrettyPrintDFG(DefPredicate);*/ |
| |
| for (Scan2=Terms; !list_Empty(Scan2) && Applics != 0; Scan2=list_Cdr(Scan2)) { |
| ActTerm = list_PairSecond(list_Car(Scan2)); |
| TargetList = term_FindAllAtoms(ActTerm, term_TopSymbol(DefPredicate)); |
| term_AddFatherLinks(ActTerm); |
| |
| /* puts("\nActTerm:"); fol_PrettyPrintDFG(ActTerm);*/ |
| |
| for (Scan3=TargetList; !list_Empty(Scan3) && Applics != 0; Scan3=list_Cdr(Scan3)) { |
| Target = list_Car(Scan3); |
| cont_StartBinding(); |
| |
| /* puts("\nTarget:"); fol_PrettyPrintDFG(Target);*/ |
| |
| if (unify_Match(cont_LeftContext(), DefPredicate, Target)) { |
| cont_BackTrack(); |
| Expansion = term_Copy(def_Expansion(list_Car(Scan1))); |
| fol_NormalizeVarsStartingAt(ActTerm, term_MaxVar(Expansion)); |
| unify_Match(cont_LeftContext(), DefPredicate, Target); |
| |
| if (fol_ApplyContextToTerm(cont_LeftContext(), Expansion)) { /* Matcher applied on Expansion */ |
| if (!def_HasGuard(list_Car(Scan1))) { |
| Applics--; |
| Apply = TRUE; |
| /* puts("\n*no Guard!");*/ |
| term_RplacTop(Target, term_TopSymbol(Expansion)); |
| term_DeleteTermList(term_ArgumentList(Target)); |
| term_RplacArgumentList(Target, term_ArgumentList(Expansion)); |
| term_RplacArgumentList(Expansion, list_Nil()); |
| term_AddFatherLinks(ActTerm); |
| #ifdef CHECK |
| if (!fol_CheckFormula(ActTerm)) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In def_ApplyDefinitionToTermList:"); |
| misc_ErrorReport(" No correct formula ActTerm."); |
| misc_FinishErrorReport(); |
| } |
| #endif |
| if (flag_GetFlagValue(Flags, flag_PAPPLYDEFS)) { |
| puts("\nApplied definition for"); |
| fol_PrettyPrintDFG(def_Predicate(list_Car(Scan1))); |
| puts("\nNew formula:"); |
| fol_PrettyPrintDFG(ActTerm); |
| } |
| } |
| else { /* check guard */ |
| TERM Guard; |
| Guard = term_Copy(def_ToProve(list_Car(Scan1))); |
| if (fol_ApplyContextToTerm(cont_LeftContext(), Guard)) { |
| cont_BackTrack(); |
| if (def_FindProofForGuard(ActTerm, Target,Guard, |
| Flags, Precedence)) { |
| Applics--; |
| Apply = TRUE; |
| term_RplacTop(Target, term_TopSymbol(Expansion)); |
| term_DeleteTermList(term_ArgumentList(Target)); |
| term_RplacArgumentList(Target, term_ArgumentList(Expansion)); |
| term_RplacArgumentList(Expansion, list_Nil()); |
| term_AddFatherLinks(ActTerm); |
| #ifdef CHECK |
| if (!fol_CheckFormula(ActTerm)) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In def_ApplyDefinitionToTermList:"); |
| misc_ErrorReport(" No correct formula ActTerm"); |
| misc_FinishErrorReport(); |
| } |
| #endif |
| if (flag_GetFlagValue(Flags, flag_PAPPLYDEFS)) { |
| puts("\nApplied definition for"); |
| fol_PrettyPrintDFG(def_Predicate(list_Car(Scan1))); |
| puts("\nNew formula:"); |
| fol_PrettyPrintDFG(ActTerm); |
| } |
| } |
| } |
| term_Delete(Guard); |
| } |
| } |
| term_Delete(Expansion); |
| } |
| cont_BackTrack(); |
| } |
| list_Delete(TargetList); |
| } |
| term_Delete(DefPredicate); |
| } |
| } |
| return Terms; |
| } |