/*----------------------------------------------------------------------- File : ccl_splitting.c Author: Stephan Schulz Contents Implements functions for destructive splitting of clauses with at least two non-propositional variable disjoint subsets of literals. Copyright 1998, 1999 by the author. This code is released under the GNU General Public Licence and the GNU Lesser General Public License. See the file COPYING in the main E directory for details.. Run "eprover -h" for contact information. Changes <1> Wed Apr 18 18:24:18 MET DST 2001 New -----------------------------------------------------------------------*/ #include "ccl_splitting.h" /*---------------------------------------------------------------------*/ /* Global Variables */ /*---------------------------------------------------------------------*/ /*---------------------------------------------------------------------*/ /* Forward Declarations */ /*---------------------------------------------------------------------*/ /*---------------------------------------------------------------------*/ /* Internal Functions */ /*---------------------------------------------------------------------*/ /*----------------------------------------------------------------------- // // Function: initialize_lit_table() // // Initialize the literal table. // // Global Variables: // // Side Effects : // /----------------------------------------------------------------------*/ static void initialize_lit_table(LitSplitDesc_p lit_table,Clause_p clause, SplitType how, TermProperties var_filter) { int i, lit_no = ClauseLiteralNumber(clause); Eqn_p handle = clause->literals; for(i=0; inext; } } /*----------------------------------------------------------------------- // // Function: find_free_literal() // // Find the first entry in lit_table that corresponds to a literal // not yet assigned to any clause part and return its index. If none // exists, return -1. // // Global Variables: - // // Side Effects : - // /----------------------------------------------------------------------*/ static int find_free_literal(LitSplitDesc_p lit_table, int lit_no) { int res = -1,i; for(i=0; ichildren); assert(!clause->set); assert(set); props = ClauseGiveProps(clause, CPTypeMask|CPIsSOS); lit_no = ClauseLiteralNumber(clause); if(lit_no<=1 || ClauseHasSplitLiteral(clause)) { return 0; } bank = clause->literals->bank; size = lit_no*sizeof(LitSplitDescCell); lit_table = SizeMalloc(size); split_var_no = PStackGetSP(split_vars); if(!split_var_no) { initialize_lit_table(lit_table, clause, how, TPIgnoreProps); } else { PStackPointer sp; Term_p var; ClauseTermSetProp(clause, TPCheckFlag); for(sp=0; sp1) { Clause_p parent1 = clause->parent1; Clause_p parent2 = clause->parent2; PStack_p def_stack = PStackAlloc(); ClauseDetachParents(clause); /* Build split clauses from original literals */ join = NULL; clause->literals = NULL; /* Literals are recycled in new clauses, clause skeleton is deallocated below */ for(i=1; i<=part; i++) { if(split_var_no) { /* Get new predicate code */ new_pred = SigGetNewPredicateCode(bank->sig, split_var_no); SigSetFuncProp(bank->sig, new_pred, FPClSplitDef); /* Create definition clause (for maintaining completeness) */ handle = GenDefLit(bank, new_pred, true, split_vars); assert(!handle->next); for(j=0; jnext = handle; handle = tmp; } } new_clause = ClauseAlloc(handle); assert(new_clause); def_id = new_clause->ident; assert(def_id); assert(new_pred); } else { /* Create definition clause (for maintaining completeness) */ handle = NULL; for(j=0; jnext = handle; handle = tmp; } } new_clause = GetDefinition(store, handle, &new_pred, fresh_defs, &def_id); assert(def_id); assert(new_pred); } PStackPushInt(def_stack, def_id); if(new_clause) { /* Fix clause properties */ new_clause->properties = props; /* Note: Potentially recycled definitions have no real parents, as they are conceptually introduced ad-hoc and can be reused for many other clauses. */ if(parent1 && fresh_defs) { new_clause->parent1 = parent1; ClauseRegisterChild(parent1, new_clause); } if(parent2 && fresh_defs) { new_clause->parent2 = parent2; ClauseRegisterChild(parent2, new_clause); } /* Insert result clause */ ClauseSetInsert(set, new_clause); /* Document creation -> Now done in ccl_def_handling.c*/ /* DocClauseCreationDefault(new_clause, inf_split, clause, NULL); */ } /* Extend remainder clause (after application of definition) */ tmp = GenDefLit(bank, new_pred, false, split_vars); tmp->next = join; join = tmp; } new_clause = ClauseAlloc(join); new_clause->properties = props; if(parent1) { new_clause->parent1 = parent1; ClauseRegisterChild(parent1, new_clause); } if(parent2) { new_clause->parent2 = parent2; ClauseRegisterChild(parent2, new_clause); } ClauseSetInsert(set, new_clause); /* DocClauseCreationDefault(new_clause, inf_split, clause, NULL); */ DocClauseApplyDefsDefault(new_clause, clause, def_stack); ClauseFree(clause); /* We still retain the literals in the split clauses! */ res = part+1; PStackFree(def_stack); } for(i=0; i=0) { PStackPushInt(permute_stack, tmp); tmp++; i--; } return true; } i++; } return false; } /*---------------------------------------------------------------------*/ /* Exported Functions */ /*---------------------------------------------------------------------*/ /*----------------------------------------------------------------------- // // Function: ClauseHasSplitLiteral() // // Return true if a literal in the clause is a split literal. // // Global Variables: - // // Side Effects : - // /----------------------------------------------------------------------*/ bool ClauseHasSplitLiteral(Clause_p clause) { Eqn_p handle; for(handle = clause->literals; handle; handle = handle->next) { if(EqnQueryProp(handle, EPIsSplitLit)) { return true; } } return false; } /*----------------------------------------------------------------------- // // Function: ClauseSplit() // // Try to split clause into different clauses according to the // inference rule below. If successful, // deposit split clauses into set and return number of clauses // created. Otherwise return 0. // // L1 v L2 v L3 ... // ---------------------------------------------------- // T1 v T2 v T3 ...., ~T1 v L1, ~T2 v L2, ~T3 v L3, ... // // if the Li are variable-disjoint subsets of the clause and the Ti // are _new_ propositional variables. // // Global Variables: - // // Side Effects : Memory allocation, if successful, destroys // clause! // /----------------------------------------------------------------------*/ int ClauseSplit(DefStore_p store, Clause_p clause, ClauseSet_p set, SplitType how, bool fresh_defs) { int res ; PStack_p dummy = PStackAlloc(); res = clause_split_general(store, clause, set, how, fresh_defs, dummy); PStackFree(dummy); return res; } /*----------------------------------------------------------------------- // // Function: ClauseSplitGeneral() // // Wrapper for clause_split_general(). Tries tries different // variable subsets (partially ordered by cardinality) to find a // subset that splits the clause. Only used for eground, so I skimp // on options. // // Global Variables: - // // Side Effects : Memory allocation, if successful, destroys // clause! // /----------------------------------------------------------------------*/ int ClauseSplitGeneral(DefStore_p store, bool fresh_defs, Clause_p clause, ClauseSet_p set, long tries) { int res, var_no, set_size; PStackPointer i; PStack_p vars, split_vars, permute_stack; PTree_p vars_tree = NULL; res = ClauseSplit(store, clause, set, SplitGroundOne, fresh_defs); if(res) { return res; } var_no = ClauseCollectVariables(clause, &vars_tree); if(var_no<=2) /* Non-ground splitting is useless here */ { PTreeFree(vars_tree); return 0; } vars = PStackAlloc(); split_vars = PStackAlloc(); permute_stack = PStackAlloc(); PTreeToPStack(vars, vars_tree); PTreeFree(vars_tree); set_size = 1; initialize_permute_stack(permute_stack, set_size); while(tries) { PStackReset(split_vars); for(i=0; i