// checks that the atom has the form f(x) = t[x], // where f is a function symbol and t[x] is a term of x not containing f // 09/05/2002, Manchester bool Atom::isDefinition (Term& lhs, Term& rhs) const { TRACER ( "Atom::isDefinition" ); if ( ! isEquality() ) { return false; } // the atom is an equality Term l (args().head()); Term r (args().second()); if ( l.isvar() || r.isvar() ) { return false; } // l=r, both l and r are non-variables if ( r.defines(l) ) { lhs = l; rhs = r; return true; } if ( l.defines(r) ) { rhs = l; lhs = r; return true; } return false; } // Term* Atom::isDefinition
// comparison of two atoms, needed to normalize // 28/08/2002 Torrevieja Compare Atom::compare ( Atom a ) const { // equality is less than nonequality if ( isEquality() ) { if ( ! a.isEquality() ) return LESS; } else if ( a.isEquality() ) { return GREATER; } // now either both are equality or both are not equality switch ( functor()->compare(a.functor()) ) { case LESS: return LESS; case EQUAL: return args().compare(a.args()); case GREATER: return GREATER; #if DEBUG_PREPRO default: ASS(false); #endif } } // Atom::compare
// return true if the atom is t = t // 29/04/2002 Manchester bool Atom::isTautology () const { TRACER("Atom::isTautology"); if ( ! isEquality() ) return false; return args().head().equal(args().second()); } // Atom::isTautology
bool Logic::isAtom(PTRef r) const { Pterm& t = term_store[r]; if (sym_store[t.symb()].rsort() == getSort_bool()) { if (t.size() == 0) return true; if (t.symb() == getSym_not() ) return false; // At this point all arguments of equivalence have the same sort. Check only the first if (isEquality(t.symb()) && (sym_store[term_store[t[0]].symb()].rsort() != getSort_bool())) return true; if (isUP(r)) return true; } return false; }
// true if this is t1 = t2 and a is t2 = t1 // 29/04/2002, Manchester // 28/08/2002 Torrevieja changed bool Atom::swap (Atom a) const { TRACER("Atom::swap"); if ( ! isEquality() ) return false; if ( ! a.isEquality() ) return false; return args().head().equal (a.args().second()) && a.args().head().equal(args().second()); } // Atom::swap
// A term is literal if its sort is Bool and // (i) number of arguments is 0 // (ii) its symbol is sym_NOT and argument is a literal (nested nots // create literals?) // (iii) it is an atom stating an equivalence of non-boolean terms (terms must be purified at this point) bool Logic::isLit(PTRef tr) const { Pterm& t = getPterm(tr); if (sym_store[t.symb()].rsort() == getSort_bool()) { if (t.size() == 0) return true; if (t.symb() == getSym_not() ) return isLit(t[0]); // At this point all arguments of equivalence have the same sort. Check only the first if (isEquality(tr) && (sym_store[getPterm(t[0]).symb()].rsort() != getSort_bool())) return true; if (isUP(tr)) return true; } return false; }
// Uninterpreted predicate p : U U* -> Bool bool Logic::isUP(PTRef ptr) const { Pterm& t = term_store[ptr]; SymRef sr = t.symb(); // Should this really be an uninterpreted predicate? // At least it falsely identifies (= true false) as an uninterpreted // predicate without the extra condition if (isEquality(sr) || isDisequality(sr)) { if (isBooleanOperator(sr)) return false; else return true; } Symbol& sym = sym_store[sr]; if (sym.nargs() == 0) return false; if (sym.rsort() != getSort_bool()) return false; if (isBooleanOperator(sr)) return false; return true; }
// normalize the atom // 29/08/2002 Torrevieja, changed void Atom::normalize () { if ( ! isEquality() ) { return; } // equality TermList as (args()); Term l (as.head()); Term r (as.second()); if (l.compare(r) == LESS) { TermList newAs (r, TermList (l)); Atom newAtom (functor(), newAs); *this = newAtom; } } // Atom::normalize
// Adds the uninterpreted predicate if ptr is an uninterpreted predicate. // Returns reference to corresponding equality term or PTRef_Undef. Creates // the eq term if it does not exist. // If the term is an equality (disequality), it must be an equality // (disequality) over terms with non-boolean return type. Those must be then // returned as is. PTRef Logic::lookupUPEq(PTRef ptr) { assert(isUP(ptr)); // already seen if (UP_map.contains(ptr)) return UP_map[ptr]; // already an equality Pterm& t = term_store[ptr]; if (isEquality(t.symb()) | isDisequality(t.symb())) return ptr; // Create a new equality // Symbol& sym = sym_store[t.symb()]; vec<PTRef> args; args.push(ptr); args.push(getTerm_true()); return mkEq(args); // return resolveTerm(tk_equals, args); }
// // Sort a term if it commutes. // The following simplifications implemented // (should be refactored to separate methods?): // - `and': // - drop constant true terms // - convert an empty `and' to the constant term `true' // - convert an `and' containing `false' to a replicate `false' // - `or': // - drop constant false terms // - convert an empty `or' to a replicate `false' term // - convert an `or' containing `true' to a replicate `true' // // void Logic::simplify(SymRef& s, vec<PTRef>& args) { // First sort it #ifdef SORT_BOOLEANS if (sym_store[s].commutes()) #else if (sym_store[s].commutes() && !isAnd(s) && !isOr(s)) #endif sort(args, LessThan_PTRef()); if (!isBooleanOperator(s) && !isEquality(s)) return; int dropped_args = 0; bool replace = false; if (s == getSym_and()) { int i, j; PTRef p = PTRef_Undef; for (i = j = 0; i < args.size(); i++) { if (args[i] == getTerm_false()) { args.clear(); s = getSym_false(); #ifdef SIMPLIFY_DEBUG cerr << "and -> false" << endl; #endif return; } else if (args[i] != getTerm_true() && args[i] != p) { args[j++] = p = args[i]; } else { #ifdef SIMPLIFY_DEBUG cerr << "and -> drop" << endl; #endif } } dropped_args = i-j; if (dropped_args == args.size()) { s = getSym_true(); args.clear(); #ifdef SIMPLIFY_DEBUG cerr << "and -> true" << endl; #endif return; } else if (dropped_args == args.size() - 1) replace = true; else if (dropped_args > 0) args.shrink(dropped_args); } if (s == getSym_or()) { int i, j; PTRef p = PTRef_Undef; for (i = j = 0; i < args.size(); i++) { if (args[i] == getTerm_true()) { args.clear(); s = getSym_true(); #ifdef SIMPLIFY_DEBUG cerr << "or -> true" << endl; #endif return; } else if (args[i] != getTerm_false() && args[i] != p) { args[j++] = p = args[i]; } else { #ifdef SIMPLIFY_DEBUG cerr << "or -> drop" << endl; #endif } } dropped_args = i-j; if (dropped_args == args.size()) { s = getSym_false(); args.clear(); #ifdef SIMPLIFY_DEBUG cerr << "or -> false" << endl; #endif return; } else if (dropped_args == args.size() - 1) replace = true; else if (dropped_args > 0) args.shrink(dropped_args); } if (isEquality(s)) { assert(args.size() == 2); if (isBooleanOperator(s) && (args[0] == getTerm_true())) { Pterm& t = getPterm(args[1]); s = t.symb(); args.clear(); for (int i = 0; i < t.size(); i++) args.push(t[i]); #ifdef SIMPLIFY_DEBUG cerr << "eq -> second" << endl; #endif return; } else if (isBooleanOperator(s) && (args[0] == getTerm_false())) { PTRef old = args[1]; PTRef tr = mkNot(args[1]); Pterm& t = getPterm(tr); s = t.symb(); args.clear(); args.push(old); #ifdef SIMPLIFY_DEBUG cerr << "eq -> not second" << endl; #endif return; } else if (isBooleanOperator(s) && (args[1] == getTerm_true())) { args.clear(); Pterm& t = getPterm(args[0]); s = t.symb(); args.clear(); for (int i = 0; i < t.size(); i++) args.push(t[i]); #ifdef SIMPLIFY_DEBUG cerr << "eq -> first" << endl; #endif return; } else if (isBooleanOperator(s) && (args[1] == getTerm_false())) { PTRef old = args[0]; PTRef tr = mkNot(args[0]); Pterm& t = getPterm(tr); s = t.symb(); args.clear(); args.push(old); #ifdef SIMPLIFY_DEBUG cerr << "eq -> not first"<< endl; #endif return; } else if (args[0] == args[1]) { args.clear(); s = getSym_true(); #ifdef SIMPLIFY_DEBUG cerr << "eq -> true" << endl; #endif return; } else if (isBooleanOperator(s) && (args[0] == mkNot(args[1]))) { args.clear(); s = getSym_false(); #ifdef SIMPLIFY_DEBUG cerr << "eq -> false" << endl; #endif return; } } if (isNot(s)) { if (isTrue(args[0])) { args.clear(); s = getSym_false(); #ifdef SIMPLIFY_DEBUG cerr << "not -> false" << endl; #endif return; } if (isFalse(args[0])) { args.clear(); s = getSym_true(); #ifdef SIMPLIFY_DEBUG cerr << "not -> true" << endl; #endif return; } } // Others, to be implemented: // - distinct // - implies // - xor // - ite if (replace) { // Return whatever is the sole argument Pterm& t = getPterm(args[0]); s = t.symb(); args.clear(); for (int i = 0; i < t.size(); i++) args.push(t[i]); #ifdef SIMPLIFY_DEBUG cerr << " replace" << endl; #endif } }