| /**************************************************************/ |
| /* ********************************************************** */ |
| /* * * */ |
| /* * INFERENCE RULES FOR SORTS * */ |
| /* * * */ |
| /* * $Module: SORTRULES * */ |
| /* * * */ |
| /* * Copyright (C) 1996, 1997, 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$ */ |
| |
| /**************************************************************/ |
| /* Includes */ |
| /**************************************************************/ |
| |
| #include "rules-sort.h" |
| |
| |
| /**************************************************************/ |
| /* Functions */ |
| /**************************************************************/ |
| |
| static LIST inf_GetForwardPartnerLits(LITERAL, st_INDEX); |
| static SORT inf_GetSortFromLits(LIST, SORTTHEORY); |
| |
| |
| static BOOL inf_SubsortPrecheck(CLAUSE Clause, LIST TLits, LITERAL Special, |
| st_INDEX Index, SORTTHEORY SortTheory) |
| /************************************************************** |
| INPUT: A clause, a list of constraint literal indices in |
| that clause, a special literal, an index of clauses, |
| and the actual sort theory. |
| RETURNS: TRUE, if there exists any subsort of the <TLits> sort. |
| ***************************************************************/ |
| { |
| SORT tSort, unifierSort; |
| LIST unifiers; |
| BOOL result; |
| |
| unifiers = inf_GetForwardPartnerLits(clause_GetLiteral(Clause,(int)list_Car(TLits)), |
| Index); |
| unifierSort = inf_GetSortFromLits(unifiers, SortTheory); |
| list_Delete(unifiers); |
| |
| tSort = sort_TopSort(); |
| for (; !list_Empty(TLits); TLits = list_Cdr(TLits)) { |
| TERM actAtom = clause_GetLiteralAtom(Clause, (int)list_Car(TLits)); |
| tSort = sort_Intersect(sort_TheorySortOfSymbol(SortTheory, term_TopSymbol(actAtom)), |
| tSort); |
| } |
| tSort = list_PointerDeleteDuplicates(tSort); |
| |
| if (Special == NULL) |
| result = sort_TheoryIsSubsortOf(SortTheory, unifierSort, tSort); |
| else { |
| SORT extraSort; |
| extraSort = sort_TheorySortOfSymbol(SortTheory, clause_LiteralPredicate(Special)); |
| result = sort_TheoryIsSubsortOfExtra(SortTheory, extraSort, unifierSort, tSort); |
| sort_Delete(extraSort); |
| } |
| |
| sort_Delete(tSort); |
| sort_Delete(unifierSort); |
| |
| return result; |
| } |
| |
| static LIST inf_GetSortResolutionPartnerLits(TERM Atom, st_INDEX Index) |
| /************************************************************** |
| INPUT: A clause, and an Index of clauses. |
| RETURNS: A list of literals with which sortresolution is possible. |
| MEMORY: Allocates memory for the list. |
| ***************************************************************/ |
| { |
| LIST Result, TermList, LitScan; |
| LITERAL NextLit; |
| CLAUSE Clause; |
| |
| #ifdef CHECK |
| if (!term_IsAtom(Atom)) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In inf_GetSortResolutionPartnerLits: Variable as atom input.\n"); |
| misc_FinishErrorReport(); |
| } |
| #endif |
| |
| Result = list_Nil(); |
| TermList = st_GetUnifier(cont_LeftContext(), Index, cont_RightContext(), Atom); |
| |
| for ( ; !list_Empty(TermList); TermList = list_Pop(TermList)) { |
| |
| if (term_IsAtom(list_Car(TermList))) { |
| |
| for (LitScan = sharing_NAtomDataList(list_Car(TermList)); |
| !list_Empty(LitScan); |
| LitScan = list_Cdr(LitScan)){ |
| NextLit = list_Car(LitScan); |
| Clause = clause_LiteralOwningClause(NextLit); |
| |
| if (clause_LiteralIsPositive(NextLit) && |
| clause_LiteralGetFlag(NextLit,STRICTMAXIMAL) && |
| clause_GetFlag(Clause, WORKEDOFF) && |
| clause_HasSolvedConstraint(Clause) && |
| !list_PointerMember(Result, NextLit)) |
| Result = list_Cons(NextLit, Result); |
| } |
| } |
| } |
| |
| return Result; |
| } |
| |
| |
| static CLAUSE inf_BuildConstraintHyperResolvent(CLAUSE Clause, LIST Lits, |
| SUBST Subst, LIST Foundlits, |
| FLAGSTORE Flags, |
| PRECEDENCE Precedence) |
| /************************************************************** |
| INPUT: A <Clause> where the sort constraint is resolved, |
| a list <Lits> of constraint indices in <Clause> where |
| all corresponding constraints have the same term, |
| the overall substitution <Subst>, |
| a list <Foundlits> of literals of found partner clauses, |
| a flag store and a precedence. |
| RETURNS: A clause, the resolvent of a resolution step. |
| ***************************************************************/ |
| { |
| CLAUSE NewClause, ClauseCopy; |
| LIST Constraint, Antecedent, Succedent, ParentCls, ParentLits, Scan; |
| TERM Atom; |
| SYMBOL MaxVar,MaxCand; |
| int i,bound, depth; |
| BOOL IsFromEmptySort; |
| LIST Partners; |
| |
| ParentCls = list_Nil(); |
| ParentLits = list_Nil(); |
| Constraint = list_Nil(); |
| Antecedent = list_Nil(); |
| Succedent = list_Nil(); |
| Partners = list_Nil(); |
| depth = clause_Depth(Clause); |
| |
| for (Scan=Foundlits; !list_Empty(Scan); Scan=list_Cdr(Scan)) |
| depth = misc_Max(depth, |
| clause_Depth(clause_LiteralOwningClause(list_Car(Scan)))); |
| |
| ClauseCopy = clause_Copy(Clause); |
| Partners = list_Cons(ClauseCopy, Partners); |
| clause_SubstApply(Subst, ClauseCopy); |
| |
| IsFromEmptySort = term_IsVariable(term_FirstArgument( |
| clause_GetLiteralAtom(Clause, (int)list_Car(Lits)))); |
| |
| bound = clause_LastConstraintLitIndex(ClauseCopy); |
| |
| for (i = clause_FirstLitIndex(); i <= bound; i++) |
| if (!list_PointerMember(Lits, (POINTER)i)) { |
| Atom = term_Copy(clause_GetLiteralAtom(ClauseCopy, i)); |
| Constraint = list_Cons(Atom, Constraint); |
| } |
| else { |
| ParentCls = list_Cons((POINTER)clause_Number(ClauseCopy), ParentCls); |
| ParentLits = list_Cons((POINTER)i, ParentLits); |
| } |
| |
| bound = clause_LastAntecedentLitIndex(ClauseCopy); |
| for ( ; i <= bound; i++) { |
| Atom = term_Copy(clause_GetLiteralAtom(ClauseCopy, i)); |
| Antecedent = list_Cons(Atom, Antecedent); |
| } |
| bound = clause_LastSuccedentLitIndex(ClauseCopy); |
| for (; i <= bound; i++) { |
| Atom = term_Copy(clause_GetLiteralAtom(ClauseCopy, i)); |
| Succedent = list_Cons(Atom, Succedent); |
| } |
| bound = clause_LastConstraintLitIndex(Clause); |
| for (i = clause_FirstLitIndex(); i <= bound; i++) { |
| /* Hier sollen die gematchten Constraintliterale dazu fuehren, dass die */ |
| /* c,a und s- literale der Partnerclauses in die Listen kommen... */ |
| |
| if (list_PointerMember(Lits, (POINTER)i)) { |
| CLAUSE PartnerCopy; |
| LITERAL PLit; |
| TERM PAtom; |
| SUBST NewSubst,RightSubst; |
| int j,lc,la,n,PLitInd; |
| |
| Atom = clause_GetLiteralAtom(ClauseCopy, i); |
| NewClause = clause_CreateUnnormalized(Constraint, Antecedent, Succedent); |
| |
| list_Delete(Constraint); |
| list_Delete(Antecedent); |
| list_Delete(Succedent); |
| Constraint = list_Nil(); |
| Antecedent = list_Nil(); |
| Succedent = list_Nil(); |
| |
| /* Find corresponding Foundlit: */ |
| for (Scan = Foundlits; |
| term_TopSymbol(Atom) != |
| term_TopSymbol(clause_LiteralAtom(list_Car(Scan))); |
| Scan = list_Cdr(Scan)); |
| PLit = list_Car(Scan); |
| PLitInd = clause_LiteralGetIndex(PLit); |
| PartnerCopy = clause_Copy(clause_LiteralOwningClause(PLit)); |
| Partners = list_Cons(PartnerCopy, Partners); |
| ParentCls = list_Cons((POINTER)clause_Number(PartnerCopy), ParentCls); |
| ParentLits = list_Cons((POINTER)PLitInd, ParentLits); |
| MaxVar = clause_SearchMaxVar(ClauseCopy); |
| MaxCand = clause_SearchMaxVar(NewClause); |
| MaxVar = ((MaxVar > MaxCand) ? MaxVar : MaxCand); |
| /* MaxVar is the maximal variable in the new clause or the ClauseCopy, */ |
| /* the latter to guarantee the stability of variable names. */ |
| |
| clause_RenameVarsBiggerThan(PartnerCopy, MaxVar); |
| PLit = clause_GetLiteral(PartnerCopy, PLitInd); |
| PAtom = clause_LiteralAtom(PLit); |
| |
| cont_Check(); |
| if (!unify_UnifyNoOC(cont_LeftContext(), PAtom, cont_RightContext(), Atom)) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In inf_BuildConstraintHyperResolvent: Unification failed."); |
| misc_FinishErrorReport(); |
| } |
| subst_ExtractUnifier(cont_LeftContext(), &RightSubst, cont_RightContext(), &NewSubst); |
| cont_Reset(); |
| |
| clause_SubstApply(NewSubst, NewClause); |
| clause_SubstApply(NewSubst, ClauseCopy); |
| subst_Delete(NewSubst); |
| |
| n = clause_Length(PartnerCopy); |
| lc = clause_LastConstraintLitIndex(PartnerCopy); |
| la = clause_LastAntecedentLitIndex(PartnerCopy); |
| for (j = clause_FirstLitIndex(); j < n; j++) { |
| if (j <= lc) |
| Constraint = list_Cons(subst_Apply(RightSubst, |
| term_Copy(clause_GetLiteralAtom(PartnerCopy, j))), |
| Constraint); |
| else if (j <= la) |
| Antecedent = list_Cons(subst_Apply(RightSubst, |
| term_Copy(clause_GetLiteralAtom(PartnerCopy, j))), |
| Antecedent); |
| else if (j != PLitInd) |
| Succedent = list_Cons(subst_Apply(RightSubst, |
| term_Copy(clause_GetLiteralAtom(PartnerCopy, j))), |
| Succedent); |
| } |
| |
| subst_Delete(RightSubst); |
| |
| n = clause_Length(NewClause); |
| lc = clause_LastConstraintLitIndex(NewClause); |
| la = clause_LastAntecedentLitIndex(NewClause); |
| |
| for (j = clause_FirstLitIndex(); j < n; j++) { |
| if (j <= lc) |
| Constraint = list_Cons(term_Copy(clause_GetLiteralAtom(NewClause, j)), |
| Constraint); |
| else if (j <= la) |
| Antecedent = list_Cons(term_Copy(clause_GetLiteralAtom(NewClause, j)), |
| Antecedent); |
| else |
| Succedent = list_Cons(term_Copy(clause_GetLiteralAtom(NewClause, j)), |
| Succedent); |
| } |
| clause_Delete(NewClause); |
| clause_DecreaseCounter(); |
| } |
| } |
| NewClause = clause_Create(Constraint, Antecedent, Succedent, Flags,Precedence); |
| |
| list_Delete(Constraint); |
| list_Delete(Antecedent); |
| list_Delete(Succedent); |
| |
| if (IsFromEmptySort) |
| clause_SetFromEmptySort(NewClause); |
| else |
| clause_SetFromSortResolution(NewClause); |
| |
| clause_SetDepth(NewClause, depth + 1); |
| |
| clause_SetSplitDataFromList(NewClause, Partners); |
| clause_DeleteClauseList(Partners); |
| |
| clause_SetParentClauses(NewClause, list_NReverse(ParentCls)); |
| clause_SetParentLiterals(NewClause, list_NReverse(ParentLits)); |
| |
| return NewClause; |
| } |
| |
| |
| static LIST inf_ConstraintHyperResolvents(CLAUSE Clause, LIST Lits, |
| SUBST Subst, LIST Restlits, |
| LIST Foundlits, st_INDEX Index, |
| FLAGSTORE Flags, PRECEDENCE Precedence) |
| /************************************************************** |
| INPUT: A <Clause> where the sort constraint is resolved, |
| a list <Lits> of constraint indices in <Clause> where |
| all corresponding constraints have the same term, |
| the overall substitution <Subst>, |
| a list <Restlits> of constraint indeces for which |
| a partner clause is searched with respect to <Index>, |
| a list <Foundlits> of literals of already found partner clauses, |
| a flag store and a precedence. |
| RETURNS: The list of possible resolvents. |
| ***************************************************************/ |
| { |
| if (list_Empty(Restlits)) |
| return list_List(inf_BuildConstraintHyperResolvent(Clause,Lits,Subst, |
| Foundlits, Flags, |
| Precedence)); |
| else { |
| CLAUSE PartnerCopy; |
| LITERAL Lit, PLit; |
| LIST Result, NextLits; |
| TERM AtomCopy; |
| SUBST NewSubst, RightSubst, HelpSubst; |
| SYMBOL MaxVar, MaxCand; |
| int PLitInd; |
| |
| Result = list_Nil(); |
| Lit = clause_GetLiteral(Clause, (int) list_Car(Restlits)); |
| AtomCopy = subst_Apply(Subst, term_Copy(clause_LiteralAtom(Lit))); |
| NextLits = inf_GetSortResolutionPartnerLits(AtomCopy,Index); |
| MaxVar = clause_MaxVar(Clause); |
| MaxCand = clause_AtomMaxVar(AtomCopy); |
| MaxVar = (symbol_GreaterVariable(MaxVar, MaxCand) ? MaxVar : MaxCand); |
| |
| for ( ; !list_Empty(NextLits); NextLits = list_Pop(NextLits)) { |
| PLit = list_Car(NextLits); |
| PLitInd = clause_LiteralGetIndex(PLit); |
| Foundlits = list_Cons(PLit, Foundlits); |
| PartnerCopy = clause_Copy(clause_LiteralOwningClause(PLit)); |
| |
| clause_RenameVarsBiggerThan(PartnerCopy, MaxVar); |
| PLit = clause_GetLiteral(PartnerCopy, PLitInd); |
| |
| cont_Check(); |
| unify_UnifyNoOC(cont_LeftContext(), AtomCopy, |
| cont_RightContext(), clause_LiteralAtom(PLit)); |
| subst_ExtractUnifier(cont_LeftContext(), &NewSubst, cont_RightContext(), &RightSubst); |
| cont_Reset(); |
| |
| subst_Delete(RightSubst); |
| HelpSubst = NewSubst; |
| NewSubst = subst_Compose(NewSubst, subst_Copy(Subst)); |
| |
| Result = list_Nconc(inf_ConstraintHyperResolvents(Clause, Lits, NewSubst, |
| list_Cdr(Restlits), |
| Foundlits, Index, Flags, |
| Precedence), |
| Result); |
| subst_Delete(NewSubst); |
| subst_Delete(HelpSubst); |
| clause_Delete(PartnerCopy); |
| |
| Foundlits = list_Pop(Foundlits); |
| } |
| term_Delete(AtomCopy); |
| |
| return Result; |
| } |
| } |
| |
| |
| LIST inf_BackwardSortResolution(CLAUSE GivenClause, st_INDEX Index, |
| SORTTHEORY SortTheory, BOOL Precheck, |
| FLAGSTORE Flags, PRECEDENCE Precedence) |
| /************************************************************** |
| INPUT: A clause with a solved sort constraint, an index of clauses, |
| a sort theory, a boolean flag indicating whether the subsort |
| precheck can be applied, a flag store and a precedence. |
| RETURNS: A list of clauses inferred from the GivenClause by |
| SortResolution with the given clause. |
| MEMORY: A list of clauses is produced, where memory for the list |
| and the clauses is allocated. |
| ***************************************************************/ |
| { |
| LIST result; |
| int i, ls; |
| |
| #ifdef CHECK |
| if (!clause_IsClause(GivenClause, Flags, Precedence) || |
| !clause_HasSolvedConstraint(GivenClause)) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In inf_BackwardSortResolution: Illegal input.\n"); |
| misc_FinishErrorReport(); |
| } |
| #endif |
| |
| result = list_Nil(); |
| ls = clause_LastSuccedentLitIndex(GivenClause); |
| |
| for (i = clause_FirstSuccedentLitIndex(GivenClause); i <= ls; i++) { |
| LITERAL pLit; |
| TERM pAtom; |
| |
| pLit = clause_GetLiteral(GivenClause, i); |
| pAtom = clause_LiteralAtom(pLit); |
| |
| if (clause_LiteralGetFlag(pLit,STRICTMAXIMAL) && |
| clause_LiteralIsSort(pLit)) { |
| LIST termList; |
| termList = st_GetUnifier(cont_LeftContext(),Index,cont_RightContext(),pAtom); |
| |
| for ( ; !list_Empty(termList); termList = list_Pop(termList)){ |
| if (term_IsAtom(list_Car(termList)) && |
| !term_IsVariable(term_FirstArgument(list_Car(termList)))) { |
| |
| LIST litScan; |
| litScan = sharing_NAtomDataList(list_Car(termList)); |
| for ( ; !list_Empty(litScan); litScan = list_Cdr(litScan)) { |
| LITERAL gLit; |
| CLAUSE gClause; |
| gLit = list_Car(litScan); |
| gClause = clause_LiteralOwningClause(gLit); |
| if (clause_LiteralGetIndex(gLit) < clause_FirstAntecedentLitIndex(gClause) && |
| clause_GetFlag(gClause,WORKEDOFF)) { |
| TERM gAtom; |
| int lc, gi, j; |
| LIST tLits, restLits; |
| gAtom = clause_LiteralAtom(gLit); |
| lc = clause_LastConstraintLitIndex(gClause); |
| gi = clause_LiteralGetIndex(gLit); |
| tLits = list_List((POINTER)gi); |
| restLits = list_Nil(); |
| for (j = clause_FirstLitIndex(); j <= lc; j++) { |
| LITERAL tCand; |
| tCand = clause_GetLiteral(gClause, j); |
| if (j != gi && |
| term_FirstArgument(clause_LiteralAtom(tCand)) |
| == term_FirstArgument(gAtom)) { |
| tLits = list_Cons((POINTER)j, tLits); |
| restLits = list_Cons((POINTER)j, restLits); |
| } |
| } |
| |
| if (!Precheck || |
| inf_SubsortPrecheck(gClause,tLits,pLit,Index,SortTheory)) { |
| CLAUSE pClauseCopy; |
| SYMBOL minVar; |
| LIST foundLits; |
| SUBST leftSubst, rightSubst; |
| pClauseCopy = clause_Copy(GivenClause); |
| minVar = clause_MaxVar(gClause); |
| foundLits = list_List(pLit); |
| |
| clause_RenameVarsBiggerThan(pClauseCopy, minVar); |
| pAtom = clause_GetLiteralAtom(pClauseCopy, i); |
| /* set, to unify correctly! */ |
| |
| cont_Check(); |
| unify_UnifyNoOC(cont_LeftContext(), gAtom, cont_RightContext(), pAtom); |
| subst_ExtractUnifier(cont_LeftContext(), &leftSubst, |
| cont_RightContext(), &rightSubst); |
| cont_Reset(); |
| |
| subst_Delete(rightSubst); |
| |
| result = |
| list_Nconc(inf_ConstraintHyperResolvents(gClause, tLits, |
| leftSubst, restLits, |
| foundLits, Index, |
| Flags, Precedence), |
| result); |
| |
| pAtom = clause_LiteralAtom(pLit); |
| |
| subst_Delete(leftSubst); |
| list_Delete(foundLits); |
| clause_Delete(pClauseCopy); |
| } /* if Precheck */ |
| list_Delete(tLits); |
| list_Delete(restLits); |
| } |
| } |
| } |
| } |
| } |
| } |
| return result; |
| } |
| |
| |
| LIST inf_ForwardSortResolution(CLAUSE GivenClause, st_INDEX Index, |
| SORTTHEORY SortTheory, BOOL Precheck, |
| FLAGSTORE Flags, PRECEDENCE Precedence) |
| /************************************************************** |
| INPUT: A clause with an unsolved sort constraint, an index of clauses, |
| a sort theory, a boolean flag indicating whether the subsort |
| precheck can be applied, a flag store and a precedence. |
| RETURNS: A list of clauses inferred from the GivenClause by |
| SortResolution on the given clause. |
| MEMORY: A list of clauses is produced, where memory for the list |
| and the clauses is allocated. |
| ***************************************************************/ |
| { |
| LIST Result, TLits, RestLits; |
| int i, j, lc; |
| BOOL Hit; |
| TERM TAtom; |
| |
| #ifdef CHECK |
| if (!clause_IsClause(GivenClause, Flags, Precedence) || |
| !clause_HasTermSortConstraintLits(GivenClause)) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In inf_ForwardSortResolution: Illegal input.\n"); |
| misc_FinishErrorReport(); |
| } |
| #endif |
| |
| Result = list_Nil(); |
| lc = clause_LastConstraintLitIndex(GivenClause); |
| Hit = FALSE; |
| |
| i = clause_FirstLitIndex(); |
| while (i <= lc && !Hit) { |
| TAtom = clause_GetLiteralAtom(GivenClause, i); |
| if (!term_IsVariable(term_FirstArgument(TAtom))) |
| Hit = TRUE; |
| else |
| i++; |
| } |
| |
| if (!Hit) |
| return list_Nil(); |
| |
| /* added because of compiler warnings */ |
| TAtom = clause_GetLiteralAtom(GivenClause, i); |
| |
| /* Search the other T_i from <GivenClause> */ |
| TLits = list_List((POINTER)i); |
| for (j = i+1; j <= lc; j++) { |
| if (term_FirstArgument(clause_GetLiteralAtom(GivenClause, j)) |
| == term_FirstArgument(TAtom)) |
| TLits = list_Cons((POINTER)j, TLits); |
| } |
| RestLits = list_Copy(TLits); |
| |
| if (!Precheck || |
| inf_SubsortPrecheck(GivenClause, TLits, NULL, Index, SortTheory)) { |
| |
| Result = inf_ConstraintHyperResolvents(GivenClause, TLits, subst_Nil(), |
| RestLits, list_Nil(), Index, Flags, |
| Precedence); |
| |
| } |
| list_Delete(RestLits); |
| list_Delete(TLits); |
| |
| return Result; |
| } |
| |
| |
| LIST inf_BackwardEmptySort(CLAUSE GivenClause, st_INDEX Index, |
| SORTTHEORY SortTheory, BOOL Precheck, |
| FLAGSTORE Flags, PRECEDENCE Precedence) |
| /************************************************************** |
| INPUT: A clause with a solved sort constraint, an 'Index' of clauses, |
| a sort theory, a boolean flag indicating whether the subsort |
| precheck can be applied, a flag store and a precedence. |
| RETURNS: A list of clauses inferred from the GivenClause by |
| EmptySort with the given clause. |
| MEMORY: A list of clauses is produced, where memory for the list |
| and the clauses is allocated. |
| ***************************************************************/ |
| { |
| LIST result; |
| int i, ls; |
| |
| #ifdef CHECK |
| if (!(clause_IsClause(GivenClause, Flags, Precedence)) || |
| !clause_HasSolvedConstraint(GivenClause)) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In inf_BackwardEmptySort: Illegal input.\n"); |
| misc_FinishErrorReport(); |
| } |
| #endif |
| |
| result = list_Nil(); |
| |
| ls = clause_LastSuccedentLitIndex(GivenClause); |
| |
| for (i = clause_FirstSuccedentLitIndex(GivenClause); i <= ls; i++) { |
| LITERAL pLit = clause_GetLiteral(GivenClause, i); |
| TERM pAtom = clause_LiteralAtom(pLit); |
| |
| if (clause_LiteralGetFlag(pLit,STRICTMAXIMAL) && |
| clause_LiteralIsSort(pLit)) { |
| LIST unifiers = st_GetUnifier(cont_LeftContext(),Index,cont_RightContext(),pAtom); |
| |
| for ( ; !list_Empty(unifiers); unifiers = list_Pop(unifiers)){ |
| if (term_IsAtom(list_Car(unifiers)) && |
| term_IsVariable(term_FirstArgument(list_Car(unifiers)))) { |
| LIST litScan = sharing_NAtomDataList(list_Car(unifiers)); |
| |
| for ( ; !list_Empty(litScan); litScan = list_Cdr(litScan)){ |
| LITERAL gLit = list_Car(litScan); |
| CLAUSE gClause = clause_LiteralOwningClause(gLit); |
| |
| if (clause_LiteralGetIndex(gLit) < clause_FirstAntecedentLitIndex(gClause) && |
| clause_GetFlag(gClause,WORKEDOFF) && |
| clause_HasOnlyVarsInConstraint(gClause, Flags, Precedence)) { |
| TERM gAtom = clause_LiteralAtom(gLit); |
| SYMBOL var = term_TopSymbol(term_FirstArgument(gAtom)); |
| int lc = clause_LastConstraintLitIndex(gClause); |
| int gi = clause_LiteralGetIndex(gLit); |
| BOOL varOccursNoMore; |
| int j, bound; |
| |
| varOccursNoMore = TRUE; |
| bound = clause_LastSuccedentLitIndex(gClause); |
| |
| for (j = clause_FirstAntecedentLitIndex(gClause); |
| (j <= bound) && varOccursNoMore; |
| j++) { |
| if (term_ContainsSymbol(clause_GetLiteralAtom(gClause, j), var)) |
| varOccursNoMore = FALSE; |
| } |
| |
| if (varOccursNoMore) { |
| LIST tLits, restLits; |
| |
| /* Search the other T_i from <gClause> */ |
| tLits = list_List((POINTER)gi); |
| restLits = list_Nil(); |
| for (j = clause_FirstLitIndex(); j <= lc; j++) { |
| LITERAL tCand = clause_GetLiteral(gClause, j); |
| |
| if (j != gi && |
| term_FirstArgument(clause_LiteralAtom(tCand)) |
| == term_FirstArgument(gAtom)) { |
| tLits = list_Cons((POINTER)j, tLits); |
| restLits = list_Cons((POINTER)j, restLits); |
| } |
| } |
| |
| if (!Precheck || |
| inf_SubsortPrecheck(gClause,tLits,pLit,Index,SortTheory)) { |
| CLAUSE pCopy = clause_Copy(GivenClause); |
| SYMBOL minVar = clause_MaxVar(gClause); |
| LIST foundLits = list_List(pLit); |
| SUBST leftSubst, rightSubst; |
| |
| clause_RenameVarsBiggerThan(pCopy, minVar); |
| pAtom = clause_GetLiteralAtom(pCopy, i); |
| /* set, to adress the renamed term! */ |
| |
| cont_Check(); |
| unify_UnifyNoOC(cont_LeftContext(), gAtom, cont_RightContext(), pAtom); |
| subst_ExtractUnifier(cont_LeftContext(), &leftSubst, |
| cont_RightContext(), &rightSubst); |
| cont_Reset(); |
| |
| subst_Delete(rightSubst); |
| |
| result = |
| list_Nconc(inf_ConstraintHyperResolvents(gClause, tLits, |
| leftSubst,restLits, |
| foundLits, Index, |
| Flags, Precedence), |
| result); |
| |
| list_Delete(foundLits); |
| subst_Delete(leftSubst); |
| clause_Delete(pCopy); |
| |
| pAtom = clause_LiteralAtom(pLit); |
| /* reset to original clauses literal! */ |
| } /* if Precheck */ |
| list_Delete(tLits); |
| list_Delete(restLits); |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| return result; |
| } |
| |
| |
| LIST inf_ForwardEmptySort(CLAUSE GivenClause, st_INDEX Index, |
| SORTTHEORY SortTheory, BOOL Precheck, FLAGSTORE Flags, |
| PRECEDENCE Precedence) |
| /************************************************************** |
| INPUT: A clause, an index of clauses, a sort theory, |
| a boolean flag indicating whether the subsort |
| precheck can be applied, a flag store and a precedence. |
| The constraint of <GivenClause> is necessarily unsolved |
| RETURNS: A list of clauses inferred from the GivenClause by |
| EmptySort on the given clause. |
| MEMORY: A list of clauses is produced, where memory for the list |
| and the clauses is allocated. |
| ***************************************************************/ |
| { |
| LIST Result, TLits, RestLits; |
| int i, j, lc, ls; |
| BOOL Hit; |
| TERM TAtom; |
| SYMBOL Var; |
| |
| #ifdef CHECK |
| if (clause_HasTermSortConstraintLits(GivenClause) || |
| clause_HasSolvedConstraint(GivenClause)) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In inf_ForwardEmptySort: Illegal input.\n"); |
| misc_FinishErrorReport(); |
| } |
| #endif |
| |
| Result = list_Nil(); |
| lc = clause_LastConstraintLitIndex(GivenClause); |
| Hit = FALSE; |
| |
| i = clause_FirstLitIndex(); |
| while (i <= lc && !Hit) { |
| TAtom = clause_GetLiteralAtom(GivenClause, i); |
| |
| if (term_IsVariable(term_FirstArgument(TAtom))) { |
| Var = term_TopSymbol(term_FirstArgument(TAtom)); |
| ls = clause_LastSuccedentLitIndex(GivenClause); |
| Hit = TRUE; |
| /* Check if the variable occurs in antecedent or succedent literals */ |
| for (j = clause_FirstAntecedentLitIndex(GivenClause); |
| j <= ls && Hit; j++) { |
| if (term_ContainsSymbol(clause_GetLiteralAtom(GivenClause,j), Var)) |
| Hit = FALSE; /* Variable occurs in antecedent/constraint literal */ |
| } |
| } |
| if (!Hit) |
| i++; |
| } |
| |
| if (!Hit) |
| return list_Nil(); |
| |
| TAtom = clause_GetLiteralAtom(GivenClause, i); |
| Var = term_TopSymbol(term_FirstArgument(TAtom)); |
| |
| /* Search the other T_i(t) literals */ |
| TLits = list_List((POINTER)i); |
| for (j = i+1; j <= lc; j++) { |
| TERM TCand; |
| |
| TCand = clause_GetLiteralAtom(GivenClause, j); |
| |
| if (symbol_Equal(term_TopSymbol(term_FirstArgument(TCand)), Var)) |
| TLits = list_Cons((POINTER)j, TLits); |
| } |
| RestLits = list_Copy(TLits); |
| |
| if (!Precheck || |
| inf_SubsortPrecheck(GivenClause, TLits, NULL, Index, SortTheory)) { |
| |
| Result = inf_ConstraintHyperResolvents(GivenClause, TLits, subst_Nil(), |
| RestLits, list_Nil(), Index, Flags, |
| Precedence); |
| |
| } |
| list_Delete(RestLits); |
| list_Delete(TLits); |
| |
| return Result; |
| } |
| |
| static LIST inf_GetForwardPartnerLits(LITERAL Literal, st_INDEX Index) |
| /************************************************************** |
| INPUT: A monadic literal, and an index of clauses. |
| RETURNS: A list of monadic succedent literals whose subterm |
| is unifiable with the (one) subterm of <Literal>. |
| The literals are strict maximal in their respective clauses, |
| the clauses are "WORKEDOFF" and either the subterm |
| is not a variable or the clause has an empty constraint. |
| MEMORY: Allocates memory for the list. |
| ***************************************************************/ |
| { |
| LIST result, unifiers, atomScan, litScan; |
| |
| #ifdef CHECK |
| if (!clause_LiteralIsLiteral(Literal) || !clause_LiteralIsSort(Literal)) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In inf_GetForwardPartnerLits: Illegal input.\n"); |
| misc_FinishErrorReport(); |
| } |
| #endif |
| |
| result = list_Nil(); |
| /* Search unifiers for the literal's subterm */ |
| unifiers = st_GetUnifier(cont_LeftContext(), Index, cont_RightContext(), |
| term_FirstArgument(clause_LiteralAtom(Literal))); |
| |
| for ( ; !list_Empty(unifiers); unifiers = list_Pop(unifiers)) { |
| |
| if (!term_IsAtom(list_Car(unifiers))) { /* Can happen if arg is variable */ |
| |
| for (atomScan = term_SupertermList(list_Car(unifiers)); |
| !list_Empty(atomScan); |
| atomScan = list_Cdr(atomScan)) { |
| TERM atomCand; |
| atomCand = (TERM) list_Car(atomScan); |
| if (term_IsDeclaration(atomCand)) { |
| /* We are looking for an unary atom */ |
| |
| for (litScan = sharing_NAtomDataList(atomCand); |
| !list_Empty(litScan); |
| litScan = list_Cdr(litScan)) { |
| LITERAL nextLit; |
| CLAUSE nextClause; |
| nextLit = list_Car(litScan); |
| nextClause = clause_LiteralOwningClause(nextLit); |
| |
| if (clause_LiteralIsPositive(nextLit) && |
| clause_LiteralGetFlag(nextLit,STRICTMAXIMAL) && |
| clause_GetFlag(nextClause, WORKEDOFF) && |
| (!term_IsVariable(list_Car(unifiers)) || |
| clause_HasEmptyConstraint(nextClause)) && |
| clause_HasSolvedConstraint(nextClause)) { |
| /* Add the literal from the copied clause */ |
| result = list_Cons(nextLit, result); |
| } |
| } /* litScan */ |
| } /* if IsAtom */ |
| } /* atomScan */ |
| } /* ! variable */ |
| } /* unifiers */ |
| return result; |
| } |
| |
| static BOOL inf_LiteralsHaveSameSubtermAndAreFromSameClause(LITERAL L1, LITERAL L2) |
| /************************************************************** |
| INPUT: Two literals. |
| RETURNS: TRUE, if both literals have the same term and are |
| from the same clause, FALSE otherwise. |
| Since both literals are shared, pointer equality |
| is used to detect this. |
| This function is used by inf_GetBackwardPartnerLits(). |
| ***************************************************************/ |
| { |
| return (term_FirstArgument(clause_LiteralAtom(L1)) |
| == term_FirstArgument(clause_LiteralAtom(L2)) && |
| clause_LiteralOwningClause(L1) == clause_LiteralOwningClause(L2)); |
| } |
| |
| static void inf_GetBackwardPartnerLits(LITERAL Literal, st_INDEX Index, |
| LIST* ConstraintLits, LIST* Unifiers, |
| BOOL IsFromEmptySort, FLAGSTORE Flags, |
| PRECEDENCE Precedence) |
| /************************************************************** |
| INPUT: A literal, an index of clauses, two pointers to lists, |
| a boolean value, a flag store and a precedence. |
| RETURNS: |
| MEMORY: Allocates memory for the list. |
| ***************************************************************/ |
| { |
| LIST candidates, atomScan, litScan; |
| LITERAL nextLit; |
| CLAUSE nextClause; |
| |
| #ifdef CHECK |
| if (!clause_LiteralIsLiteral(Literal) || !clause_LiteralIsSort(Literal)) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In inf_GetBackwardPartnerLits: Illegal input.\n"); |
| misc_FinishErrorReport(); |
| } |
| #endif |
| |
| candidates = st_GetUnifier(cont_LeftContext(), Index, cont_RightContext(), |
| term_FirstArgument(clause_LiteralAtom(Literal))); |
| |
| for ( ; !list_Empty(candidates); candidates = list_Pop(candidates)) { |
| if (!term_IsAtom(list_Car(candidates))) { /* May happen if arg is variable */ |
| /* Consider variable unifiers only if called from BackwardEmptySort */ |
| for (atomScan = term_SupertermList(list_Car(candidates)); |
| !list_Empty(atomScan); |
| atomScan = list_Cdr(atomScan)) { |
| TERM atomCand; |
| atomCand = (TERM) list_Car(atomScan); |
| if (term_IsDeclaration(atomCand)) { |
| /* We are looking for unary atoms */ |
| |
| for (litScan = sharing_NAtomDataList(atomCand); |
| !list_Empty(litScan); |
| litScan = list_Cdr(litScan)) { |
| nextLit = list_Car(litScan); |
| nextClause = clause_LiteralOwningClause(nextLit); |
| |
| if (clause_GetFlag(nextClause, WORKEDOFF)) { |
| if (clause_LiteralIsPositive(nextLit)) { |
| if (clause_LiteralGetFlag(nextLit,STRICTMAXIMAL) && |
| (!term_IsVariable(list_Car(candidates)) || |
| clause_HasEmptyConstraint(nextClause)) && |
| clause_HasSolvedConstraint(nextClause) && |
| !symbol_Equal(clause_LiteralPredicate(Literal), |
| clause_LiteralPredicate(nextLit))) { |
| /* Don't consider literals with same top symbol as given literal */ |
| /* since the given clause must be part of any inference */ |
| *Unifiers = list_Cons(nextLit, *Unifiers); |
| } |
| } else if (clause_LiteralGetIndex(nextLit) < clause_FirstAntecedentLitIndex(nextClause) && |
| ((!term_IsVariable(list_Car(candidates)) && !IsFromEmptySort) || |
| (term_IsVariable(list_Car(candidates)) && IsFromEmptySort && |
| clause_HasOnlyVarsInConstraint(nextClause,Flags, Precedence)))) { |
| *ConstraintLits = list_Cons(nextLit, *ConstraintLits); |
| } |
| } |
| } /* litScan */ |
| } |
| } /* atomScan */ |
| } |
| } /* candidates */ |
| |
| /* We have to avoid constraint literals from the same clause with the same |
| term or variable, since those would create the same result clause. */ |
| *ConstraintLits = |
| list_DeleteDuplicates(*ConstraintLits, |
| (BOOL (*)(POINTER,POINTER)) inf_LiteralsHaveSameSubtermAndAreFromSameClause); |
| } |
| |
| static void inf_MakeClausesDisjoint(CLAUSE GClause, LIST Literals) |
| /************************************************************** |
| INPUT: A clause and a non-empty list of literals. |
| EFFECT: All input clauses, those pointed to by the literals, |
| are variable disjointly renamed. |
| ***************************************************************/ |
| { |
| SYMBOL maxVar, maxCand; |
| CLAUSE lastClause; |
| |
| maxVar = clause_MaxVar(GClause); |
| lastClause = clause_LiteralOwningClause(list_Car(Literals)); |
| clause_RenameVarsBiggerThan(lastClause, maxVar); |
| Literals = list_Cdr(Literals); |
| |
| for ( ; !list_Empty(Literals); Literals = list_Cdr(Literals)) { |
| CLAUSE actClause; |
| |
| clause_UpdateMaxVar(lastClause); |
| maxCand = clause_MaxVar(lastClause); |
| maxVar = (symbol_GreaterVariable(maxVar,maxCand)? maxVar : maxCand); |
| |
| actClause = clause_LiteralOwningClause(list_Car(Literals)); |
| clause_RenameVarsBiggerThan(actClause, maxVar); |
| } |
| } |
| |
| static void inf_CopyUnifierClauses(LIST Literals) |
| /************************************************************** |
| INPUT: A list of literals. |
| EFFECT: Replaces all literals by pointers to literals of copies |
| of the respective clauses. |
| ***************************************************************/ |
| { |
| for ( ; !list_Empty(Literals); Literals = list_Cdr(Literals)) { |
| CLAUSE actClause; |
| int i; |
| |
| actClause = clause_LiteralOwningClause(list_Car(Literals)); |
| i = clause_LiteralGetIndex(list_Car(Literals)); |
| actClause = clause_Copy(actClause); |
| list_Rplaca(Literals, clause_GetLiteral(actClause, i)); /* Set to literal from copy */ |
| } |
| } |
| |
| static void inf_DeleteUnifierClauses(LIST Literals) |
| /************************************************************** |
| INPUT: A list of literals. |
| EFFECT: Deletes all clauses the literals point to. |
| ***************************************************************/ |
| { |
| for ( ; !list_Empty(Literals); Literals = list_Cdr(Literals)) { |
| clause_Delete(clause_LiteralOwningClause(list_Car(Literals))); |
| list_Rplaca(Literals, NULL); |
| } |
| } |
| |
| static SORT inf_GetSortFromLits(LIST Literals, SORTTHEORY SortTheory) |
| /************************************************************** |
| INPUT: A list of literals and a sort theory. |
| RETURNS: The sort created from the literals' predicates. |
| ***************************************************************/ |
| { |
| SORT result = sort_TopSort(); |
| |
| for ( ; !list_Empty(Literals); Literals = list_Cdr(Literals)) { |
| SORT newSort = sort_TheorySortOfSymbol(SortTheory, |
| clause_LiteralPredicate(list_Car(Literals))); |
| |
| result = sort_Intersect(newSort, result); |
| } |
| |
| list_PointerDeleteDuplicates(result); |
| |
| return result; |
| } |
| |
| static LIST inf_ApplyWeakening(CLAUSE Clause, LIST TLits, LIST Partners, |
| CONDITION Condition, FLAGSTORE Flags, |
| PRECEDENCE Precedence) |
| /************************************************************** |
| INPUT: A clause, a list of constraint indices in <Clause>, |
| a list of maximal, monadic succedent literals, |
| a subsort condition, a flag store and a precedence. |
| RETURNS: A one-element list with a clause derived from the |
| clause and the partner clauses by the Weakening or |
| Empty Sort rule. |
| The flag store is needed to create the result clause. |
| MEMORY: Memory is allocated for the returned list and the clause. |
| ***************************************************************/ |
| { |
| LIST scan, parents; |
| LIST constraint, antecedent, succedent; |
| LIST parentClauses, parentLits; /* clause numbers and literal indices */ |
| int i, bound, depth; |
| TERM tSubterm; |
| CLAUSE newClause; |
| |
| #ifdef CHECK |
| if (!clause_IsClause(Clause, Flags, Precedence) || list_Empty(TLits) || |
| list_Empty(Partners) || Condition == NULL) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In inf_ApplyWeakening: Illegal input.\n"); |
| misc_FinishErrorReport(); |
| } |
| #endif |
| |
| constraint = antecedent = succedent = list_Nil(); |
| parentClauses = parentLits = list_Nil(); |
| parents = list_Nil(); /* Used to set split data */ |
| depth = clause_Depth(Clause); |
| tSubterm = term_FirstArgument(clause_GetLiteralAtom(Clause, (int)list_Car(TLits))); |
| |
| /* Now collect the literals of the new clause */ |
| /* First consider the condition atoms */ |
| for (scan=sort_ConditionConstraint(Condition); !list_Empty(scan); scan=list_Cdr(scan)) { |
| TERM termCopy; |
| |
| termCopy = term_Copy(list_Car(scan)); |
| term_ReplaceVariable(termCopy, sort_ConditionVar(Condition), tSubterm); |
| constraint = list_Cons(cont_CopyAndApplyBindings(cont_LeftContext(), termCopy), |
| constraint); |
| term_Delete(termCopy); /* constraint contains a copy */ |
| } |
| for (scan=sort_ConditionAntecedent(Condition); !list_Empty(scan); scan=list_Cdr(scan)) { |
| TERM termCopy; |
| |
| termCopy = term_Copy(list_Car(scan)); |
| term_ReplaceVariable(termCopy, sort_ConditionVar(Condition), tSubterm); |
| antecedent = list_Cons(cont_CopyAndApplyBindings(cont_LeftContext(), termCopy), |
| antecedent); |
| term_Delete(termCopy); /* antecedent contains a copy */ |
| } |
| for (scan=sort_ConditionSuccedent(Condition); !list_Empty(scan); scan=list_Cdr(scan)) { |
| TERM termCopy; |
| |
| termCopy = term_Copy(list_Car(scan)); |
| term_ReplaceVariable(termCopy, sort_ConditionVar(Condition), tSubterm); |
| succedent = list_Cons(cont_CopyAndApplyBindings(cont_LeftContext(), termCopy), |
| succedent); |
| term_Delete(termCopy); /* succedent contains a copy */ |
| } |
| /* update parents and depth from condition clauses */ |
| for (scan=sort_ConditionClauses(Condition); !list_Empty(scan); scan=list_Cdr(scan)) { |
| CLAUSE condClause; |
| |
| condClause = list_Car(scan); |
| parents = list_Cons(condClause, parents); |
| parentClauses = list_Cons((POINTER)clause_Number(condClause), parentClauses); |
| parentLits = list_Cons((POINTER)clause_FirstSuccedentLitIndex(condClause), parentLits); |
| depth = misc_Max(depth, clause_Depth(condClause)); |
| } |
| |
| /* Now we consider the partner clauses */ |
| for (scan = Partners; !list_Empty(scan); scan = list_Cdr(scan)) { |
| LITERAL pLit; |
| CLAUSE pClause; |
| int pi; |
| |
| pLit = list_Car(scan); |
| pClause = clause_LiteralOwningClause(pLit); |
| pi = clause_LiteralGetIndex(pLit); |
| bound = clause_LastConstraintLitIndex(pClause); |
| for (i = clause_FirstLitIndex(); i <= bound; i++) { |
| constraint = list_Cons(cont_CopyAndApplyBindings(cont_RightContext(), |
| clause_GetLiteralAtom(pClause,i)), |
| constraint); |
| } |
| bound = clause_LastAntecedentLitIndex(pClause); |
| for (i = clause_FirstAntecedentLitIndex(pClause); i <= bound; i++) { |
| antecedent = list_Cons(cont_CopyAndApplyBindings(cont_RightContext(), |
| clause_GetLiteralAtom(pClause,i)), |
| antecedent); |
| } |
| bound = clause_LastSuccedentLitIndex(pClause); |
| for (i = clause_FirstSuccedentLitIndex(pClause); i <= bound; i++) { |
| if (i != pi) |
| succedent = list_Cons(cont_CopyAndApplyBindings(cont_RightContext(), |
| clause_GetLiteralAtom(pClause,i)), |
| succedent); |
| } |
| |
| parents = list_Cons(pClause, parents); |
| |
| parentClauses = list_Cons((POINTER)clause_Number(pClause), parentClauses); |
| parentLits = list_Cons((POINTER) pi, parentLits); |
| |
| depth = misc_Max(depth, clause_Depth(pClause)); |
| } |
| |
| /* Last but not least we consider the <Clause> itself */ |
| bound = clause_LastConstraintLitIndex(Clause); |
| for (i = clause_FirstLitIndex(); i <= bound; i++) { |
| if (!list_PointerMember(TLits, (POINTER)i)) |
| constraint = list_Cons(cont_CopyAndApplyBindings(cont_LeftContext(), |
| clause_GetLiteralAtom(Clause,i)), |
| constraint); |
| else { |
| parentClauses = list_Cons((POINTER)clause_Number(Clause), parentClauses); |
| parentLits = list_Cons((POINTER)i, parentLits); |
| } |
| } |
| bound = clause_LastAntecedentLitIndex(Clause); |
| for (i = clause_FirstAntecedentLitIndex(Clause); i <= bound; i++) { |
| antecedent = list_Cons(cont_CopyAndApplyBindings(cont_LeftContext(), |
| clause_GetLiteralAtom(Clause,i)), |
| antecedent); |
| } |
| bound = clause_LastSuccedentLitIndex(Clause); |
| for (i = clause_FirstSuccedentLitIndex(Clause); i <= bound; i++) { |
| succedent = list_Cons(cont_CopyAndApplyBindings(cont_LeftContext(), |
| clause_GetLiteralAtom(Clause,i)), |
| succedent); |
| } |
| |
| parents = list_Cons(Clause, parents); |
| |
| /* Now we've got all data we need */ |
| newClause = clause_Create(constraint, antecedent, succedent, Flags,Precedence); |
| |
| list_Delete(constraint); |
| list_Delete(antecedent); |
| list_Delete(succedent); |
| |
| if (term_IsVariable(tSubterm)) |
| clause_SetFromEmptySort(newClause); |
| else |
| clause_SetFromSortResolution(newClause); |
| |
| clause_SetDepth(newClause, depth+1); |
| clause_SetFlag(newClause, DOCCLAUSE); |
| |
| clause_SetSplitDataFromList(newClause, parents); |
| list_Delete(parents); |
| |
| clause_SetParentClauses(newClause, parentClauses); |
| clause_SetParentLiterals(newClause, parentLits); |
| |
| return list_List(newClause); |
| } |
| |
| static LIST inf_InternWeakening(CLAUSE Clause, LIST TLits, LIST Unifiers, |
| LITERAL Special, LIST SojuList, FLAGSTORE Flags, |
| PRECEDENCE Precedence) |
| /************************************************************** |
| INPUT: A <Clause> with unsolved sort constraint, |
| a list <TLits> of constraint indices in <Clause> where |
| all corresponding constraints have the same term, |
| a list <Unifiers> of monadic succedent literals whose |
| subterm is unifiable with the subterm of the <TLits>, |
| and a flag store. |
| If called from a backward rule the literal <Special> |
| will be the succedent literal from the respective |
| GivenClause, that must be part of every considered |
| SOJU sort. If called from a forward rule <Special> is NULL. |
| A list <SojuList> of sort pairs. |
| A flag store and a precedence. |
| RETURNS: The list of possible resolvents. |
| EFFECT: ATTENTION: <SojuList> is deleted. |
| MEMORY: Memory is allocated for the returned list and the clauses. |
| ***************************************************************/ |
| { |
| LIST result, myUnifiers; |
| TERM searchTerm; |
| int stack; |
| |
| LIST scan; |
| #ifdef CHECK |
| if (!clause_IsClause(Clause, Flags, Precedence) || list_Empty(TLits) || |
| list_Empty(Unifiers)) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In inf_InternWeakening: Illegal input.\n"); |
| misc_FinishErrorReport(); |
| } |
| #endif |
| |
| putchar('\n'); clause_Print(Clause); |
| fputs("\nT_k = ", stdout); |
| for (scan = TLits; !list_Empty(scan); scan = list_Cdr(scan)) { |
| clause_LiteralPrint(clause_GetLiteral(Clause, (int)list_Car(scan))); |
| putchar(' '); |
| } |
| fputs("\nS_k =", stdout); |
| for (scan = Unifiers; !list_Empty(scan); scan = list_Cdr(scan)) { |
| putchar('\n'); |
| clause_LiteralPrint(list_Car(scan)); |
| fputs(" in ", stdout); |
| clause_Print(clause_LiteralOwningClause(list_Car(scan))); |
| } |
| putchar('\n'); |
| |
| if (list_Empty(SojuList)) |
| return list_Nil(); |
| |
| /*return list_Nil();*/ |
| /* Und Schluss */ |
| |
| result = list_Nil(); |
| |
| myUnifiers = list_Copy(Unifiers); |
| inf_CopyUnifierClauses(myUnifiers); |
| inf_MakeClausesDisjoint(Clause, myUnifiers); |
| |
| searchTerm = |
| term_FirstArgument(clause_GetLiteralAtom(Clause, (int)list_Car(TLits))); |
| |
| stack = stack_Bottom(); |
| |
| for ( ; !list_Empty(SojuList); SojuList = list_Pop(SojuList)) { |
| SOJU actSoju = list_Car(SojuList); |
| |
| fputs("\nSOJU: ", stdout); sort_PairPrint(actSoju); fflush(stdout); |
| |
| if (Special == NULL || |
| sort_ContainsSymbol(sort_PairSort(actSoju), |
| clause_LiteralPredicate(Special))) { |
| LIST actSortSymbols, symbolScan, unifierScan, subset; |
| |
| actSortSymbols = sort_GetSymbolsFromSort(sort_PairSort(actSoju)); |
| subset = list_Nil(); |
| |
| symbolScan = actSortSymbols; |
| unifierScan = myUnifiers; |
| |
| do { |
| while (!list_Empty(symbolScan) && !list_Empty(unifierScan)) { |
| LITERAL actLit = list_Car(unifierScan); |
| |
| if (symbol_Equal(clause_LiteralPredicate(list_Car(unifierScan)), |
| (SYMBOL)list_Car(symbolScan))) { |
| cont_StartBinding(); |
| if (unify_UnifyNoOC(cont_LeftContext(), searchTerm, cont_RightContext(), |
| term_FirstArgument(clause_LiteralAtom(actLit)))) { |
| /* Found corresponding literal for sort symbol */ |
| stack_Push(symbolScan); |
| stack_Push(list_Cdr(unifierScan)); |
| subset = list_Cons(actLit, subset); |
| /* Now search literals for the next sort symbol */ |
| symbolScan = list_Cdr(symbolScan); |
| |
| if (!list_Empty(symbolScan)) |
| /* Start search for literal at the beginning of unifier list */ |
| unifierScan = myUnifiers; |
| else |
| unifierScan = list_Cdr(unifierScan); |
| } else { |
| cont_BackTrack(); |
| unifierScan = list_Cdr(unifierScan); |
| } |
| } else |
| unifierScan = list_Cdr(unifierScan); |
| } |
| |
| if (list_Empty(symbolScan)) { |
| /*putchar('\n'); |
| clause_LiteralListPrint(subset);*/ |
| /* Found subset */ |
| result = list_Nconc(inf_ApplyWeakening(Clause, TLits, subset, |
| sort_PairCondition(actSoju), |
| Flags, Precedence), |
| result); |
| } |
| |
| while (!stack_Empty(stack) && list_Empty(stack_Top())) { |
| /* No more literals */ |
| stack_NPop(2); |
| cont_BackTrack(); |
| subset = list_Pop(subset); |
| } |
| |
| if (!stack_Empty(stack)) { |
| /* Implies that stack_Top is a non-empty list */ |
| unifierScan = stack_PopResult(); |
| symbolScan = stack_PopResult(); |
| cont_BackTrack(); |
| subset = list_Pop(subset); |
| } |
| } while (!stack_Empty(stack) || !list_Empty(unifierScan)); |
| |
| list_Delete(actSortSymbols); |
| } |
| sort_PairDelete(actSoju); |
| } /* For all SOJUs */ |
| |
| inf_DeleteUnifierClauses(myUnifiers); |
| list_Delete(myUnifiers); |
| |
| return result; |
| } |
| |
| LIST inf_ForwardWeakening(CLAUSE GivenClause, st_INDEX Index, |
| SORTTHEORY SortTheory, FLAGSTORE Flags, |
| PRECEDENCE Precedence) |
| /************************************************************** |
| INPUT: A clause, an index of clauses, a sort theory, a flag store |
| and a precedence. |
| The sort constraint of the clause must contain a non-variable term |
| (this implies the sort constraint is unsolved). |
| RETURNS: A list of clauses derived from the GivenClause by |
| the Weakening rule. |
| MEMORY: Memory is allocated for the returned list and the clauses. |
| ***************************************************************/ |
| { |
| LIST result; |
| int i, lc; |
| BOOL hit; |
| |
| #ifdef CHECK |
| if (!clause_HasTermSortConstraintLits(GivenClause)) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In inf_ForwardWeakening: Illegal input.\n"); |
| misc_FinishErrorReport(); |
| } |
| #endif |
| |
| result = list_Nil(); |
| lc = clause_LastConstraintLitIndex(GivenClause); |
| hit = FALSE; |
| |
| for (i = clause_FirstLitIndex(); i <= lc && !hit; i++) { |
| |
| if (!term_IsVariable(term_FirstArgument(clause_GetLiteralAtom(GivenClause, i)))) { |
| /* Condition implies that constraint is unsolved */ |
| LITERAL tLit; |
| LIST unifiers; |
| int j; |
| |
| tLit = clause_GetLiteral(GivenClause, i); |
| hit = TRUE; /* Try only the first appropriate constraint literal */ |
| unifiers = inf_GetForwardPartnerLits(tLit, Index); |
| |
| if (!list_Empty(unifiers)) { |
| TERM tAtom; |
| LIST tLits, sojuList; |
| SORT tSort, unifierSort; |
| |
| tAtom = clause_GetLiteralAtom(GivenClause, i); |
| |
| /* Search the other T_k(t) in GivenClause */ |
| tLits = list_Nil(); |
| tSort = sort_TopSort(); |
| for (j = lc; j > i; j--) { |
| TERM actAtom; |
| actAtom = clause_GetLiteralAtom(GivenClause, j); |
| if (term_FirstArgument(actAtom) == term_FirstArgument(tAtom)) { |
| tLits = list_Cons((POINTER)j, tLits); |
| tSort = sort_Intersect(sort_TheorySortOfSymbol(SortTheory, term_TopSymbol(actAtom)), |
| tSort); |
| } |
| } |
| tLits = list_Cons((POINTER)i, tLits); |
| tSort = sort_Intersect(sort_TheorySortOfSymbol(SortTheory, term_TopSymbol(tAtom)), |
| tSort); |
| list_PointerDeleteDuplicates(tSort); |
| /* Necessary for Christoph's function */ |
| |
| unifierSort = inf_GetSortFromLits(unifiers, SortTheory); |
| sojuList = sort_TheoryComputeAllSubsortHits(SortTheory, unifierSort, tSort); |
| sort_Delete(unifierSort); |
| sort_Delete(tSort); |
| |
| result = |
| list_Nconc(inf_InternWeakening(GivenClause, tLits, unifiers, NULL, |
| sojuList, Flags, Precedence), |
| result); |
| |
| list_Delete(tLits); |
| list_Delete(unifiers); |
| } |
| } |
| } |
| return result; |
| } |
| |
| LIST inf_BackwardWeakening(CLAUSE GivenClause, st_INDEX Index, |
| SORTTHEORY SortTheory, FLAGSTORE Flags, |
| PRECEDENCE Precedence) |
| /************************************************************** |
| INPUT: A clause with solved sort constraint, an index of clauses, |
| a sort theory, a flag store and a precedence. |
| RETURNS: A list of clauses inferred from the GivenClause by |
| the Weakening rule. |
| MEMORY: Memory is allocated for the list and the clauses. |
| ***************************************************************/ |
| { |
| LIST result; |
| int i, ls; |
| |
| #ifdef CHECK |
| if (!clause_HasSolvedConstraint(GivenClause)) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In inf_BackwardWeakening: Illegal input.\n"); |
| misc_FinishErrorReport(); |
| } |
| #endif |
| |
| result = list_Nil(); |
| ls = clause_LastSuccedentLitIndex(GivenClause); |
| |
| for (i = clause_FirstSuccedentLitIndex(GivenClause); i <= ls; i++) { |
| LITERAL sLit; |
| TERM sAtom; |
| |
| sLit = clause_GetLiteral(GivenClause, i); |
| sAtom = clause_LiteralAtom(sLit); |
| if (clause_LiteralGetFlag(sLit, STRICTMAXIMAL) && |
| clause_LiteralIsSort(sLit) && |
| (!term_IsVariable(term_FirstArgument(sAtom)) || |
| clause_HasEmptyConstraint(GivenClause))) { |
| LIST unifiers, partners; |
| SORT unifierSort; |
| |
| unifiers = partners = list_Nil(); |
| inf_GetBackwardPartnerLits(sLit,Index,&partners,&unifiers,FALSE,Flags, |
| Precedence); |
| unifiers = list_Cons(sLit, unifiers); |
| /* <partners> holds monadic constraint literals */ |
| /* <unifiers> holds monadic, maximal succedent literals */ |
| unifierSort = inf_GetSortFromLits(unifiers, SortTheory); |
| |
| for ( ; !list_Empty(partners); partners = list_Pop(partners)) { |
| LITERAL tLit; |
| CLAUSE tClause; |
| TERM tAtom; |
| int ti; |
| int lc; |
| int j; |
| LIST tLits, sojuList; |
| SORT tSort; |
| |
| tLit = list_Car(partners); |
| tClause = clause_LiteralOwningClause(tLit); |
| tAtom = clause_LiteralAtom(tLit); |
| ti = clause_LiteralGetIndex(tLit); |
| lc = clause_LastConstraintLitIndex(tClause); |
| |
| /* Search the other T_k(t) in GivenClause */ |
| tLits = list_Nil(); |
| tSort = sort_TopSort(); |
| for (j = lc; j >= clause_FirstLitIndex(); j--) { |
| TERM actAtom; |
| |
| actAtom = clause_GetLiteralAtom(tClause, j); |
| if (j != ti && |
| term_FirstArgument(actAtom) == term_FirstArgument(tAtom)) { |
| tLits = list_Cons((POINTER)j, tLits); |
| tSort = sort_Intersect(sort_TheorySortOfSymbol(SortTheory, term_TopSymbol(actAtom)), |
| tSort); |
| } |
| } |
| tLits = list_Cons((POINTER)ti, tLits); |
| tSort = sort_Intersect(sort_TheorySortOfSymbol(SortTheory, term_TopSymbol(tAtom)), |
| tSort); |
| list_PointerDeleteDuplicates(tSort); |
| |
| sojuList = sort_TheoryComputeAllSubsortHits(SortTheory, unifierSort, tSort); |
| sort_Delete(tSort); |
| |
| cont_StartBinding(); |
| unify_UnifyNoOC(cont_LeftContext(), tAtom, |
| cont_RightContext(), sAtom); |
| |
| result = |
| list_Nconc(inf_InternWeakening(tClause, tLits, unifiers, sLit, |
| sojuList, Flags, Precedence), |
| result); |
| |
| cont_BackTrack(); |
| |
| list_Delete(tLits); |
| } |
| sort_Delete(unifierSort); |
| list_Delete(unifiers); |
| } |
| } |
| |
| return result; |
| } |
| |
| LIST inf_ForwardEmptySortPlusPlus(CLAUSE GivenClause, st_INDEX Index, |
| SORTTHEORY SortTheory, FLAGSTORE Flags, |
| PRECEDENCE Precedence) |
| /************************************************************** |
| INPUT: A clause, an 'Index' of clauses, a sort theory, a flag store |
| and a precedence. |
| The sort constraint of the clause must not contain a |
| non-variable term, but the sort constraint has to be unsolved. |
| RETURNS: A list of clauses derived from the GivenClause by |
| the Empty Sort rule. |
| MEMORY: Memory is allocated for the returned list and the clauses. |
| ***************************************************************/ |
| { |
| LIST result; |
| int i, lc; |
| BOOL hit; |
| |
| #ifdef CHECK |
| if (clause_HasTermSortConstraintLits(GivenClause) || |
| clause_HasSolvedConstraint(GivenClause)) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In inf_ForwardEmptySortPlusPlus: Illegal input.\n"); |
| misc_FinishErrorReport(); |
| } |
| #endif |
| |
| result = list_Nil(); |
| lc = clause_LastConstraintLitIndex(GivenClause); |
| hit = FALSE; |
| |
| for (i = clause_FirstLitIndex(); i <= lc && !hit; i++) { |
| |
| if (term_IsVariable(term_FirstArgument(clause_GetLiteralAtom(GivenClause,i)))) { |
| LITERAL tLit; |
| TERM var; |
| int j, ls; |
| BOOL varOccursNoMore; |
| |
| tLit = clause_GetLiteral(GivenClause, i); |
| var = term_FirstArgument(clause_LiteralAtom(tLit)); |
| ls = clause_LastSuccedentLitIndex(GivenClause); |
| varOccursNoMore = TRUE; |
| /* Check if the variable occurs in antecedent or succedent literals */ |
| for (j = clause_FirstAntecedentLitIndex(GivenClause); |
| (j <= ls) && varOccursNoMore; j++) { |
| if (term_ContainsSymbol(clause_GetLiteralAtom(GivenClause,j), |
| term_TopSymbol(var))) |
| varOccursNoMore = FALSE; |
| } |
| |
| if (varOccursNoMore) { |
| /* Condition implies that constraint is unsolved */ |
| LIST unifiers; |
| |
| unifiers = inf_GetForwardPartnerLits(tLit, Index); |
| hit = TRUE; /* We found the first appropriate constraint literal */ |
| |
| if (!list_Empty(unifiers)) { |
| TERM tAtom = clause_LiteralAtom(tLit); |
| LIST tLits, sojuList; |
| SORT tSort, unifierSort; |
| |
| /* Search the other T_k(t) in GivenClause */ |
| tLits = list_Nil(); |
| tSort = sort_TopSort(); |
| for (j = lc; j > i; j--) { |
| TERM actAtom; |
| |
| actAtom = clause_GetLiteralAtom(GivenClause, j); |
| if (term_FirstArgument(actAtom) == var) { /* tClause is shared */ |
| tLits = list_Cons((POINTER)j, tLits); |
| tSort = sort_Intersect(sort_TheorySortOfSymbol(SortTheory, |
| term_TopSymbol(actAtom)), |
| tSort); |
| } |
| } |
| tLits = list_Cons((POINTER)i, tLits); |
| tSort = sort_Intersect(sort_TheorySortOfSymbol(SortTheory, |
| term_TopSymbol(tAtom)), |
| tSort); |
| list_PointerDeleteDuplicates(tSort); |
| |
| unifierSort = inf_GetSortFromLits(unifiers, SortTheory); |
| sojuList = sort_TheoryComputeAllSubsortHits(SortTheory, unifierSort, tSort); |
| |
| sort_Delete(unifierSort); |
| sort_Delete(tSort); |
| |
| result = |
| list_Nconc(inf_InternWeakening(GivenClause, tLits, unifiers, NULL, |
| sojuList, Flags, Precedence), |
| result); |
| |
| list_Delete(tLits); |
| list_Delete(unifiers); |
| } |
| } |
| } |
| } |
| return result; |
| } |
| |
| LIST inf_BackwardEmptySortPlusPlus(CLAUSE GivenClause, st_INDEX Index, |
| SORTTHEORY SortTheory, FLAGSTORE Flags, |
| PRECEDENCE Precedence) |
| /************************************************************** |
| INPUT: A clause with solved sort constraint, an index of clauses, |
| a sort theory, a flag store and a precedence. |
| RETURNS: A list of clauses inferred from the GivenClause by |
| the Empty Sort rule. |
| MEMORY: Memory is allocated for the list and the clauses. |
| ***************************************************************/ |
| { |
| LIST result; |
| int i, ls; |
| |
| #ifdef CHECK |
| if (!clause_HasSolvedConstraint(GivenClause)) { |
| misc_StartErrorReport(); |
| misc_ErrorReport("\n In inf_BackwardEmptySortPlusPlus: Illegal input.\n"); |
| misc_FinishErrorReport(); |
| } |
| #endif |
| |
| result = list_Nil(); |
| ls = clause_LastSuccedentLitIndex(GivenClause); |
| |
| for (i = clause_FirstSuccedentLitIndex(GivenClause); i <= ls; i++) { |
| LITERAL sLit; |
| TERM sAtom; |
| |
| sLit = clause_GetLiteral(GivenClause, i); |
| sAtom = clause_LiteralAtom(sLit); |
| if (clause_LiteralGetFlag(sLit,STRICTMAXIMAL) && |
| clause_LiteralIsSort(sLit) && |
| (!term_IsVariable(term_FirstArgument(sAtom)) || |
| clause_HasEmptyConstraint(GivenClause))) { |
| LIST unifiers, partners; |
| SORT unifierSort; |
| |
| unifiers = partners = list_Nil(); |
| inf_GetBackwardPartnerLits(sLit, Index, &partners, &unifiers, TRUE, Flags, |
| Precedence); |
| unifiers = list_Cons(sLit, unifiers); |
| /* <partners> holds monadic constraint literals */ |
| /* <unifiers> holds monadic, maximal succedent literals */ |
| |
| unifierSort = inf_GetSortFromLits(unifiers, SortTheory); |
| |
| for ( ; !list_Empty(partners); partners = list_Pop(partners)) { |
| LITERAL tLit; |
| CLAUSE tClause; |
| TERM tAtom; |
| int ti; |
| int li; |
| TERM var; |
| BOOL varOccursNoMore; |
| int j; |
| |
| tLit = list_Car(partners); |
| tClause = clause_LiteralOwningClause(tLit); |
| tAtom = clause_LiteralAtom(tLit); |
| ti = clause_LiteralGetIndex(tLit); |
| li = clause_LastSuccedentLitIndex(tClause); |
| var = term_FirstArgument(tAtom); |
| varOccursNoMore = TRUE; |
| for (j = clause_FirstAntecedentLitIndex(tClause); |
| j <= li && varOccursNoMore; |
| j++) { |
| if (term_ContainsSymbol(clause_GetLiteralAtom(tClause,j), |
| term_TopSymbol(var))) |
| varOccursNoMore = FALSE; |
| } |
| |
| if (varOccursNoMore) { |
| /* Condition implies that constraint is unsolved */ |
| int lc; |
| LIST tLits, sojuList; |
| SORT tSort; |
| |
| lc = clause_LastConstraintLitIndex(tClause); |
| |
| /* Search the other T_k(t) in GivenClause */ |
| tLits = list_Nil(); |
| tSort = sort_TopSort(); |
| for (j = lc; j >= clause_FirstLitIndex(); j--) { |
| TERM actAtom; |
| |
| actAtom = clause_GetLiteralAtom(tClause, j); |
| if (j != ti && |
| term_TopSymbol(term_FirstArgument(actAtom)) == term_TopSymbol(var)) { |
| tLits = list_Cons((POINTER)j, tLits); |
| tSort = sort_Intersect(sort_TheorySortOfSymbol(SortTheory, term_TopSymbol(actAtom)), |
| tSort); |
| } |
| } |
| tLits = list_Cons((POINTER)ti, tLits); |
| tSort = sort_Intersect(sort_TheorySortOfSymbol(SortTheory, term_TopSymbol(tAtom)), |
| tSort); |
| list_PointerDeleteDuplicates(tSort); |
| |
| sojuList = sort_TheoryComputeAllSubsortHits(SortTheory, unifierSort, tSort); |
| sort_Delete(tSort); |
| |
| cont_StartBinding(); |
| unify_UnifyNoOC(cont_LeftContext(), tAtom, |
| cont_RightContext(), sAtom); |
| |
| result = |
| list_Nconc(inf_InternWeakening(tClause, tLits, unifiers, sLit, |
| sojuList, Flags, Precedence), |
| result); |
| |
| cont_BackTrack(); |
| |
| list_Delete(tLits); |
| } |
| } |
| sort_Delete(unifierSort); |
| list_Delete(unifiers); |
| } |
| } |
| |
| return result; |
| } |