blob: 4f28ef2942c022dfc0eb96c8c8e3f447232d3330 [file] [log] [blame]
/**************************************************************/
/* ********************************************************** */
/* * * */
/* * UR-RESOLUTION * */
/* * * */
/* * $Module: INFERENCE RULES * */
/* * * */
/* * Copyright (C) 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-ur.h"
#include "list.h"
static LIST inf_GetURPartnerLits(TERM Atom, LITERAL Lit,
BOOL Unit, SHARED_INDEX Index)
/**************************************************************
INPUT: An atom, a literal, a boolean flag and a SHARED_INDEX.
RETURNS: A list of literals with sign complementary to <Lit>
that are unifiable with <Atom>. If <Unit> is true,
only literals from unit clauses are returned, if <Unit>
is false, only literals from non-unit clauses are
returned.
EFFECT: <Atom> is a copy of <Lit>'s atom where some substitution
was applied and equality literals might have been swapped.
<Lit> is just needed to check whether the unifiable
literals are complementary.
***************************************************************/
{
LIST Result, Unifiers, LitScan;
LITERAL PLit;
int length;
Result = list_Nil();
Unifiers = st_GetUnifier(cont_LeftContext(), sharing_Index(Index),
cont_RightContext(), Atom);
for ( ; !list_Empty(Unifiers); Unifiers = list_Pop(Unifiers)) {
if (!term_IsVariable(list_Car(Unifiers))) {
for (LitScan = sharing_NAtomDataList(list_Car(Unifiers));
!list_Empty(LitScan); LitScan = list_Cdr(LitScan)) {
PLit = list_Car(LitScan);
length = clause_Length(clause_LiteralOwningClause(PLit));
if (clause_LiteralsAreComplementary(Lit, PLit) &&
((Unit && length==1) || (!Unit && length!=1)))
/* The partner literals must have complementary sign and
if <Unit> == TRUE they must be from unit clauses,
if <Unit> == FALSE they must be from non-unit clauses. */
Result = list_Cons(PLit, Result);
}
}
}
return Result;
}
static CLAUSE inf_CreateURUnitResolvent(CLAUSE Clause, int i, SUBST Subst,
LIST FoundMap, FLAGSTORE Flags,
PRECEDENCE Precedence)
/**************************************************************
INPUT: A non-unit clause, a literal index from the clause,
a substitution, a list of pairs (l1, l2) of literals,
where l1 is from the non-unit clause and l2 is from a
unit clause, a flag store and a precedence.
RETURNS: The resolvent of this UR resolution inference. The
clause consists of the literal at index <i> in <Clause>
after application of <Subst>.
EFFECT: The flag store and the precedence are needed to create
the new clause.
***************************************************************/
{
CLAUSE Result, PClause;
LITERAL Lit;
TERM Atom;
LIST Parents;
NAT depth;
/* Create atom for resolvent */
Atom = subst_Apply(Subst, term_Copy(clause_GetLiteralAtom(Clause, i)));
/* Create clause */
Parents = list_List(Atom);
if (i <= clause_LastConstraintLitIndex(Clause))
Result = clause_Create(Parents, list_Nil(), list_Nil(), Flags, Precedence);
else if (i <= clause_LastAntecedentLitIndex(Clause))
Result = clause_Create(list_Nil(), Parents, list_Nil(), Flags, Precedence);
else
Result = clause_Create(list_Nil(), list_Nil(), Parents, Flags, Precedence);
list_Delete(Parents);
/* Get parent clauses and literals, calculate depth of resolvent */
Parents = list_List(Clause);
depth = clause_Depth(Clause);
for ( ; !list_Empty(FoundMap); FoundMap = list_Cdr(FoundMap)) {
Lit = list_PairSecond(list_Car(FoundMap)); /* Literal from unit */
PClause = clause_LiteralOwningClause(Lit);
Parents = list_Cons(PClause, Parents);
depth = misc_Max(depth, clause_Depth(PClause));
clause_AddParentClause(Result, clause_Number(PClause));
clause_AddParentLiteral(Result, clause_LiteralGetIndex(Lit));
Lit = list_PairFirst(list_Car(FoundMap)); /* Is from <Clause> */
clause_AddParentClause(Result, clause_Number(Clause));
clause_AddParentLiteral(Result, clause_LiteralGetIndex(Lit));
}
clause_SetFromURResolution(Result);
clause_SetDepth(Result, depth+1);
clause_SetSplitDataFromList(Result, Parents);
list_Delete(Parents);
return Result;
}
static LIST inf_SearchURResolvents(CLAUSE Clause, int i, LIST FoundMap,
LIST RestLits, SUBST Subst,
SYMBOL GlobalMaxVar, SHARED_INDEX Index,
FLAGSTORE Flags, PRECEDENCE Precedence)
/**************************************************************
INPUT: A non-unit clause, a literal index from <Clause>.
<FoundMap> is a list of pairs (l1,l2) of unifiable literals,
where l1 is from <Clause> and l2 is from a unit clause.
<RestLits> is a list of literals from <Clause> where
we haven't found unifiable literals from unit clauses
so far.
<Subst> is the overall substitution for <Clause>
(not for the unit-clauses!).
<GlobalMaxVar> is the maximal variable encountered so far.
<Index> is used to search unifiable literals.
The flag store and the precedence are needed to create
the new clauses.
RETURNS: A list of UR resolution resolvents.
***************************************************************/
{
if (list_Empty(RestLits)) {
/* Stop the recursion */
return list_List(inf_CreateURUnitResolvent(Clause, i, Subst, FoundMap,
Flags, Precedence));
} else {
LITERAL Lit, PLit;
SYMBOL NewMaxVar;
SUBST NewSubst, RightSubst;
TERM AtomCopy, PAtom;
LIST Result, Partners;
BOOL Swapped;
Result = list_Nil();
Swapped = FALSE;
/* Choose the unmatched literal with the most symbols */
RestLits = clause_MoveBestLiteralToFront(list_Copy(RestLits), Subst,
GlobalMaxVar,
clause_HyperLiteralIsBetter);
Lit = list_Car(RestLits);
RestLits = list_Pop(RestLits);
AtomCopy = subst_Apply(Subst, term_Copy(clause_LiteralAtom(Lit)));
/* The following 'endless' loop runs twice for equality literals */
/* and only once for other literals. */
while (TRUE) {
Partners = inf_GetURPartnerLits(AtomCopy, Lit, TRUE, Index);
for ( ; !list_Empty(Partners); Partners = list_Pop(Partners)) {
PLit = list_Car(Partners);
/* Rename the atom */
PAtom = term_Copy(clause_LiteralAtom(PLit));
term_StartMaxRenaming(GlobalMaxVar);
term_Rename(PAtom);
/* Get the new global maximal variable */
NewMaxVar = term_MaxVar(PAtom);
if (symbol_GreaterVariable(GlobalMaxVar, NewMaxVar))
NewMaxVar = GlobalMaxVar;
/* Get the substitution */
cont_Check();
if (!unify_UnifyNoOC(cont_LeftContext(), AtomCopy,
cont_RightContext(), PAtom)) {
misc_StartErrorReport();
misc_ErrorReport("\n In inf_SearchURResolvents: Unification failed.");
misc_FinishErrorReport();
}
subst_ExtractUnifier(cont_LeftContext(), &NewSubst,
cont_RightContext(), &RightSubst);
cont_Reset();
subst_Delete(RightSubst); /* Forget substitution for unit clause */
term_Delete(PAtom); /* Was just needed to get the substitution */
/* Build the composition of the substitutions */
RightSubst = NewSubst;
NewSubst = subst_Compose(NewSubst, subst_Copy(Subst));
subst_Delete(RightSubst);
FoundMap = list_Cons(list_PairCreate(Lit, PLit), FoundMap);
Result = list_Nconc(inf_SearchURResolvents(Clause,i,FoundMap,RestLits,
NewSubst,NewMaxVar,Index,
Flags, Precedence),
Result);
list_PairFree(list_Car(FoundMap));
FoundMap = list_Pop(FoundMap);
subst_Delete(NewSubst);
}
/* loop control */
if (!fol_IsEquality(AtomCopy) || Swapped)
break;
else {
term_EqualitySwap(AtomCopy);
Swapped = TRUE;
}
}
/* cleanup */
term_Delete(AtomCopy);
list_Delete(RestLits);
return Result;
}
}
static LIST inf_NonUnitURResolution(CLAUSE Clause, int SpecialLitIndex,
LIST FoundMap, SUBST Subst,
SYMBOL GlobalMaxVar, SHARED_INDEX Index,
FLAGSTORE Flags, PRECEDENCE Precedence)
/**************************************************************
INPUT: A non-unit clause, a literal index from <Clause>.
<FoundMap> is a list of pairs (l1,l2) of unifiable literals,
where l1 is from <Clause> and l2 is from a unit clause.
At this point the list has at most one element.
<Subst> is the substitution for <Clause>.
<GlobalMaxVar> is the maximal variable encountered so far.
<Index> is used to search unifiable literals.
The flag store and the precedence are needed to create
the new clauses.
RETURNS: The list of UR resolution resolvents.
EFFECT: If inf_URResolution was called with a unit clause,
<SpecialLitIndex> is the index of a literal from a non-unit
clause, that is unifiable with the unit clause's literal,
otherwise it is set to -1.
***************************************************************/
{
LIST Result, RestLits;
int i, last;
Result = list_Nil();
RestLits = clause_GetLiteralListExcept(Clause, SpecialLitIndex);
last = clause_LastLitIndex(Clause);
for (i = clause_FirstLitIndex(); i <= last; i++) {
/* <i> is the index of the literal that remains in the resolvent */
if (i != SpecialLitIndex) {
RestLits = list_PointerDeleteOneElement(RestLits,
clause_GetLiteral(Clause,i));
Result = list_Nconc(inf_SearchURResolvents(Clause, i, FoundMap, RestLits,
Subst, GlobalMaxVar, Index,
Flags, Precedence),
Result);
RestLits = list_Cons(clause_GetLiteral(Clause, i), RestLits);
}
}
list_Delete(RestLits);
return Result;
}
LIST inf_URResolution(CLAUSE Clause, SHARED_INDEX Index, FLAGSTORE Flags,
PRECEDENCE Precedence)
/**************************************************************
INPUT: A clause, a shared index, a flag store and a precedence.
RETURNS: The list of UR resolution resolvents.
EFFECT: The flag store and the precedence are needed to create
the resolvents.
***************************************************************/
{
LIST Result;
if (clause_Length(Clause) != 1) {
/* Clause isn't unit clause */
Result = inf_NonUnitURResolution(Clause, -1, list_Nil(), subst_Nil(),
clause_MaxVar(Clause), Index, Flags,
Precedence);
}
else {
/* Clause is unit clause, so search partner literals in non-unit clauses */
LITERAL Lit, PLit;
TERM Atom;
LIST Partners, FoundMap;
SYMBOL MaxVar, PMaxVar;
SUBST LeftSubst, RightSubst;
CLAUSE PClause;
int PLitInd;
BOOL Swapped;
Result = list_Nil();
Lit = clause_GetLiteral(Clause, clause_FirstLitIndex());
Atom = term_Copy(clause_LiteralAtom(Lit));
Swapped = FALSE;
/* The following 'endless' loop runs twice for equality literals */
/* and only once for other literals. */
while (TRUE) {
/* Get complementary literals from non-unit clauses */
Partners = inf_GetURPartnerLits(Atom, Lit, FALSE, Index);
for ( ; !list_Empty(Partners); Partners = list_Pop(Partners)) {
PLit = list_Car(Partners);
PLitInd = clause_LiteralGetIndex(PLit);
PClause = clause_LiteralOwningClause(PLit); /* non-unit clause */
PMaxVar = clause_MaxVar(PClause);
term_StartMaxRenaming(PMaxVar);
term_Rename(Atom); /* Rename atom from unit clause */
MaxVar = term_MaxVar(Atom);
if (symbol_GreaterVariable(PMaxVar, MaxVar))
MaxVar = PMaxVar;
/* Get the substitution */
cont_Check();
unify_UnifyNoOC(cont_LeftContext(), clause_LiteralAtom(PLit),
cont_RightContext(), Atom);
subst_ExtractUnifier(cont_LeftContext(), &LeftSubst,
cont_RightContext(), &RightSubst);
cont_Reset();
/* We don't need the substitution for the unit clause */
subst_Delete(RightSubst);
FoundMap = list_List(list_PairCreate(PLit, Lit));
Result = list_Nconc(inf_NonUnitURResolution(PClause, PLitInd, FoundMap,
LeftSubst, MaxVar, Index,
Flags, Precedence),
Result);
list_DeletePairList(FoundMap);
subst_Delete(LeftSubst);
}
/* loop control */
if (!fol_IsEquality(Atom) || Swapped)
break;
else {
term_EqualitySwap(Atom);
Swapped = TRUE;
}
} /* end of endless loop */
term_Delete(Atom);
}
return Result;
}