int Semantic::schaum(String &andor, Array<List<Semantic * > > &asubc, Array<List<Semantic * > > &asubx) const { // check the type of record if (isPredicate()) { return(none(andor, asubc, asubx, "schaum", "%p0")); } else if (isExpression()) { switch (type) { case And: return(schaum_and(andor, asubc, asubx, "schaum")); case Or: return(schaum_or(andor, asubc, asubx, "schaum")); case Conditional: return(schaum_conditional(andor, asubc, asubx, "schaum")); case Biconditional: return(schaum_biconditional(andor, asubc, asubx, "schaum")); default: return(none(andor, asubc, asubx, "schaum", "%p0")); } } // all done ERRORD("schaum called with wrong type.", type, EINVAL); return(NOTOK); }
// split problems int Semantic::split(const String &rtype, String &andor, Array<List<Semantic * > > &asubc, Array<List<Semantic * > > &asubx) const { // check if we reducing the correct types if (!isExpression() && !isPredicate()) return(NOTOK); // determine reducing strategy if (rtype == String("bledsoe")) { return(bledsoe(andor, asubc, asubx)); } else if (rtype == String("schaum")) { return(schaum(andor, asubc, asubx)); } else if (rtype == String("cp")) { return(cp(andor, asubc, asubx)); } else if (rtype == String("none")) { return(none(andor, asubc, asubx, "none", "%p0")); } else { ERRORD("invalid reduction type", rtype, EINVAL); return(NOTOK); } }
int Semantic::cp(String &andor, Array<List<Semantic * > > &asubc, Array<List<Semantic * > > &asubx) const { // check the type of record if (isPredicate()) { return(none(andor, asubc, asubx, "cp", "%p0")); } else if (isExpression()) { switch (type) { case Conditional: return(cp_conditional(andor, asubc, asubx, "cp")); case Biconditional: return(cp_biconditional(andor, asubc, asubx, "cp")); default: return(none(andor, asubc, asubx, "cp", "%p0")); } } // all done ERRORD("contrapositive called with wrong type.", type, EINVAL); return(NOTOK); }
// remove existential quantifier by using skolem functions. all skolem // functions must be unique. remember that the skolem function is dependent // on any universal variables that are in scope. // int Semantic::skolemize(List<Symbol> &localscope) { // check if expression or predicate if (isExpression()) { // get expression Expression *pe = (Expression *)prep; // what type is it if (pe->type == Expression::Universal) { // store universal variable localscope.insertAtEnd(Symbol(pe->name, Symbol::UniversalVariable)); // follow right leg, left leg is null MustBeTrue(pe->left == NULL && pe->right != NULL); if (pe->right->skolemize(localscope) != OK) { ERROR("skolemize failed.", EINVAL); return(NOTOK); } // remove universal variable Symbol tmp; localscope.removeAtEnd(tmp); } else if (pe->type == Expression::Existential) { // store existential variable String uname = uniqueName(String("_SK")); localscope.insertAtEnd(Symbol(pe->name, uname, Symbol::ExistentialVariable)); if (updateVariableNames(pe->name, uname) != OK) { ERROR("update variable names failed.", EINVAL); return(NOTOK); } // follow right leg, left leg is null MustBeTrue(pe->left == NULL && pe->right != NULL); if (pe->right->skolemize(localscope) != OK) { ERROR("skolemize failed.", EINVAL); return(NOTOK); } // remove existential variable Symbol tmp; localscope.removeAtEnd(tmp); } else { // follow down other expression operators if (pe->left != NULL && pe->left->skolemize(localscope) != OK) { ERROR("skolemize failed.", EINVAL); return(NOTOK); } if (pe->right != NULL && pe->right->skolemize(localscope) != OK) { ERROR("skolemize failed.", EINVAL); return(NOTOK); } } } else if (isPredicate()) { // get predicate Predicate *pp = (Predicate *)prep; // check for functions if ((pp->type == Predicate::Function) || (pp->type == Predicate::Equal)) { // cycle thru arguments ListIterator<Semantic * > pargsIter(*pp->pargs); for ( ; !pargsIter.done(); pargsIter++) { Semantic *parg = pargsIter(); if (parg != NULL && parg->skolemize(localscope) != OK) { ERROR("skolemize failed.", EINVAL); return(NOTOK); } } } } else if (isTerm()) { // check type of argument Term *pa = (Term *)prep; switch (pa->type) { case Term::Variable: { // check if an existential variable Symbol qvarsym(pa->name); if(localscope.retrieve(qvarsym) != OK) break; if (qvarsym.getType() != Symbol::ExistentialVariable) break; // we have an existential variable String skolemName(qvarsym.getUniqueName()); // need to replace this variable with a // skolem function which is dependent on all // universal variables in scope at this time. // List<Semantic * > *pargs = new List<Semantic * >; MustBeTrue(pargs != NULL); ListIterator<Symbol> scopeIter(localscope); int nargs; for (nargs = 0; !scopeIter.done(); scopeIter++) { // get symbol Symbol uvar = scopeIter(); // check if we found the current // symbol. this marks the end of // dependent variables for the // skolem function. all other // existential variables are skipped. // if (uvar.getType() == Symbol::ExistentialVariable) { if (uvar == Symbol(pa->name)) break; else continue; } // we have a universal variable in // scope // Semantic *parg = new Semantic( Term::Variable, uvar.getName()); MustBeTrue(parg != NULL); pargs->insertAtEnd(parg); nargs++; } if (nargs == 0) { // skolem constant pa->type = Term::Constant; pa->name = skolemName; pa->pargs = NULL; pa->argnum = 0; // delete unused argument list delete pargs; } else { // skolem function pa->type = Term::Function; pa->name = skolemName; pa->pargs = pargs; pa->argnum = nargs; } break; } case Term::Function: { // we have a function, scan its arguments ListIterator<Semantic *> pargsIter(*pa->pargs); for ( ; !pargsIter.done(); pargsIter++) { Semantic *parg = pargsIter(); if (parg != NULL && parg->skolemize(localscope) != OK) { ERROR("skolemize failed.", EINVAL); return(NOTOK); } } break; } } } else { MustBeTrue(0); } // all done return(OK); }
// rename all variable names to unique names. int Semantic::renameVariables(List<Symbol> &localscope) { // check of predicate or expression if (isExpression()) { // get expression record Expression *pe = (Expression *)prep; // check if we have quantifier int popscope = 0; if (pe->type == Expression::Universal) { // we have a quantifier, rename variable popscope = 1; String uname = uniqueName(String("_V")); localscope.insertAtFront( Symbol(pe->name, uname, Symbol::UniversalVariable)); // change name in semantic record if (updateVariableNames(pe->name, uname) != OK) { ERROR("update variable names failed.", EINVAL); return(NOTOK); } pe->name = uname; } else if (pe->type == Expression::Existential) { // we have a quantifier, rename variable popscope = 1; String uname = uniqueName(String("_V")); localscope.insertAtFront( Symbol(pe->name, uname, Symbol::ExistentialVariable)); // change name in semantic record if (updateVariableNames(pe->name, uname) != OK) { ERROR("update variable names failed.", EINVAL); return(NOTOK); } pe->name = uname; } // follow left and right branches if (pe->left != NULL && pe->left->renameVariables(localscope) != OK) { ERROR("renameVariables failed.", EINVAL); return(NOTOK); } if (pe->right != NULL && pe->right->renameVariables(localscope) != OK) { ERROR("renameVariables failed.", EINVAL); return(NOTOK); } // pop scope variable if required if (popscope) { Symbol tmp; MustBeTrue(localscope.removeAtFront(tmp) == OK); } } else if (isPredicate()) { // get predicate record Predicate *pp = (Predicate *)prep; // check if a function if ((pp->type == Predicate::Function) || (pp->type == Predicate::Equal)) { // we have a function, scan argument list ListIterator<Semantic *> pargsIter(*pp->pargs); for ( ; !pargsIter.done(); pargsIter++) { Semantic *parg = pargsIter(); if (parg != NULL && parg->renameVariables(localscope) != OK) { ERROR("renameVariables failed.", EINVAL); return(NOTOK); } } } } else if (isTerm()) { // check if a variable, function or anything else Term *pa = (Term *)prep; if (pa->type == Term::Variable) { // find variable in scope Symbol usym(pa->name); if (localscope.retrieve(usym) == OK) { pa->name = usym.getUniqueName(); MustBeTrue(pa->name != String("")); } } else if (pa->type == Term::Function) { // we have a function, scan argument list ListIterator<Semantic *> pargsIter(*pa->pargs); for ( ; !pargsIter.done(); pargsIter++) { Semantic *parg = pargsIter(); if (parg != NULL && parg->renameVariables(localscope) != OK) { ERROR("renameVariables failed.", EINVAL); return(NOTOK); } } } } else { MustBeTrue(0); } // all done return(OK); }
const Predicate& Value::predicate() const { assert(isPredicate()); return *(impl_->predicate); }