diff options
author | xleroy <xleroy@fca1b0fc-160b-0410-b1d3-a4f43f01ea2e> | 2010-03-03 12:34:43 +0000 |
---|---|---|
committer | xleroy <xleroy@fca1b0fc-160b-0410-b1d3-a4f43f01ea2e> | 2010-03-03 12:34:43 +0000 |
commit | 6c196ec8a41d6ed506c133c8b33dba9684f9a7a6 (patch) | |
tree | 4e1422ea2a810520d0d9b0fbb78c0014ba9f8443 /test/spass/sort.c | |
parent | 93d89c2b5e8497365be152fb53cb6cd4c5764d34 (diff) | |
download | compcert-6c196ec8a41d6ed506c133c8b33dba9684f9a7a6.tar.gz compcert-6c196ec8a41d6ed506c133c8b33dba9684f9a7a6.zip |
Updated raytracer test. Added SPASS test.
git-svn-id: https://yquem.inria.fr/compcert/svn/compcert/trunk@1271 fca1b0fc-160b-0410-b1d3-a4f43f01ea2e
Diffstat (limited to 'test/spass/sort.c')
-rw-r--r-- | test/spass/sort.c | 1974 |
1 files changed, 1974 insertions, 0 deletions
diff --git a/test/spass/sort.c b/test/spass/sort.c new file mode 100644 index 00000000..e109ef13 --- /dev/null +++ b/test/spass/sort.c @@ -0,0 +1,1974 @@ +/**************************************************************/ +/* ********************************************************** */ +/* * * */ +/* * SORTED REASONING * */ +/* * * */ +/* * $Module: SORT * */ +/* * * */ +/* * 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: 21527 $ * */ +/* $State$ * */ +/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $ * */ +/* $Author: duraid $ * */ +/* * * */ +/* * Contact: * */ +/* * Christoph Weidenbach * */ +/* * MPI fuer Informatik * */ +/* * Stuhlsatzenhausweg 85 * */ +/* * 66123 Saarbruecken * */ +/* * Email: weidenb@mpi-sb.mpg.de * */ +/* * Germany * */ +/* * * */ +/* ********************************************************** */ +/**************************************************************/ + + +/* $RCSfile$ */ + +#include "sort.h" + +/**************************************************************/ +/* Global Variables */ +/**************************************************************/ + + +/**************************************************************/ +/* ********************************************************** */ +/* * * */ +/* * HIGH LEVEL FUNCTIONS * */ +/* * * */ +/* ********************************************************** */ +/**************************************************************/ + +void sort_Delete(SORT Sort) +/************************************************************** + INPUT: A sort. + RETURNS: Nothing. + MEMORY: The memory of the sort is freed. +***************************************************************/ +{ + list_Delete(Sort); +} + +BOOL sort_Eq(SORT S1, SORT S2) +/************************************************************** + INPUT: Two sorts. + RETURNS: TRUE iff the sorts <S1> and <S2> are the same base + sort intersection +***************************************************************/ +{ + LIST Scan1,Scan2; + BOOL Found; + +#ifdef CHECK + if (!sort_IsSort(S1) || !sort_IsSort(S2)) { + misc_StartErrorReport(); + misc_ErrorReport("\n In sort_Eq :"); + misc_ErrorReport(" Illegal input.\n"); + misc_FinishErrorReport(); + } +#endif + + if (list_Length(S1) != list_Length(S2)) + return FALSE; + + for (Scan1=S1; !list_Empty(Scan1); Scan1=list_Cdr(Scan1)) { + Found = FALSE; + for (Scan2=S2; !list_Empty(Scan2) && !Found; Scan2=list_Cdr(Scan2)) + Found = sort_NodeEqual(list_Car(Scan1),list_Car(Scan2)); + if (!Found) + return FALSE; + } + + return TRUE; +} + + +LIST sort_GetSymbolsFromSort(SORT Sort) +/************************************************************** + INPUT: A sort. + RETURNS: The list of sort symbols.. +***************************************************************/ +{ + LIST result = list_Nil(); + + for ( ; !list_Empty(Sort); Sort = list_Cdr(Sort)) + result = list_Cons((POINTER)sort_NodeSymbol(list_Car(Sort)), result); + + return result; +} + +BOOL sort_ContainsSymbol(SORT Sort, SYMBOL Symbol) +/************************************************************** + INPUT: A sort and a symbol. + RETURNS: TRUE, if the sort contains the symbol, FALSE otherwise. +***************************************************************/ +{ + for ( ; !list_Empty(Sort); Sort = list_Cdr(Sort)) + if (symbol_Equal(sort_NodeSymbol(list_Car(Sort)), Symbol)) + return TRUE; + + return FALSE; +} + +BOOL sort_IsSort(SORT Sort) +/************************************************************** + INPUT: A sort. + RETURNS: TRUE, if the sort contains not more than one node. +***************************************************************/ +{ + LIST Scan1,Scan2; + + for (Scan1=Sort ; !list_Empty(Scan1); Scan1 = list_Cdr(Scan1)) + for (Scan2=list_Cdr(Scan1) ; !list_Empty(Scan2); Scan2 = list_Cdr(Scan2)) + if (sort_NodeEqual(list_Car(Scan1),list_Car(Scan2))) + return FALSE; + + return TRUE; +} + +BOOL sort_TheorySortEqual(SORTTHEORY Theory, SORT Sort1, SORT Sort2) +/************************************************************** + INPUT: + RETURNS: +***************************************************************/ +{ + LIST Scan; + + if (list_Length(Sort1) != list_Length(Sort2)) + return FALSE; + + sort_TheoryIncrementMark(Theory); + + for (Scan=Sort1; !list_Empty(Scan); Scan=list_Cdr(Scan)) + sort_PutNodeExtraTrue(Theory,list_Car(Scan)); + for (Scan=Sort2; !list_Empty(Scan); Scan=list_Cdr(Scan)) + if (!sort_NodeExtraValue(Theory,list_Car(Scan))) + return FALSE; + + return TRUE; +} + +static BOOL sort_TheorySortMember(SORTTHEORY Theory, LIST List, SORT Sort) +/************************************************************** + INPUT: + RETURNS: +***************************************************************/ +{ + while (!list_Empty(List)) { + if (sort_TheorySortEqual(Theory,list_Car(List),Sort)) + return TRUE; + List = list_Cdr(List); + } + return FALSE; +} + + +void sort_DeleteSortPair(SOJU Pair) +/************************************************************** + INPUT: + RETURNS: Nothing. +***************************************************************/ +{ + sort_DeleteOne(sort_PairSort(Pair)); + sort_ConditionDelete(sort_PairCondition(Pair)); + list_PairFree(Pair); +} + + + +static void sort_ConditionPrint(CONDITION Cond) +/************************************************************** + INPUT: + RETURNS: Nothing. +***************************************************************/ +{ + LIST Scan; + + symbol_Print(sort_ConditionVar(Cond)); + for (Scan=sort_ConditionConstraint(Cond);!list_Empty(Scan);Scan=list_Cdr(Scan)) { + putchar(','); + term_PrintPrefix(list_Car(Scan)); + } + for (Scan=sort_ConditionAntecedent(Cond);!list_Empty(Scan);Scan=list_Cdr(Scan)) { + putchar(','); + term_PrintPrefix(list_Car(Scan)); + } + for (Scan=sort_ConditionSuccedent(Cond);!list_Empty(Scan);Scan=list_Cdr(Scan)) { + putchar(','); + term_PrintPrefix(list_Car(Scan)); + } + for (Scan=sort_ConditionClauses(Cond);!list_Empty(Scan);Scan=list_Cdr(Scan)) { + printf(",%d",clause_Number(list_Car(Scan))); + } +} + +static void sort_LinkPrint(SLINK Link) +/************************************************************** + INPUT: + RETURNS: Nothing. +***************************************************************/ +{ + LIST Scan; + + fputs("Input: (", stdout); + for (Scan=sort_LinkInput(Link);!list_Empty(Scan);Scan=list_Cdr(Scan)) { + symbol_Print(sort_NodeSymbol(list_Car(Scan))); + if (!list_Empty(list_Cdr(Scan))) + putchar(','); + } + fputs(") Output: ", stdout); + symbol_Print(sort_NodeSymbol(sort_LinkOutput(Link))); + fputs(" C: (", stdout); + for (Scan=sort_LinkConstraint(Link);!list_Empty(Scan);Scan=list_Cdr(Scan)) { + term_PrintPrefix(list_Car(Scan)); + if (!list_Empty(list_Cdr(Scan))) + putchar(','); + } + fputs(") A: (", stdout); + for (Scan=sort_LinkAntecedent(Link);!list_Empty(Scan);Scan=list_Cdr(Scan)) { + term_PrintPrefix(list_Car(Scan)); + if (!list_Empty(list_Cdr(Scan))) + putchar(','); + } + fputs(") S: (", stdout); + for (Scan=sort_LinkSuccedent(Link);!list_Empty(Scan);Scan=list_Cdr(Scan)) { + term_PrintPrefix(list_Car(Scan)); + if (!list_Empty(list_Cdr(Scan))) + putchar(','); + } + printf(") Clause: %d Card: %d Fire: %d Var: ", clause_Number(sort_LinkClause(Link)), sort_LinkCard(Link), + sort_LinkFire(Link)); + symbol_Print(sort_LinkVar(Link)); +} + + + +void sort_PairPrint(SOJU Pair) +/************************************************************** + INPUT: + RETURNS: Nothing. +***************************************************************/ +{ + sort_Print(sort_PairSort(Pair)); + fputs(":[", stdout); + sort_ConditionPrint(sort_PairCondition(Pair)); + putchar(']'); +} + + +static NODE sort_NodeCreate(SYMBOL S) +/************************************************************** + INPUT: A sort symbol. + RETURNS: A new initialized sort node for the symbol <S>. +***************************************************************/ +{ + NODE Result; + + Result = (NODE)memory_Malloc(sizeof(NODE_NODE)); + + sort_PutNodeLinks(Result, list_Nil()); + sort_PutNodeConditions(Result, list_Nil()); + sort_PutNodeMark(Result, 0); + sort_PutNodeStart(Result, 0); + sort_PutNodeExtra(Result, 0); + sort_PutNodeSymbol(Result, S); + + return Result; +} + +BOOL sort_NodeIsTop(SORTTHEORY Theory, NODE Node) +/************************************************************** + INPUT: A sort theory and a node. + RETURNS: TRUE if the Node is declared to be equivalent to the + top sort. +***************************************************************/ +{ + LIST Scan; + SLINK Link; + + for (Scan=sort_TheorySuborigcls(Theory);!list_Empty(Scan);Scan=list_Cdr(Scan)) { + Link = (SLINK)list_Third(list_Car(Scan)); + if (list_Empty(sort_LinkInput(Link)) && Node == sort_LinkOutput(Link)) + return TRUE; + } + return FALSE; +} + + +static SLINK sort_TheoryLinkCreate(SORTTHEORY Theory, CLAUSE Origin, + CLAUSE Clause, LITERAL Lit) +/************************************************************** + INPUT: A sort theory, a clause its origin and a subsort declaration + literal in the clause + RETURNS: A new link in <Theory> origin <Clause> and subsort declaration <Lit> +***************************************************************/ +{ + SLINK Result; + SYMBOL Output,Var,Max; + int i; + LIST Input, Antecedent, Succedent, Constraint; + TERM Term; + + Result = (SLINK)memory_Malloc(sizeof(SLINK_NODE)); + + Output = term_TopSymbol(clause_LiteralSignedAtom(Lit)); + Var = term_TopSymbol(term_FirstArgument(clause_LiteralSignedAtom(Lit))); + Input = Antecedent = Succedent = Constraint = list_Nil(); + Max = clause_MaxVar(Clause); + term_StartMaxRenaming(Max); + Max = symbol_CreateStandardVariable(); + + for (i = clause_FirstConstraintLitIndex(Clause); + i <= clause_LastConstraintLitIndex(Clause); i++) + if (symbol_Equal(Var,term_TopSymbol(term_FirstArgument(clause_GetLiteralAtom(Clause,i))))) + Input = list_Cons(sort_TheoryNode(Theory,term_TopSymbol(clause_GetLiteralAtom(Clause,i))), + Input); + else { + Term = term_Copy(clause_GetLiteralTerm(Clause,i)); + term_ExchangeVariable(Term,Var,Max); + Constraint = list_Cons(Term,Constraint); + } + + for (i = clause_FirstAntecedentLitIndex(Clause); + i <= clause_LastAntecedentLitIndex(Clause); i++) { + Term = term_Copy(clause_GetLiteralTerm(Clause,i)); + term_ExchangeVariable(Term,Var,Max); + Antecedent = list_Cons(Term,Antecedent); + } + + for (i = clause_FirstSuccedentLitIndex(Clause); + i <= clause_LastSuccedentLitIndex(Clause); i++) + if (clause_GetLiteral(Clause,i) != Lit) { + Term = term_Copy(clause_GetLiteralTerm(Clause,i)); + term_ExchangeVariable(Term,Var,Max); + Succedent = list_Cons(Term,Succedent); + } + + + sort_PutLinkInput(Result,Input); + sort_PutLinkOutput(Result,sort_TheoryNode(Theory,Output)); + sort_PutLinkVar(Result,Max); + sort_PutLinkConstraint(Result,Constraint); + sort_PutLinkAntecedent(Result,Antecedent); + sort_PutLinkSuccedent(Result,Succedent); + sort_PutLinkCard(Result,list_Length(Input)); + sort_LinkResetFire(Result); + sort_PutLinkClause(Result,Origin); + + while (!list_Empty(Input)) { + sort_PutNodeLinks(list_Car(Input),list_Cons(Result,sort_NodeLinks(list_Car(Input)))); + Input = list_Cdr(Input); + } + + return Result; +} + + +void sort_Init(void) +/************************************************************** + INPUT: None. + RETURNS: None. + SUMMARY: Initializes the sort Module. + EFFECTS: Initializes global variables, i.e. the BASESORT-Array. + CAUTION: MUST BE CALLED BEFORE ANY OTHER sort-FUNCTION. +***************************************************************/ +{ + return; +} + + +void sort_Print(SORT Sort) +/************************************************************** + INPUT: + RETURNS: Nothing. +***************************************************************/ +{ + putchar('('); + + while (!list_Empty(Sort)) { + symbol_Print(sort_NodeSymbol(list_Car(Sort))); + Sort = list_Cdr(Sort); + if (!list_Empty(Sort)) + putchar(','); + } + putchar(')'); +} + + +void sort_Free(void) +/************************************************************** + INPUT: None. + RETURNS: Nothing. + SUMMARY: Frees the sort Module. +***************************************************************/ +{ + return; +} + +SORTTHEORY sort_TheoryCreate(void) +/************************************************************** + INPUT: None. + RETURNS: A new sort theory. + EFFECT: A new sort theory is created and initialized. +***************************************************************/ +{ + SORTTHEORY Result; + int i; + SIGNATURE Entry; + SYMBOL Symbol; + + Result = (SORTTHEORY)memory_Malloc(sizeof(SORTTHEORY_NODE)); + + for (i = 1; i < symbol_ACTINDEX; i++) { + Result->basesorttable[i] = (NODE)NULL; + Entry = symbol_Signature(i); + if (Entry != NULL) { + Symbol = Entry->info; + if (symbol_IsPredicate(Symbol) && Entry->arity == 1) + Result->basesorttable[i] = sort_NodeCreate(Symbol); + } + } + + Result->index = st_IndexCreate(); + Result->suborigcls = list_Nil(); + Result->termorigcls = list_Nil(); + Result->mark = 0; + + return Result; +} + +void sort_TheoryPrint(SORTTHEORY Theory) +/************************************************************** + INPUT: A sort theory + RETURNS: None. + EFFECT: Prints the sort theory to stdout. +***************************************************************/ +{ + LIST Scan; + + if (Theory == (SORTTHEORY)NULL) { + fputs(" Empty Theory", stdout); + return; + } + + fputs("\n Subsort Clauses:", stdout); + for (Scan=sort_TheorySuborigcls(Theory);!list_Empty(Scan);Scan=list_Cdr(Scan)) { + fputs("\n\t\t Clause:", stdout); + clause_Print(list_Second(list_Car(Scan))); + fputs("\n\t\t Link: ", stdout); + sort_LinkPrint(list_Third(list_Car(Scan))); + } + fputs("\n Term Declaration Clauses:", stdout); + for (Scan=sort_TheoryTermorigcls(Theory);!list_Empty(Scan);Scan=list_Cdr(Scan)) { + fputs("\n\t\t Clause:", stdout); + clause_Print(list_Second(list_Car(Scan))); + } + +} + +void sort_TheoryDelete(SORTTHEORY Theory) +/************************************************************** + INPUT: A sort theory + RETURNS: None. + EFFECT: The complete sort theory is deleted. +***************************************************************/ +{ + if (Theory != (SORTTHEORY)NULL) { + int i; + LIST Scan,Tuple; + TERM Term, Atom; + + for (Scan=Theory->suborigcls;!list_Empty(Scan);Scan=list_Cdr(Scan)) { + Tuple = (LIST)list_Car(Scan); + sort_LinkDelete(list_Third(Tuple)); + clause_Delete(list_Second(Tuple)); + list_Delete(Tuple); + } + list_Delete(Theory->suborigcls); + for (Scan=Theory->termorigcls;!list_Empty(Scan);Scan=list_Cdr(Scan)) { + Tuple = (LIST)list_Car(Scan); + Term = (TERM)list_Third(Tuple); + Atom = (TERM)list_Car(term_SupertermList(Term)); + st_EntryDelete(Theory->index,Term,Term,cont_LeftContext()); + st_EntryDelete(Theory->index,Atom,Atom,cont_LeftContext()); + list_Delete(term_SupertermList(Atom)); + list_Delete(term_SupertermList(Term)); + term_RplacSupertermList(Term, list_Nil()); + term_RplacSupertermList(Atom, list_Nil()); + clause_Delete(list_Second(Tuple)); + list_Delete(Tuple); + } + list_Delete(Theory->termorigcls); + st_IndexDelete(Theory->index); + + for (i=1;i<symbol_ACTINDEX;i++) + if (Theory->basesorttable[i] != (NODE)NULL) + sort_NodeDelete(Theory->basesorttable[i]); + + memory_Free(Theory,sizeof(SORTTHEORY_NODE)); + } +} + +void sort_TheoryInsertClause(SORTTHEORY Theory, CLAUSE Origin, CLAUSE Clause, LITERAL L) +/************************************************************** + INPUT: A sort theory, two clauses and a declaration of the second clause. + <Origin> is the original clause and <Clause> is a possibly approximated + copy of <Origin>. + RETURNS: None. + EFFECT: Inserts <Clause> with declaration <L> into the sort theory. +***************************************************************/ +{ + TERM Term, Atom; + + Term = term_FirstArgument(clause_LiteralSignedAtom(L)); + + if (term_IsVariable(Term)) { + SLINK Link; + Link = sort_TheoryLinkCreate(Theory,Origin,Clause,L); + Theory->suborigcls = list_Cons(list_Cons(Origin,list_Cons(clause_Copy(Clause),list_List(Link))), + Theory->suborigcls); + } + + /* Since currently Sort Resolution and Empty Sort require the subsort declaration clauses */ + /* also subsort clauses are introduced into the sort theory index */ + + Atom = clause_LiteralSignedAtom(L); + term_RplacSupertermList(Atom, list_List(L)); + term_RplacSupertermList(Term, list_List(Atom)); /* Must be empty before this operation */ + st_EntryCreate(Theory->index,Term,Term,cont_LeftContext()); + st_EntryCreate(Theory->index,Atom,Atom,cont_LeftContext()); + Theory->termorigcls = list_Cons(list_Cons(Origin,list_Cons(Clause,list_List(Term))), + Theory->termorigcls); +} + +void sort_TheoryDeleteClause(SORTTHEORY Theory, CLAUSE Origin) +/************************************************************** + INPUT: A sort theory and a clause possibly inserted several times in the theory. + RETURNS: None. + EFFECT: <Origin> is deleted from the sort theory, but not deleted itself. +***************************************************************/ +{ + TERM Term,Atom; + LIST Scan,Tuple; + + for (Scan=Theory->suborigcls;!list_Empty(Scan);Scan=list_Cdr(Scan)) { + Tuple = list_Car(Scan); + if ((CLAUSE)list_First(Tuple) == Origin) { + list_Rplaca(Scan,NULL); + sort_LinkDelete(list_Third(Tuple)); + clause_Delete(list_Second(Tuple)); + list_Delete(Tuple); + } + } + Theory->suborigcls = list_PointerDeleteElement(Theory->suborigcls,NULL); + for (Scan=Theory->termorigcls;!list_Empty(Scan);Scan=list_Cdr(Scan)) { + Tuple = list_Car(Scan); + if ((CLAUSE)list_First(Tuple) == Origin) { + list_Rplaca(Scan,NULL); + Term = (TERM)list_Third(Tuple); + Atom = (TERM)list_Car(term_SupertermList(Term)); + st_EntryDelete(Theory->index,Term,Term,cont_LeftContext()); + st_EntryDelete(Theory->index,Atom,Atom,cont_LeftContext()); + list_Delete(term_SupertermList(Atom)); + list_Delete(term_SupertermList(Term)); + term_RplacSupertermList(Term, list_Nil()); + term_RplacSupertermList(Atom, list_Nil()); + clause_Delete(list_Second(Tuple)); + list_Delete(Tuple); + } + } + Theory->termorigcls = list_PointerDeleteElement(Theory->termorigcls,NULL); +} + +CONDITION sort_ConditionCreate(SYMBOL Var, LIST Constr, LIST Ante, LIST Succ, LIST Clauses) +/************************************************************** + INPUT: A variable, a list of constraint literals, antecedent literals, succedent literals + and a list of clauses. + RETURNS: The condition created from these arguments. + MEMORY: It is assumed that all literals are unshared whereas the clauses are shared. +***************************************************************/ +{ + CONDITION Result; + + Result = (CONDITION)memory_Malloc(sizeof(CONDITION_NODE)); + + sort_ConditionPutVar(Result, Var); + sort_ConditionPutConstraint(Result, Constr); + sort_ConditionPutAntecedent(Result, Ante); + sort_ConditionPutSuccedent(Result, Succ); + sort_ConditionPutClauses(Result, Clauses); + + return Result; +} + +CONDITION sort_ConditionNormalize(CONDITION Cond) +/************************************************************** + INPUT: A condition. + RETURNS: The normalized condition, i.e., the variables for the various + literals are normalized starting with the minimal variable. + EFFECT: Destructive. +***************************************************************/ +{ + LIST Scan; + SYMBOL Old,New; + + term_StartMinRenaming(); + for (Scan=sort_ConditionConstraint(Cond);!list_Empty(Scan);Scan=list_Cdr(Scan)) + term_Rename(list_Car(Scan)); + for (Scan=sort_ConditionAntecedent(Cond);!list_Empty(Scan);Scan=list_Cdr(Scan)) + term_Rename(list_Car(Scan)); + for (Scan=sort_ConditionSuccedent(Cond);!list_Empty(Scan);Scan=list_Cdr(Scan)) + term_Rename(list_Car(Scan)); + New = symbol_CreateStandardVariable(); + Old = term_GetRenamedVarSymbol(sort_ConditionVar(Cond)); + for (Scan=sort_ConditionConstraint(Cond);!list_Empty(Scan);Scan=list_Cdr(Scan)) + term_ExchangeVariable(list_Car(Scan),Old,New); + for (Scan=sort_ConditionAntecedent(Cond);!list_Empty(Scan);Scan=list_Cdr(Scan)) + term_ExchangeVariable(list_Car(Scan),Old,New); + for (Scan=sort_ConditionSuccedent(Cond);!list_Empty(Scan);Scan=list_Cdr(Scan)) + term_ExchangeVariable(list_Car(Scan),Old,New); + + sort_ConditionPutVar(Cond,New); + + return Cond; +} + +CONDITION sort_ConditionCreateNoResidues(LIST Clauses) +/************************************************************** + INPUT: A list of clauses. + RETURNS: The condition created just from the clauses. +***************************************************************/ +{ + CONDITION Result; + + Result = (CONDITION)memory_Malloc(sizeof(CONDITION_NODE)); + + sort_ConditionPutVar(Result, symbol_FirstVariable()); + sort_ConditionPutConstraint(Result, list_Nil()); + sort_ConditionPutAntecedent(Result, list_Nil()); + sort_ConditionPutSuccedent(Result, list_Nil()); + sort_ConditionPutClauses(Result, Clauses); + + return Result; +} + +CONDITION sort_ExtendConditionByLink(CONDITION Cond, SLINK Link) +/************************************************************** + INPUT: A condition and a link. + RETURNS: <Cond> extended by the clause, antecedent, constraint and succedent + literals of <Link> + EFFECT: <Cond> is destructively extended with <Link>. +***************************************************************/ +{ + LIST Lits,Antecedent,Succedent,Constraint; + SYMBOL Old,New; + + + term_StartMaxRenaming(sort_ConditionVar(Cond)); + Constraint = term_CopyTermList(sort_LinkConstraint(Link)); + Antecedent = term_CopyTermList(sort_LinkAntecedent(Link)); + Succedent = term_CopyTermList(sort_LinkSuccedent(Link)); + for (Lits=Constraint;!list_Empty(Lits);Lits=list_Cdr(Lits)) + term_Rename(list_Car(Lits)); + for (Lits=Antecedent;!list_Empty(Lits);Lits=list_Cdr(Lits)) + term_Rename(list_Car(Lits)); + for (Lits=Succedent;!list_Empty(Lits);Lits=list_Cdr(Lits)) + term_Rename(list_Car(Lits)); + Old = term_GetRenamedVarSymbol(sort_LinkVar(Link)); + New = symbol_CreateStandardVariable(); + for (Lits=Constraint;!list_Empty(Lits);Lits=list_Cdr(Lits)) + term_ExchangeVariable(list_Car(Lits),Old,New); + for (Lits=Antecedent;!list_Empty(Lits);Lits=list_Cdr(Lits)) + term_ExchangeVariable(list_Car(Lits),Old,New); + for (Lits=Succedent;!list_Empty(Lits);Lits=list_Cdr(Lits)) + term_ExchangeVariable(list_Car(Lits),Old,New); + Old = sort_ConditionVar(Cond); + for (Lits=sort_ConditionConstraint(Cond);!list_Empty(Lits);Lits=list_Cdr(Lits)) + term_ExchangeVariable(list_Car(Lits),Old,New); + for (Lits=sort_ConditionAntecedent(Cond);!list_Empty(Lits);Lits=list_Cdr(Lits)) + term_ExchangeVariable(list_Car(Lits),Old,New); + for (Lits=sort_ConditionSuccedent(Cond);!list_Empty(Lits);Lits=list_Cdr(Lits)) + term_ExchangeVariable(list_Car(Lits),Old,New); + sort_ConditionPutConstraint(Cond,list_Nconc(sort_ConditionConstraint(Cond),Constraint)); + sort_ConditionPutAntecedent(Cond,list_Nconc(sort_ConditionAntecedent(Cond),Antecedent)); + sort_ConditionPutSuccedent(Cond,list_Nconc(sort_ConditionSuccedent(Cond),Succedent)); + sort_ConditionPutClauses(Cond,list_Cons(sort_LinkClause(Link),sort_ConditionClauses(Cond))); + sort_ConditionPutVar(Cond,New); + sort_ConditionNormalize(Cond); + + return Cond; + +} + +CONDITION sort_ExtendConditionByCondition(CONDITION Cond, CONDITION Update) +/************************************************************** + INPUT: Two conditions. + RETURNS: <Cond> extended by the clauses, antecedent, constraint and succedent + literals of <Update> + EFFECT: <Cond> is destructively extended by <Update>. +***************************************************************/ +{ + LIST Lits,Antecedent,Succedent,Constraint; + SYMBOL Old,New; + + term_StartMaxRenaming(sort_ConditionVar(Cond)); + Constraint = term_CopyTermList(sort_ConditionConstraint(Update)); + Antecedent = term_CopyTermList(sort_ConditionAntecedent(Update)); + Succedent = term_CopyTermList(sort_ConditionSuccedent(Update)); + for (Lits=Constraint;!list_Empty(Lits);Lits=list_Cdr(Lits)) + term_Rename(list_Car(Lits)); + for (Lits=Antecedent;!list_Empty(Lits);Lits=list_Cdr(Lits)) + term_Rename(list_Car(Lits)); + for (Lits=Succedent;!list_Empty(Lits);Lits=list_Cdr(Lits)) + term_Rename(list_Car(Lits)); + Old = term_GetRenamedVarSymbol(sort_ConditionVar(Update)); + New = symbol_CreateStandardVariable(); + for (Lits=Constraint; !list_Empty(Lits); Lits=list_Cdr(Lits)) + term_ExchangeVariable(list_Car(Lits),Old,New); + for (Lits=Antecedent; !list_Empty(Lits); Lits=list_Cdr(Lits)) + term_ExchangeVariable(list_Car(Lits),Old,New); + for (Lits=Succedent; !list_Empty(Lits); Lits=list_Cdr(Lits)) + term_ExchangeVariable(list_Car(Lits),Old,New); + Old = sort_ConditionVar(Cond); + for (Lits=sort_ConditionConstraint(Cond);!list_Empty(Lits);Lits=list_Cdr(Lits)) + term_ExchangeVariable(list_Car(Lits),Old,New); + for (Lits=sort_ConditionAntecedent(Cond);!list_Empty(Lits);Lits=list_Cdr(Lits)) + term_ExchangeVariable(list_Car(Lits),Old,New); + for (Lits=sort_ConditionSuccedent(Cond);!list_Empty(Lits);Lits=list_Cdr(Lits)) + term_ExchangeVariable(list_Car(Lits),Old,New); + sort_ConditionPutConstraint(Cond,list_Nconc(sort_ConditionConstraint(Cond),Constraint)); + sort_ConditionPutAntecedent(Cond,list_Nconc(sort_ConditionAntecedent(Cond),Antecedent)); + sort_ConditionPutSuccedent(Cond,list_Nconc(sort_ConditionSuccedent(Cond),Succedent)); + sort_ConditionPutClauses(Cond,list_Nconc(list_Copy(sort_ConditionClauses(Update)), + sort_ConditionClauses(Cond))); + sort_ConditionPutVar(Cond,New); + sort_ConditionNormalize(Cond); + + return Cond; +} + +LIST sort_ExtendConditions(LIST Conditions, SLINK Link) +/************************************************************** + INPUT: A list of conditions and a link. + RETURNS: A new list of conditions augmented by the conditions in <Link>. +***************************************************************/ +{ + LIST Result,Scan,Antecedent,Succedent,Constraint; + CONDITION Cond; + + Result = list_Nil(); + + for (Scan=Conditions;!list_Empty(Scan);Scan=list_Cdr(Scan)) { + Cond = (CONDITION)list_Car(Scan); + Constraint = term_CopyTermList(sort_ConditionConstraint(Cond)); + Antecedent = term_CopyTermList(sort_ConditionAntecedent(Cond)); + Succedent = term_CopyTermList(sort_ConditionSuccedent(Cond)); + if (sort_LinkNoResidues(Link)) + Result = list_Cons(sort_ConditionCreate(sort_ConditionVar(Cond),Constraint,Antecedent, + Succedent,list_Cons(sort_LinkClause(Link), + list_Copy(sort_ConditionClauses(Cond)))), + Result); + else { + SYMBOL New,Old; + LIST NewAntecedent,NewSuccedent,NewConstraint,Lits; + term_StartMaxRenaming(sort_ConditionVar(Cond)); + NewConstraint = term_CopyTermList(sort_LinkConstraint(Link)); + NewAntecedent = term_CopyTermList(sort_LinkAntecedent(Link)); + NewSuccedent = term_CopyTermList(sort_LinkSuccedent(Link)); + for (Lits=NewConstraint; !list_Empty(Lits); Lits=list_Cdr(Lits)) + term_Rename(list_Car(Lits)); + for (Lits=NewAntecedent; !list_Empty(Lits); Lits=list_Cdr(Lits)) + term_Rename(list_Car(Lits)); + for (Lits=NewSuccedent; !list_Empty(Lits); Lits=list_Cdr(Lits)) + term_Rename(list_Car(Lits)); + Old = term_GetRenamedVarSymbol(sort_LinkVar(Link)); + New = symbol_CreateStandardVariable(); + for (Lits=NewConstraint; !list_Empty(Lits); Lits=list_Cdr(Lits)) + term_ExchangeVariable(list_Car(Lits),Old,New); + for (Lits=NewAntecedent; !list_Empty(Lits); Lits=list_Cdr(Lits)) + term_ExchangeVariable(list_Car(Lits),Old,New); + for (Lits=NewSuccedent; !list_Empty(Lits); Lits=list_Cdr(Lits)) + term_ExchangeVariable(list_Car(Lits),Old,New); + Old = sort_ConditionVar(Cond); + for (Lits=Constraint; !list_Empty(Lits); Lits=list_Cdr(Lits)) + term_ExchangeVariable(list_Car(Lits),Old,New); + for (Lits=Antecedent; !list_Empty(Lits); Lits=list_Cdr(Lits)) + term_ExchangeVariable(list_Car(Lits),Old,New); + for (Lits=Succedent; !list_Empty(Lits); Lits=list_Cdr(Lits)) + term_ExchangeVariable(list_Car(Lits),Old,New); + Result = list_Cons(sort_ConditionNormalize(sort_ConditionCreate(New,list_Nconc(Constraint,NewConstraint), + list_Nconc(Antecedent,NewAntecedent), + list_Nconc(Succedent,NewSuccedent), + list_Cons(sort_LinkClause(Link), + list_Copy(sort_ConditionClauses(Cond))))), + Result); + } + } + return Result; +} + +CONDITION sort_ConditionsUnion(LIST Conditions) +/************************************************************** + INPUT: A list of conditions. + RETURNS: A new condition that is the union of all input conditions. +***************************************************************/ +{ + LIST Scan,Antecedent,Succedent,Constraint; + CONDITION Cond; + SYMBOL Act,New,Old; + LIST NewAntecedent,NewSuccedent,NewConstraint,NewClauses,Lits; + + if (list_Empty(Conditions)) + return sort_ConditionCreate(symbol_FirstVariable(),list_Nil(),list_Nil(),list_Nil(), + list_Nil()); + else { + Cond = (CONDITION)list_Car(Conditions); + Conditions = list_Cdr(Conditions); + Act = sort_ConditionVar(Cond); + NewConstraint = term_CopyTermList(sort_ConditionConstraint(Cond)); + NewAntecedent = term_CopyTermList(sort_ConditionAntecedent(Cond)); + NewSuccedent = term_CopyTermList(sort_ConditionSuccedent(Cond)); + NewClauses = list_Copy(sort_ConditionClauses(Cond)); + } + + for (Scan=Conditions;!list_Empty(Scan);Scan=list_Cdr(Scan)) { + Cond = (CONDITION)list_Car(Scan); + if (!sort_ConditionNoResidues(Cond)) { + Constraint = term_CopyTermList(sort_ConditionConstraint(Cond)); + Antecedent = term_CopyTermList(sort_ConditionAntecedent(Cond)); + Succedent = term_CopyTermList(sort_ConditionSuccedent(Cond)); + + term_StartMaxRenaming(Act); + for (Lits=Constraint; !list_Empty(Lits); Lits=list_Cdr(Lits)) + term_Rename(list_Car(Lits)); + for (Lits=Antecedent; !list_Empty(Lits); Lits=list_Cdr(Lits)) + term_Rename(list_Car(Lits)); + for (Lits=Succedent; !list_Empty(Lits); Lits=list_Cdr(Lits)) + term_Rename(list_Car(Lits)); + Old = term_GetRenamedVarSymbol(sort_ConditionVar(Cond)); + New = symbol_CreateStandardVariable(); + for (Lits=Constraint; !list_Empty(Lits); Lits=list_Cdr(Lits)) + term_ExchangeVariable(list_Car(Lits),Old,New); + for (Lits=Antecedent; !list_Empty(Lits); Lits=list_Cdr(Lits)) + term_ExchangeVariable(list_Car(Lits),Old,New); + for (Lits=Succedent; !list_Empty(Lits); Lits=list_Cdr(Lits)) + term_ExchangeVariable(list_Car(Lits),Old,New); + for (Lits=NewConstraint; !list_Empty(Lits); Lits=list_Cdr(Lits)) + term_ExchangeVariable(list_Car(Lits),Act,New); + for (Lits=NewAntecedent; !list_Empty(Lits); Lits=list_Cdr(Lits)) + term_ExchangeVariable(list_Car(Lits),Act,New); + for (Lits=NewSuccedent; !list_Empty(Lits); Lits=list_Cdr(Lits)) + term_ExchangeVariable(list_Car(Lits),Act,New); + Act = New; + NewConstraint = list_Nconc(Constraint,NewConstraint); + NewAntecedent = list_Nconc(Antecedent,NewAntecedent); + NewSuccedent = list_Nconc(Succedent,NewSuccedent); + } + NewClauses = list_Nconc(list_Copy(sort_ConditionClauses(Cond)),NewClauses); + } + + return sort_ConditionNormalize(sort_ConditionCreate(Act,NewConstraint,NewAntecedent,NewSuccedent,NewClauses)); +} + +void sort_ConditionDelete(CONDITION C) +/************************************************************** + INPUT: A condition. + RETURNS: Nothing. + MEMORY: The condition and all literals and lists are deleted. +***************************************************************/ +{ + if (C!= (CONDITION)NULL) { + term_DeleteTermList(sort_ConditionConstraint(C)); + term_DeleteTermList(sort_ConditionAntecedent(C)); + term_DeleteTermList(sort_ConditionSuccedent(C)); + list_Delete(sort_ConditionClauses(C)); + + sort_ConditionFree(C); + } +} + + +CONDITION sort_ConditionCopy(CONDITION C) +/************************************************************** + INPUT: A condition. + RETURNS: A copy of the condition. +***************************************************************/ +{ + return sort_ConditionCreate(sort_ConditionVar(C), + term_CopyTermList(sort_ConditionConstraint(C)), + term_CopyTermList(sort_ConditionAntecedent(C)), + term_CopyTermList(sort_ConditionSuccedent(C)), + list_Copy(sort_ConditionClauses(C))); +} + + + +BOOL sort_IsBaseSortSymbol(SYMBOL Symbol) +/********************************************************* + INPUT: A Symbol. + RETURNS: The boolean value TRUE, if 'Symbol' is a + basesortsymbol, FALSE else. +*******************************************************/ +{ +#ifdef CHECK + if (!symbol_IsSymbol(Symbol)) { + misc_StartErrorReport(); + misc_ErrorReport("\n In sort_IsBaseSymbol :"); + misc_ErrorReport(" Illegal input. Input not a symbol.\n"); + misc_FinishErrorReport(); + } +#endif + + return(symbol_IsPredicate(Symbol) && symbol_Arity(Symbol) == 1); +} + + +SORT sort_TheorySortOfSymbol(SORTTHEORY Theory, SYMBOL Symbol) +/********************************************************* + INPUT: A sort theory and a base sort symbol. + RETURNS: The Basesort of 'Symbol'. +*******************************************************/ +{ +#ifdef CHECK + if (!sort_IsBaseSortSymbol(Symbol)) { + misc_StartErrorReport(); + misc_ErrorReport("\n In sort_TheorySortOfSymbol :"); + misc_ErrorReport(" Illegal input. Input not a symbol.\n"); + misc_FinishErrorReport(); + } +#endif + + return (list_List(sort_TheoryNode(Theory, Symbol))); +} + + +static void sort_EvalSubsortNoResidues(SORTTHEORY Theory, LIST Nodes) +/********************************************************* + INPUT: A sort theory and a list of nodes from this theory. + RETURNS: None. + EFFECT: Starting from the nodes in <Nodes> the subsort + graph is exploited as long as links fire and + new nodes become true. Only links without residues + are considered. +*******************************************************/ +{ + NODE Node,Head; + LIST Scan,Help,Clauses; + SLINK Link; + + while (!list_Empty(Nodes)) { + Node = (NODE)list_Car(Nodes); + Scan = Nodes; + Nodes = list_Cdr(Nodes); + list_Free(Scan); + + for (Scan = sort_NodeLinks(Node); + !list_Empty(Scan); + Scan = list_Cdr(Scan)) { + Link = (SLINK)list_Car(Scan); + if (sort_LinkNoResidues(Link) && sort_LinkDecrementFire(Link) == 0) { + Head = sort_LinkOutput(Link); + if (!sort_NodeValue(Theory, Head)) { + Clauses = list_List(sort_LinkClause(Link)); + for (Help=sort_LinkInput(Link);!list_Empty(Help);Help=list_Cdr(Help)) + if (!list_Empty(sort_NodeConditions(list_Car(Help)))) + Clauses = + list_Nconc(list_Copy(sort_ConditionClauses( + list_Car(sort_NodeConditions(list_Car(Help))))),Clauses); + sort_DeleteConditionList(sort_NodeConditions(Head)); + sort_PutNodeConditions(Head,list_List(sort_ConditionCreateNoResidues(Clauses))); + sort_PutNodeTrue(Theory, Head); + Nodes = list_Cons(Head,Nodes); + } + } + } + } +} + + +static BOOL sort_TestSubsortSpecial(SORTTHEORY Theory, LIST Nodes, LIST Goal) +/********************************************************* + INPUT: A sort theory and a list of nodes from this theory and + a list of goal nodes. + RETURNS: TRUE if we can walk from at least one node of <Nodes> over + a previously evaluated sort structure. +*******************************************************/ +{ + NODE Node,Head; + LIST Scan; + SLINK Link; + + while (!list_Empty(Nodes)) { + Node = (NODE)list_NCar(&Nodes); + if (list_PointerMember(Goal,Node)) { + list_Delete(Nodes); + return TRUE; + } + for (Scan = sort_NodeLinks(Node);!list_Empty(Scan);Scan = list_Cdr(Scan)) { + Link = (SLINK)list_Car(Scan); + if (sort_LinkFire(Link) == 0) { + Head = sort_LinkOutput(Link); + Nodes = list_Cons(Head,Nodes); + } + } + } + return FALSE; +} + +static void sort_EvalSubsortSpecial(SORTTHEORY Theory, LIST Nodes) +/********************************************************* + INPUT: A sort theory and a list of nodes from this theory. + RETURNS: None. + EFFECT: Starting from the nodes in <Nodes> the subsort + graph is exploited as long as links fire and + new nodes become true. Only links without residues + are considered. +*******************************************************/ +{ + NODE Node,Head; + LIST Scan; + SLINK Link; + + while (!list_Empty(Nodes)) { + Node = (NODE)list_NCar(&Nodes); + for (Scan = sort_NodeLinks(Node);!list_Empty(Scan);Scan = list_Cdr(Scan)) { + Link = (SLINK)list_Car(Scan); + if (sort_LinkDecrementFire(Link) == 0) { + Head = sort_LinkOutput(Link); + if (!sort_NodeValue(Theory, Head)) { + sort_PutNodeTrue(Theory, Head); + Nodes = list_Cons(Head,Nodes); + } + } + } + } +} + +static void sort_EvalSubsort(SORTTHEORY Theory, LIST Nodes) +/********************************************************* + INPUT: A sort theory and a list of nodes from this theory. + RETURNS: None. + EFFECT: Starting from the nodes in <Nodes> the subsort + graph is exploited as long as links fire and + new nodes become true. + Only ONE condition for each node becoming + valid is established. +*******************************************************/ +{ + NODE Node,Head; + LIST Scan,Help; + SLINK Link; + CONDITION Cond; + + while (!list_Empty(Nodes)) { + Node = (NODE)list_Car(Nodes); + Scan = Nodes; + Nodes = list_Cdr(Nodes); + list_Free(Scan); + + for (Scan = sort_NodeLinks(Node); + !list_Empty(Scan); + Scan = list_Cdr(Scan)) { + Link = (SLINK)list_Car(Scan); + if (sort_LinkDecrementFire(Link) == 0) { + Head = sort_LinkOutput(Link); + if (!sort_NodeValue(Theory, Head)) { + Cond = sort_ConditionCreate(symbol_FirstVariable(),list_Nil(),list_Nil(),list_Nil(),list_Nil()); + for (Help=sort_LinkInput(Link);!list_Empty(Help);Help=list_Cdr(Help)) + if (!list_Empty(sort_NodeConditions(list_Car(Help)))) + Cond = sort_ExtendConditionByCondition(Cond,list_Car(sort_NodeConditions(list_Car(Help)))); + sort_ExtendConditionByLink(Cond,Link); + sort_DeleteConditionList(sort_NodeConditions(Head)); + sort_PutNodeConditions(Head,list_List(Cond)); + sort_PutNodeTrue(Theory, Head); + Nodes = list_Cons(Head,Nodes); + } + } + } + } +} + + +CONDITION sort_TheoryIsSubsortOfNoResidues(SORTTHEORY Theory, SORT Sort1, SORT Sort2) +/********************************************************* + INPUT: A sort theory and two sorts. + RETURNS: A condition if <Sort1> is a subsort of <Sort2> and NULL otherwise. +*******************************************************/ +{ + LIST Scan,Clauses; + SLINK Link; + NODE Node; + SORT Top; + +#ifdef CHECK + if (!sort_IsSort(Sort1) || !sort_IsSort(Sort2)) { + misc_StartErrorReport(); + misc_ErrorReport("\n In sort_TheoryIsSubsortOfNoResidues :"); + misc_ErrorReport(" Illegal sort input.\n"); + misc_FinishErrorReport(); + } +#endif + + sort_TheoryIncrementMark(Theory); + + /*fputs("\n Subsort Test: ", stdout); + sort_Print(Sort1); + putchar(' '); + sort_Print(Sort2);*/ + + for (Scan=sort_TheorySuborigcls(Theory);!list_Empty(Scan);Scan=list_Cdr(Scan)) { + Link = (SLINK)list_Third(list_Car(Scan)); + sort_LinkResetFire(Link); + } + + for (Scan=Sort1;!list_Empty(Scan);Scan=list_Cdr(Scan)) { + Node = (NODE)list_Car(Scan); + sort_DeleteConditionList(sort_NodeConditions(Node)); + sort_PutNodeConditions(Node,list_List(sort_ConditionCreate(symbol_FirstVariable(), + list_Nil(),list_Nil(),list_Nil(),list_Nil()))); + sort_PutNodeTrue(Theory, Node); + } + + Top = sort_TopSort(); + for (Scan=sort_TheorySuborigcls(Theory);!list_Empty(Scan);Scan=list_Cdr(Scan)) { + Link = (SLINK)list_Third(list_Car(Scan)); + if (list_Empty(sort_LinkInput(Link)) && sort_LinkNoResidues(Link)) { + Node = sort_LinkOutput(Link); + Top = sort_AddBaseNode(Top,Node); + sort_DeleteConditionList(sort_NodeConditions(Node)); + sort_PutNodeConditions(Node,list_List(sort_ConditionCreateNoResidues(list_List(sort_LinkClause(Link))))); + sort_PutNodeTrue(Theory,Node); + } + } + + sort_EvalSubsortNoResidues(Theory,sort_Intersect(Top,sort_Copy(Sort1))); + Top = sort_TopSort(); + + Clauses = list_Nil(); + + for (Scan=Sort2;!list_Empty(Scan);Scan=list_Cdr(Scan)) { + Node = (NODE)list_Car(Scan); + if (!sort_NodeValue(Theory,Node)) { + /*puts(" FALSE");*/ + list_Delete(Clauses); + return NULL; + } + else + if (!list_Empty(sort_NodeConditions(Node))) + Clauses = list_Nconc(list_Copy(sort_ConditionClauses(list_Car(sort_NodeConditions(Node)))), + Clauses); + } + /*printf(" TRUE %lu\n",(unsigned long)Clauses);*/ + return sort_ConditionCreateNoResidues(Clauses); +} + +BOOL sort_TheoryIsSubsortOf(SORTTHEORY Theory, SORT Sort1, SORT Sort2) +/********************************************************* + INPUT: A sort theory and two sorts. + RETURNS: TRUE if <Sort1> is a subsort of <Sort2> and NULL otherwise. +*******************************************************/ +{ + LIST Scan; + SLINK Link; + NODE Node; + + sort_TheoryIncrementMark(Theory); + + /*fputs("\n Subsort Test: ", stdout); + sort_Print(Sort1); + putchar(' '); + sort_Print(Sort2);*/ + + for (Scan=sort_TheorySuborigcls(Theory);!list_Empty(Scan);Scan=list_Cdr(Scan)) { + Link = (SLINK)list_Third(list_Car(Scan)); + sort_LinkResetFire(Link); + } + + for (Scan=Sort1;!list_Empty(Scan);Scan=list_Cdr(Scan)) { + Node = (NODE)list_Car(Scan); + sort_PutNodeTrue(Theory, Node); + } + + sort_EvalSubsortSpecial(Theory,sort_Copy(Sort1)); + + for (Scan=Sort2;!list_Empty(Scan);Scan=list_Cdr(Scan)) { + Node = (NODE)list_Car(Scan); + if (!sort_NodeValue(Theory,Node)) + return FALSE; + } + + return TRUE; + +} + +BOOL sort_TheoryIsSubsortOfExtra(SORTTHEORY Theory, SORT Extra, SORT Sort1, SORT Sort2) +/********************************************************* + INPUT: A sort theory and three sorts. + RETURNS: TRUE if <Sort1> is a subsort of <Sort2> and <Extra> is + useful for that purpose +*******************************************************/ +{ + LIST Scan; + SLINK Link; + NODE Node; + + sort_TheoryIncrementMark(Theory); + + /*fputs("\n Subsort Test: ", stdout); + sort_Print(Sort1); + putchar(' '); + sort_Print(Sort2);*/ + + for (Scan=sort_TheorySuborigcls(Theory);!list_Empty(Scan);Scan=list_Cdr(Scan)) { + Link = (SLINK)list_Third(list_Car(Scan)); + sort_LinkResetFire(Link); + } + + for (Scan=Sort1;!list_Empty(Scan);Scan=list_Cdr(Scan)) { + Node = (NODE)list_Car(Scan); + sort_PutNodeTrue(Theory, Node); + } + + sort_EvalSubsortSpecial(Theory,sort_Copy(Sort1)); + + for (Scan=Sort2;!list_Empty(Scan);Scan=list_Cdr(Scan)) { + Node = (NODE)list_Car(Scan); + if (!sort_NodeValue(Theory,Node)) + return FALSE; + } + + return sort_TestSubsortSpecial(Theory,sort_Copy(Extra),Sort2); + +} + +LIST sort_TheoryComputeAllSubsortHits(SORTTHEORY Theory, SORT Sort1, SORT Sort2) +/********************************************************* + INPUT: A sort theory and two sorts. + RETURNS: All possible sorts that are subsets of <Sort1> that are subsorts + of <Sort2> together with all conditions. +*******************************************************/ +{ + LIST Scan,Result,Search,Scan2,Visited; + SLINK Link; + NODE Node; + SOJU Cand; + BOOL Valid,ValidStart; + NAT StartMark; + + sort_TheoryIncrementMark(Theory); + StartMark = sort_TheoryMark(Theory); + + /*fputs("\n Exhaustive Subsort Test: ", stdout); + sort_Print(Sort1); + putchar(' '); + sort_Print(Sort2);*/ + + for (Scan=sort_TheorySuborigcls(Theory);!list_Empty(Scan);Scan=list_Cdr(Scan)) { + Link = (SLINK)list_Third(list_Car(Scan)); + sort_LinkResetFire(Link); + } + + for (Scan=Sort1;!list_Empty(Scan);Scan=list_Cdr(Scan)) { + Node = (NODE)list_Car(Scan); + sort_DeleteConditionList(sort_NodeConditions(Node)); + sort_PutNodeConditions(Node,list_List(sort_ConditionCreate(symbol_FirstVariable(), + list_Nil(),list_Nil(),list_Nil(),list_Nil()))); + sort_PutNodeTrue(Theory, Node); + sort_PutNodeStartTrue(Theory,Node); + } + + sort_EvalSubsort(Theory,sort_Copy(Sort1)); + + for (Scan=Sort2;!list_Empty(Scan);Scan=list_Cdr(Scan)) {/* Subsort condition must hold */ + Node = (NODE)list_Car(Scan); + if (!sort_NodeValue(Theory,Node)) + return list_Nil(); + } + + Result = list_Nil(); + Search = list_List(sort_PairCreate(sort_Copy(Sort2),sort_ConditionCreateNoResidues(list_Nil()))); + Visited = list_Nil(); + fputs("\n\n Starting Soju Search:", stdout); + + while (!list_Empty(Search)) { + Cand = (SOJU)list_Car(Search); + Scan = Search; + Search = list_Cdr(Search); + list_Free(Scan); + putchar('\n'); + sort_PairPrint(Cand); + + if (!sort_TheorySortMember(Theory,Visited,sort_PairSort(Cand))) { + Visited = list_Cons(sort_Copy(sort_PairSort(Cand)),Visited); + ValidStart = TRUE; + Valid = TRUE; + for (Scan=sort_PairSort(Cand);!list_Empty(Scan) && (ValidStart || Valid);Scan=list_Cdr(Scan)) { + Node = (NODE)list_Car(Scan); + if (sort_NodeMark(Node) != StartMark) { + Valid = FALSE; + ValidStart = FALSE; + } + else + if (sort_NodeStart(Node) != StartMark) + ValidStart = FALSE; + } + if (Valid) { + if (ValidStart) + Result = list_Cons(sort_PairCopy(Cand),Result); + + for (Scan=sort_PairSort(Cand);!list_Empty(Scan);Scan=list_Cdr(Scan)) { + Node = (NODE)list_Car(Scan); + for (Scan2=sort_TheorySuborigcls(Theory);!list_Empty(Scan2);Scan2=list_Cdr(Scan2)) { + Link = (SLINK)list_Third(list_Car(Scan2)); + if (sort_LinkOutput(Link) == Node && !list_Empty(sort_LinkInput(Link))) + Search = list_Cons(sort_PairCreate(list_PointerDeleteDuplicates(sort_Intersect(sort_DeleteBaseNode(sort_Copy(sort_PairSort(Cand)),Node),sort_Copy(sort_LinkInput(Link)))), + sort_ExtendConditionByLink(sort_ConditionCopy(sort_PairCondition(Cand)),Link)), + Search); + } + } + } + sort_PairDelete(Cand); + } + } + list_DeleteWithElement(Visited,(void (*)(POINTER)) sort_Delete); + + return Result; +} + +static SORT sort_VarSort(SORTTHEORY Theory, SYMBOL Var, CLAUSE Clause, int i) +/********************************************************* + INPUT: A variable symbol, a clause and a literal index in the clause. + RETURNS: The sort of <Var> with respect to the sort constraint + literals (possibly in the antecedent) + in <Clause> except literal <i> that is not considered. + MEMORY: Both Sorts are destroyed. +*******************************************************/ +{ + SORT Result; + int j; + TERM Atom; + + Result = sort_TopSort(); + + for (j=clause_FirstConstraintLitIndex(Clause);j<=clause_LastAntecedentLitIndex(Clause);j++) + if (j != i) { + Atom = clause_LiteralAtom(clause_GetLiteral(Clause,j)); + if (symbol_IsBaseSort(term_TopSymbol(Atom)) && + term_TopSymbol(term_FirstArgument(Atom)) == Var) + Result = sort_Intersect(Result,sort_TheorySortOfSymbol(Theory,term_TopSymbol(Atom))); + } + + return Result; +} + + +static BOOL sort_MatchNoResidues(SORTTHEORY Theory, TERM Term1, TERM Term2, CLAUSE Clause, LIST* Clauses) +/********************************************************* + INPUT: A sort theory, two terms, a clause and list of clauses + as an additional return parameter. + RETURNS: TRUE iff there exists a well-sorted matcher from <Term1> to <Term2> + The sorts of variables in <Term1> is determined by the sort constraint in <Clause> + The sorts of subterms of <Term2> are assumed to be already computed and stored. +*******************************************************/ +{ + int l; + SUBST subst,scan; + SORT varsort; + LIST NewClauses; + SOJU Pair; + CONDITION Cond; + + l = clause_Length(Clause); + NewClauses = list_Nil(); + + cont_StartBinding(); + unify_Match(cont_LeftContext(),Term1,Term2); + subst = subst_ExtractMatcher(); + cont_BackTrack(); + + /*putchar('\n'); term_Print(Term1);fputs("->",stdout); + term_Print(Term2);putchar(':');subst_Print(subst); + putchar('\n');*/ + for (scan=subst;!subst_Empty(scan);scan=subst_Next(scan)) { + varsort = sort_VarSort(Theory,subst_Dom(scan),Clause,l); + Pair = hash_Get(subst_Cod(scan)); + if ((Cond = sort_TheoryIsSubsortOfNoResidues(Theory,sort_PairSort(Pair),varsort)) == NULL) { + sort_DeleteOne(varsort); + list_Delete(NewClauses); + subst_Free(subst); + return FALSE; + } else { + NewClauses = list_Nconc(NewClauses, + list_Copy(sort_ConditionClauses(sort_PairCondition(Pair)))); + NewClauses = list_Nconc(NewClauses,sort_ConditionClauses(Cond)); + sort_ConditionPutClauses(Cond,list_Nil()); + sort_ConditionDelete(Cond); + } + + sort_DeleteOne(varsort); + } + + subst_Free(subst); + *Clauses = list_Nconc(NewClauses,*Clauses); + return TRUE; +} + + +static SOJU sort_ComputeSortInternNoResidues(SORTTHEORY Theory, TERM Term, + CLAUSE Clause, int i, + FLAGSTORE Flags, + PRECEDENCE Precedence) +/********************************************************* + INPUT: A Term, a sort theory representing a set of + clauses, a clause wrt that variable sorts are + computed, where the literal <i> is discarded, + a flag store and a precedence. + The sorts of 'Term's args have to be known. + RETURNS: The sort of 'Term' wrt. the sort theory of the + clause set. Be careful, the Sort-entries of + 'Term' and its subterms are changed. +*******************************************************/ +{ + SORT Sort; + LIST HelpList, Scan, Clauses; + TERM QueryTerm; + + Sort = sort_TopSort(); + Clauses = list_Nil(); + + if (term_IsVariable(Term)) + Sort = sort_VarSort(Theory,term_TopSymbol(Term),Clause,i); + else { + HelpList = st_GetGen(cont_LeftContext(), sort_TheoryIndex(Theory), Term); + for (Scan=HelpList;!list_Empty(Scan);Scan=list_Cdr(Scan)) { + SYMBOL Top; + LITERAL ActLit; + TERM Atom; + CLAUSE ActClause; + + QueryTerm = (TERM)list_First(Scan); + + if (!term_IsVariable(QueryTerm)) { /* Currently also subort declarations are in the index ...*/ + Atom = (TERM)list_First(term_SupertermList(QueryTerm)); + Top = term_TopSymbol(Atom); + ActLit = (LITERAL)list_First(term_SupertermList(Atom)); + ActClause = clause_LiteralOwningClause(ActLit); + if (clause_IsSortTheoryClause(ActClause, Flags, Precedence) && + sort_MatchNoResidues(Theory,QueryTerm,Term, ActClause,&Clauses) && + !sort_ContainsSymbol(Sort,Top)) { + Sort = sort_Intersect(Sort,sort_TheorySortOfSymbol(Theory,Top)); + Clauses = list_Cons(ActClause,Clauses); + } + } + } + list_Delete(HelpList); + } + return (sort_PairCreate(Sort,sort_ConditionCreateNoResidues(Clauses))); +} + + +SOJU sort_ComputeSortNoResidues(SORTTHEORY Theory, TERM Term, CLAUSE Clause, + int i, FLAGSTORE Flags, PRECEDENCE Precedence) +/********************************************************* + INPUT: A Term and an Index representing a set of + clauses, a clause to access + variable-sort-information where the literal <i> + is discarded, a flag store and a precedence. + RETURNS: The sort of 'Term' wrt. the sort theory of the + clause set and the clauses used for this + computation. + Be careful, the Sort-entries of + 'Term' and its subterms are changed, if they + already existed. +*******************************************************/ +{ + int SubtermStack; + SOJU SortPair; + + SortPair = (SOJU)NULL; + SubtermStack = stack_Bottom(); + sharing_PushOnStack(Term); + + + while (!stack_Empty(SubtermStack)){ + Term = stack_PopResult(); + + if (!(SortPair = (SOJU)hash_Get(Term))) { + SortPair = sort_ComputeSortInternNoResidues(Theory,Term,Clause,i, + Flags, Precedence); + /*fputs("\n Computed:",stdout);term_Print(Term); + putchar(':');sort_PairPrint(SortPair);putchar('\n');*/ + hash_Put(Term,SortPair); + } + } + + SortPair = sort_PairCopy(SortPair); + hash_ResetWithValue((void (*)(POINTER)) sort_DeleteSortPair); + + return(SortPair); +} + + +/**************************************************************/ +/* ********************************************************** */ +/* * * */ +/* * Creating and Analyzing Sort Theories * */ +/* * * */ +/* ********************************************************** */ +/**************************************************************/ + + +static BOOL sort_SortTheoryIsTrivial(SORTTHEORY Theory, LIST Clauses) +/********************************************************* + INPUT: A sort theory and a list of clauses that generated the theory. + RETURNS: TRUE iff all considered base sorts are top. +*******************************************************/ +{ + LIST Sorts; + CLAUSE Clause; + int i,n; + CONDITION Cond; + + Sorts = list_Nil(); + + /* fputs("\n\nAnalyzing Theory:", stdout); */ + + while (!list_Empty(Clauses)) { + Clause = (CLAUSE)list_Car(Clauses); + n = clause_Length(Clause); + Clauses = list_Cdr(Clauses); + + /* fputs("\n\t", stdout);clause_Print(Clause); */ + + for (i=clause_FirstConstraintLitIndex(Clause); i<n; i++) + Sorts = list_Cons((POINTER)term_TopSymbol(clause_LiteralAtom( + clause_GetLiteral(Clause,i))), Sorts); + + Sorts = list_PointerDeleteDuplicates(Sorts); + } + + Clauses = Sorts; + while (!list_Empty(Clauses)) { + list_Rplaca(Clauses,sort_TheorySortOfSymbol(Theory,(SYMBOL)list_Car(Clauses))); + Clauses = list_Cdr(Clauses); + } + + n = list_Length(Sorts); + i = 0; + Clauses = Sorts; + + /* printf("\n\t There are %d different sorts.",n); */ + + while (!list_Empty(Clauses)) { + if ((Cond = sort_TheoryIsSubsortOfNoResidues(Theory,sort_TopSort(),list_Car(Clauses)))) { + sort_ConditionDelete(Cond); + i++; + } + sort_DeleteOne(list_Car(Clauses)); + Clauses = list_Cdr(Clauses); + } + + list_Delete(Sorts); + + return (i == n); /* All sorts are trivial */ +} + + +static LIST sort_ApproxPseudoLinear(LIST Constraint, TERM Head, SYMBOL Var) +/************************************************************** + INPUT: A list of constraint literals, the head literal term + and a variable maximal for all variables. + RETURNS: The new list of constraint literals. + EFFECT: The succedent literal is made pseudo-linear. + The function is DESTRUCTIVE. +***************************************************************/ +{ + TERM Atom; + LIST RenVars,Scan1,Scan2,Lits; + SYMBOL OldVar, NewVar; + + RenVars = term_RenamePseudoLinear(Head,Var); + Lits = list_Nil(); + + for (Scan1=RenVars;!list_Empty(Scan1);Scan1=list_Cdr(Scan1)) { + OldVar = (SYMBOL)list_PairFirst(list_Car(Scan1)); + NewVar = (SYMBOL)list_PairSecond(list_Car(Scan1)); + list_PairFree(list_Car(Scan1)); + for (Scan2=Constraint;!list_Empty(Scan2);Scan2=list_Cdr(Scan2)) { + Atom = (TERM)list_Car(Constraint); + if (symbol_Equal(term_TopSymbol(term_FirstArgument(Atom)),OldVar)) + Lits = list_Cons(term_Create(term_TopSymbol(Atom), + list_List(term_Create(NewVar,list_Nil()))), Lits); + } + } + list_Delete(RenVars); + + Lits = list_Nconc(Constraint,Lits); + + return Lits; +} + + +static LIST sort_ApproxHornClauses(CLAUSE Clause, FLAGSTORE Flags, + PRECEDENCE Precedence) +/************************************************************** + INPUT: A clause to make special horn clauses from, a flag + store and a precedence. + RETURNS: The list of clauses according to the rule + ClauseDeletion. + MEMORY: Allocates memory for the clauses and the list. +***************************************************************/ +{ + LIST Result, NewConstraint,NewSuccedent; + CLAUSE NewClause; + LITERAL LitK; + int i,length,j,lc,pli; + +#ifdef CHECK + if (!clause_IsClause(Clause, Flags, Precedence)) { + misc_StartErrorReport(); + misc_ErrorReport("\n In sort_ApproxHornClauses :"); + misc_ErrorReport(" Illegal input. Input not a clause.\n"); + misc_FinishErrorReport(); + } +#endif + + Result = list_Nil(); + + if (clause_HasOnlyVarsInConstraint(Clause, Flags, Precedence) && + clause_HasSortInSuccedent(Clause, Flags, Precedence)) { + length = clause_Length(Clause); + + for (i = clause_FirstSuccedentLitIndex(Clause); i < length; i++) { + LitK = clause_GetLiteral(Clause, i); + + if (symbol_Arity(term_TopSymbol(clause_LiteralSignedAtom(LitK))) == 1) { + pli = i; + NewSuccedent = list_List(term_Copy(clause_LiteralSignedAtom(LitK))); + NewConstraint = list_Nil(); + lc = clause_LastConstraintLitIndex(Clause); + + for (j = clause_FirstLitIndex(); j <= lc; j++) + if (clause_LitsHaveCommonVar(LitK, clause_GetLiteral(Clause, j))) + NewConstraint = list_Cons(term_Copy(clause_LiteralAtom( + clause_GetLiteral(Clause, j))), NewConstraint); + + if (!list_Empty(NewConstraint)) + NewConstraint = sort_ApproxPseudoLinear(NewConstraint, + list_Car(NewSuccedent), + clause_MaxVar(Clause)); + + NewClause = clause_Create(NewConstraint, list_Nil(), NewSuccedent, + Flags, Precedence); + clause_SetSplitLevel(NewClause, 0); + clause_SetFlag(NewClause,WORKEDOFF); + clause_SetFromClauseDeletion(NewClause); + clause_SetParentClauses(NewClause, list_List((POINTER)clause_Number(Clause))); + clause_AddParentLiteral(NewClause, pli); + + list_Delete(NewConstraint); + list_Delete(NewSuccedent); + Result = list_Cons(NewClause, Result); + } + } + } + return(Result); +} + +LIST sort_ApproxMaxDeclClauses(CLAUSE Clause, FLAGSTORE Flags, + PRECEDENCE Precedence) +/************************************************************** + INPUT: A declaration clause to make special horn clauses + from, a flag store and a precedence. + RETURNS: The list of Horn clauses that are pseudo-linear declaration + clauses generated from maximal declarations in <Clause> + MEMORY: Allocates memory for the clauses and the list. +***************************************************************/ +{ + LIST Result, NewConstraint,NewSuccedent; + CLAUSE NewClause; + LITERAL LitK; + int i,length,j,lc,pli; + +#ifdef CHECK + if (!clause_IsClause(Clause, Flags, Precedence) || + !clause_IsDeclarationClause(Clause)) { + misc_StartErrorReport(); + misc_ErrorReport("\n In sort_ApproxMaxDeclClauses :"); + misc_ErrorReport(" Illegal input.\n"); + misc_FinishErrorReport(); + } +#endif + + Result = list_Nil(); + length = clause_Length(Clause); + + for (i = clause_FirstSuccedentLitIndex(Clause); i < length; i++) { + LitK = clause_GetLiteral(Clause, i); + + if (clause_LiteralIsMaximal(LitK) && + symbol_IsBaseSort(term_TopSymbol(clause_LiteralSignedAtom(LitK)))) { + pli = i; + NewSuccedent = list_List(term_Copy(clause_LiteralSignedAtom(LitK))); + NewConstraint = list_Nil(); + lc = clause_LastConstraintLitIndex(Clause); + + for (j = clause_FirstLitIndex(); j <= lc; j++) + if (clause_LitsHaveCommonVar(LitK, clause_GetLiteral(Clause, j))) + NewConstraint = list_Cons(term_Copy(clause_LiteralAtom(clause_GetLiteral(Clause, j))), + NewConstraint); + + if (!list_Empty(NewConstraint)) + NewConstraint = sort_ApproxPseudoLinear(NewConstraint, + list_Car(NewSuccedent), + clause_MaxVar(Clause)); + + NewClause = clause_Create(NewConstraint, list_Nil(), NewSuccedent, + Flags, Precedence); + clause_SetSplitLevel(NewClause, 0); + clause_SetFlag(NewClause,WORKEDOFF); + clause_SetFromClauseDeletion(NewClause); + clause_SetParentClauses(NewClause, list_List(Clause)); /* The clause itself is added! */ + clause_AddParentLiteral(NewClause, pli); + + list_Delete(NewConstraint); + list_Delete(NewSuccedent); + Result = list_Cons(NewClause, Result); + } + } + return(Result); +} + + +static LIST sort_ApproxClauses(LIST Clauses, FLAGSTORE Flags, + PRECEDENCE Precedence) +/************************************************************** + INPUT: A list of top level clauses, a flag store and a + precedence. + RETURNS: A list of approximated clauses from <Clauses> which must + be used for sort deletion. + EFFECT: None. +***************************************************************/ +{ + LIST Result,ApproxClauses; + CLAUSE ActClause; + + Result = list_Nil(); + + while (!list_Empty(Clauses)) { + ActClause = (CLAUSE)list_Car(Clauses); + ApproxClauses = sort_ApproxHornClauses(ActClause, Flags, Precedence); + Result = list_Nconc(ApproxClauses,Result); + Clauses = list_Cdr(Clauses); + } + + return Result; +} + +LIST sort_EliminateSubsumedClauses(LIST Clauses) +/********************************************************* + INPUT: A list of clauses. + RETURNS: <Clauses> without subsumed clauses. +*******************************************************/ +{ + LIST RedundantClauses,Iter,Scan; + BOOL Kept; + + RedundantClauses = list_Nil(); + for (Scan = Clauses; !list_Empty(Scan);Scan=list_Cdr(Scan)) { + Kept = TRUE; + for (Iter = Clauses;!list_Empty(Iter) && Kept; Iter = list_Cdr(Iter)) + if (list_Car(Iter) != list_Car(Scan) && + !list_PointerMember(RedundantClauses,list_Car(Iter)) && + subs_Subsumes(list_Car(Iter),list_Car(Scan),subs_NoException(),subs_NoException())) { + Kept = FALSE; + RedundantClauses = list_Cons(list_Car(Scan),RedundantClauses); + } + } + Clauses = list_NPointerDifference(Clauses,RedundantClauses); + clause_DeleteClauseList(RedundantClauses); + return Clauses; +} + + +SORTTHEORY sort_ApproxStaticSortTheory(LIST Clauses, FLAGSTORE Flags, + PRECEDENCE Precedence) +/********************************************************* + INPUT: A list of clauses, a flag store and a + precedence. + RETURNS: NULL if the approximated sort theory is trivial, + the approximated sort theory otherwise. +*******************************************************/ +{ + LIST Scan,ApproxClauses; + CLAUSE Clause; + SORTTHEORY Result; + + Result = sort_TheoryCreate(); + ApproxClauses = sort_ApproxClauses(Clauses, Flags, Precedence); + ApproxClauses = sort_EliminateSubsumedClauses(ApproxClauses); + + /*fputs("\n\n Approx Sort Theory:", stdout); + for (Scan = ApproxClauses; !list_Empty(Scan);Scan=list_Cdr(Scan)) { + fputs("\n\t",stdout); clause_Print(list_Car(Scan)); + }*/ + + for (Scan = ApproxClauses; !list_Empty(Scan);Scan=list_Cdr(Scan)) { + Clause = (CLAUSE)list_Car(Scan); + sort_TheoryInsertClause(Result,Clause,Clause, + clause_GetLiteral(Clause,clause_FirstSuccedentLitIndex(Clause))); + } + + if (sort_SortTheoryIsTrivial(Result,ApproxClauses)) { + sort_TheoryDelete(Result); + Result = (SORTTHEORY)NULL; + } + + + if (flag_GetFlagValue(Flags, flag_DOCSST)) { + fputs("\n\n Approx Sort Theory:", stdout); + if (Result) { + puts("\n"); + sort_TheoryPrint(Result); + } + else + fputs(" trivial.", stdout); + } + list_Delete(ApproxClauses); + + return Result; +} + + +SORTTHEORY sort_ApproxDynamicSortTheory(LIST Clauses) +/********************************************************* + INPUT: A list of clauses. + RETURNS: The approximated dynamic sort theory for <Clauses> + Only maximal declarations are considered. +*******************************************************/ +{ + return (SORTTHEORY)NULL; +} + +STR sort_AnalyzeSortStructure(LIST Clauses, FLAGSTORE Flags, + PRECEDENCE Precedence) +/********************************************************* + INPUT: A list of clauses, a flag store and a + precedence. + RETURNS: SORTEQMANY if all positive equations are many + sorted. + SORTEQDEC if all positive equations are sort + decreasing. + SORTEQNONE otherwise. + For the check, the static sort theory is + considered. +*******************************************************/ +{ + SORTTHEORY Theory; + LIST Scan; + CLAUSE Clause,Copy; + int i,l; + TERM Atom,Left,Right; + SOJU SojuLeft,SojuRight; + CONDITION Cond; + BOOL ManySorted, Decreasing; + + Theory = sort_TheoryCreate(); + ManySorted = TRUE; + Decreasing = TRUE; + + for (Scan=Clauses;!list_Empty(Scan);Scan=list_Cdr(Scan)) { + /* Extract static sort theory */ + Clause = (CLAUSE)list_Car(Scan); + if (clause_IsPotentialSortTheoryClause(Clause, Flags, Precedence)) { + Copy = clause_Copy(Clause); + symbol_AddProperty(term_TopSymbol(clause_GetLiteralTerm(Copy, + clause_FirstSuccedentLitIndex(Copy))), + DECLSORT); + list_Delete(clause_ParentClauses(Copy)); + clause_SetParentClauses(Copy,list_Nil()); + list_Delete(clause_ParentLiterals(Copy)); + clause_SetParentLiterals(Copy,list_Nil()); + clause_SetNumber(Copy,clause_Number(Clause)); + clause_SetSortConstraint(Copy,FALSE, Flags, Precedence); + sort_TheoryInsertClause(Theory,Clause,Copy, + clause_GetLiteral(Copy,clause_FirstSuccedentLitIndex(Copy))); + } + } + + /*putchar('\n'); + sort_TheoryPrint(Theory); + putchar('\n');*/ + + for (Scan=Clauses;!list_Empty(Scan) && Decreasing;Scan=list_Cdr(Scan)) { + Clause = (CLAUSE)list_Car(Scan); + l = clause_Length(Clause); + for (i=clause_FirstSuccedentLitIndex(Clause);i<l && Decreasing;i++) { + Atom = clause_GetLiteralTerm(Clause,i); + if (fol_IsEquality(Atom)) { + Left = term_FirstArgument(Atom); + Right = term_SecondArgument(Atom); + SojuLeft = sort_ComputeSortNoResidues(Theory, Left, Clause, i, + Flags, Precedence); + SojuRight = sort_ComputeSortNoResidues(Theory, Right,Clause, i, + Flags, Precedence); + if (sort_IsTopSort(sort_PairSort(SojuRight)) || sort_IsTopSort(sort_PairSort(SojuLeft))) { + /*fputs("\nNon decreasing equation ",stdout); term_PrintPrefix(Atom); + fputs(" in clause: ",stdout);clause_Print(Clause);putchar('\n');*/ + ManySorted = FALSE; + Decreasing = FALSE; + } + else { + if (!sort_Eq(sort_PairSort(SojuRight), sort_PairSort(SojuLeft))) { + ManySorted = FALSE; + Cond = sort_TheoryIsSubsortOfNoResidues(Theory, sort_PairSort(SojuRight), + sort_PairSort(SojuLeft)); + if (Cond && !clause_LiteralIsOrientedEquality(clause_GetLiteral(Clause,i))) { + sort_ConditionDelete(Cond); + Cond = sort_TheoryIsSubsortOfNoResidues(Theory, sort_PairSort(SojuLeft), + sort_PairSort(SojuRight)); + } + if (Cond) + sort_ConditionDelete(Cond); + else { + /*fputs("\nNon decreasing equation ",stdout); term_PrintPrefix(Atom); + fputs(" in clause: ",stdout);clause_Print(Clause);putchar('\n');*/ + Decreasing = FALSE; + } + } + } + sort_PairDelete(SojuLeft); + sort_PairDelete(SojuRight); + } + } + } + sort_TheoryDelete(Theory); + if (ManySorted) + return SORTEQMANY; + if (Decreasing) + return SORTEQDECR; + + return SORTEQNONE; +} + |