blob: 6ea442bfedb3981c52a8a96a861942b81b19aa53 [file] [log] [blame]
/**************************************************************/
/* ********************************************************** */
/* * * */
/* * 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;
}