uf_theorem_producer.cpp

Go to the documentation of this file.
00001 /*****************************************************************************/
00002 /*!
00003  *\file uf_theorem_producer.cpp
00004  *\brief TRUSTED implementation of uninterpreted function/predicate rules
00005  *
00006  * Author: Clark Barrett
00007  *
00008  * Created: Tue Aug 31 23:20:27 2004
00009  *
00010  * <hr>
00011  * Copyright (C) 2003 by the Board of Trustees of Leland Stanford
00012  * Junior University and by New York University. 
00013  *
00014  * License to use, copy, modify, sell and/or distribute this software
00015  * and its documentation for any purpose is hereby granted without
00016  * royalty, subject to the terms and conditions defined in the \ref
00017  * LICENSE file provided with this distribution.  In particular:
00018  *
00019  * - The above copyright notice and this permission notice must appear
00020  * in all copies of the software and related documentation.
00021  *
00022  * - THE SOFTWARE IS PROVIDED "AS-IS", WITHOUT ANY WARRANTIES,
00023  * EXPRESSED OR IMPLIED.  USE IT AT YOUR OWN RISK.
00024  * 
00025  * <hr>
00026  * 
00027  */
00028 /*****************************************************************************/
00029 
00030 
00031 // This code is trusted
00032 #define _CVCL_TRUSTED_
00033 
00034 
00035 #include "uf_theorem_producer.h"
00036 #include "theory_uf.h"
00037 #include "theory_core.h"
00038 
00039 
00040 using namespace std;
00041 using namespace CVCL;
00042 
00043 
00044 ////////////////////////////////////////////////////////////////////
00045 // TheoryUF: trusted method for creating UFTheoremProducer
00046 ////////////////////////////////////////////////////////////////////
00047 
00048 
00049 UFProofRules* TheoryUF::createProofRules() {
00050   return new UFTheoremProducer(theoryCore()->getTM(), this);
00051 }
00052   
00053 
00054 ////////////////////////////////////////////////////////////////////
00055 // Proof rules
00056 ////////////////////////////////////////////////////////////////////
00057 
00058 
00059 #define CLASS_NAME "CVCL::UFTheoremProducer"
00060 
00061 
00062 Theorem UFTheoremProducer::relToClosure(const Theorem& rel)
00063 {
00064   const Expr& relExpr = rel.getExpr();
00065 
00066   if(CHECK_PROOFS)
00067     CHECK_SOUND(relExpr.isApply() && relExpr.arity() == 2,
00068                 CLASS_NAME
00069                 "theorem is not a relation or has wrong arity:\n"
00070                 + rel.getExpr().toString());
00071 
00072   Proof pf;
00073   Assumptions a;
00074 
00075   if (withAssumptions()) a = rel.getAssumptions().copy();
00076   if(withProof()) {
00077     pf = newPf("rel_closure", rel.getProof());
00078   }
00079 
00080   const string& name = relExpr.getOp().getExpr().getName();
00081   Expr tc = d_theoryUF->transClosureExpr(name, relExpr[0], relExpr[1]);
00082 
00083   return newTheorem(tc, a, pf);
00084 }
00085 
00086 
00087 Theorem UFTheoremProducer::relTrans(const Theorem& t1, const Theorem& t2)
00088 {
00089   const Expr& e1 = t1.getExpr();
00090   const Expr& e2 = t2.getExpr();
00091 
00092   if (CHECK_PROOFS) {
00093     CHECK_SOUND(e1.getOpKind() == TRANS_CLOSURE &&
00094                 e1.arity() == 2,
00095                 (CLASS_NAME
00096                  "theorem is not a proper trans_closure expr:\n"
00097                  + e1.toString()).c_str());
00098     CHECK_SOUND(e2.getOpKind() == TRANS_CLOSURE &&
00099                 e2.arity() == 2,
00100                 (CLASS_NAME
00101                  "theorem is not a proper trans_closure expr:\n"
00102                  + e2.toString()).c_str());
00103   }
00104 
00105   if (CHECK_PROOFS) {
00106     CHECK_SOUND(e1.getOpExpr().getName() == e2.getOpExpr().getName() &&
00107                 e1[1] == e2[0],
00108                 (CLASS_NAME
00109                  "Expr's don't match:\n"
00110                  + e1.toString() + " and " + e2.toString()).c_str());
00111   }
00112 
00113   Proof pf;
00114   Assumptions a;
00115 
00116   if (withAssumptions())
00117     a = merge(t1, t2);
00118   if(withProof()) {
00119     vector<Proof> pfs;
00120     pfs.push_back(t1.getProof());
00121     pfs.push_back(t2.getProof());
00122     pf = newPf("rel_trans", pfs);
00123   }
00124   return newTheorem(Expr(e1.getOp(), e1[0], e2[1]), a, pf);
00125 }
00126 
00127 
00128 Theorem UFTheoremProducer::applyLambda(const Expr& e) {
00129   if(CHECK_PROOFS) {
00130     CHECK_SOUND(e.isApply() && e.getOpKind() == LAMBDA,
00131                 "applyLambda("+e.toString()
00132                 +"):\n\n  expression is not an APPLY");
00133   }
00134   Expr lambda(e.getOpExpr());
00135   // Expand the CONSTDEF and LETDECL
00136 //   while(lambda.getKind() == CONSTDEF || lambda.getKind() == LETDECL)
00137 //     lambda = lambda[1];
00138 
00139   if (CHECK_PROOFS) {
00140     CHECK_SOUND(lambda.isLambda(),
00141                 "applyLambda:\n"
00142                 "Operator is not LAMBDA: " + lambda.toString());
00143   }
00144 
00145   Expr body(lambda.getBody());
00146   const vector<Expr>& vars = lambda.getVars();
00147 
00148   if(CHECK_PROOFS) {
00149     CHECK_SOUND(vars.size() == (size_t)e.arity(), 
00150                 "wrong number of arguments applied to lambda\n");
00151   }
00152 
00153   // Use the Expr's efficient substitution
00154   body = body.substExpr(vars, e.getKids());
00155 //   for (unsigned i = 0; i < vars.size(); i++) {
00156 //     body = substFreeTerm(body, vars[i], e[i]);
00157 //   }
00158 
00159   Assumptions a;
00160   Proof pf;
00161   if(withProof())
00162     pf = newPf("apply_lambda", e);
00163   return newRWTheorem(e, body, a, pf);
00164 }
00165 
00166 
00167 Theorem UFTheoremProducer::rewriteOpDef(const Expr& e) {
00168   if(CHECK_PROOFS) {
00169     CHECK_SOUND(e.isApply(),
00170                 "UFTheoremProducer::rewriteOpDef: 'e' is not a "
00171                 "function application:\n\n "+e.toString());
00172   }
00173 
00174   Expr op = e.getOpExpr();
00175   int opKind = op.getKind();
00176 
00177   if(CHECK_PROOFS) {
00178     CHECK_SOUND(opKind==CONSTDEF || opKind==LETDECL,
00179                 "UFTheoremProducer::rewriteOpDef: operator is not a "
00180                 "named function in:\n\n "+e.toString());
00181   }
00182   // Now actually replace the name with the definition
00183   while(opKind==CONSTDEF || opKind==LETDECL) {
00184     if(CHECK_PROOFS) {
00185       CHECK_SOUND(op.arity()==2,
00186                   "UFTheoremProducer::rewriteOpDef: bad named "
00187                   "operator in:\n\n "+e.toString());
00188     }
00189     op = op[1];
00190     opKind = op.getKind();
00191   }
00192   // ...and construct a Theorem
00193   Assumptions a;
00194   Proof pf;
00195   if(withProof())
00196     pf = newPf("rewrite_op_def", e);
00197   return newRWTheorem(e, Expr(op.mkOp(), e.getKids()), a, pf);
00198 }

Generated on Thu Apr 13 16:57:35 2006 for CVC Lite by  doxygen 1.4.4