void Tptp::makeApplication(Expr& expr, std::string& name, std::vector<Expr>& args, bool term) { if (args.empty()) { // Its a constant if (isDeclared(name)) { // already appeared expr = getVariable(name); } else { Type t = term ? d_unsorted : getExprManager()->booleanType(); expr = mkVar(name, t, ExprManager::VAR_FLAG_GLOBAL); // levelZero preemptCommand(new DeclareFunctionCommand(name, expr, t)); } } else { // Its an application if (isDeclared(name)) { // already appeared expr = getVariable(name); } else { std::vector<Type> sorts(args.size(), d_unsorted); Type t = term ? d_unsorted : getExprManager()->booleanType(); t = getExprManager()->mkFunctionType(sorts, t); expr = mkVar(name, t, ExprManager::VAR_FLAG_GLOBAL); // levelZero preemptCommand(new DeclareFunctionCommand(name, expr, t)); } // args might be rationals, in which case we need to create // distinct constants of the "unsorted" sort to represent them for (size_t i = 0; i < args.size(); ++i) { if (args[i].getType().isReal() && FunctionType(expr.getType()).getArgTypes()[i] == d_unsorted) { args[i] = convertRatToUnsorted(args[i]); } } expr = getExprManager()->mkExpr(kind::APPLY_UF, expr, args); } }
std::vector<Expr> Parser::mkVars(const std::vector<std::string> names, const Type& type, uint32_t flags) { std::vector<Expr> vars; for(unsigned i = 0; i < names.size(); ++i) { vars.push_back(mkVar(names[i], type, flags)); } return vars; }
/* parse.c 612d */ static Exp parseexp(Par p) { switch (p->alt) { case ATOM: /* parseexp [[atom]] and return the result 612e */ { const char *s = nametostr(p->u.atom); char *t; long l = strtol(s, &t, 10); if (*t == '\0') /* the number is the whole string */ return mkLiteral(l); else return mkVar(p->u.atom); } case LIST: /* parseexp [[list]] and return the result 613a */ { Parlist pl; Name first; Explist argl; pl = p->u.list; if (pl == NULL) error("%p: empty list in input", p); if (pl->hd->alt != ATOM) error("%p: first item of list not name", p); first = pl->hd->u.atom; argl = parselist(pl->tl); if (first == strtoname("begin")) { /* parseexp [[begin]] and return the result 613b */ return mkBegin(argl); } else if (first == strtoname("if")) { /* parseexp [[if]] and return the result 613c */ if (lengthEL(argl) != 3) error("%p: usage: (if cond true false)", p); return mkIfx(nthEL(argl, 0), nthEL(argl, 1), nthEL(argl, 2)); } else if (first == strtoname("set")) { /* parseexp [[set]] and return the result 613e */ if (lengthEL(argl) != 2) error("%p: usage: (set var exp)", p); if (nthEL(argl, 0)->alt != VAR) error("%p: set needs variable as first param", p); return mkSet(nthEL(argl, 0)->u.var, nthEL(argl, 1)); } else if (first == strtoname("while")) { /* parseexp [[while]] and return the result 613d */ if (lengthEL(argl) != 2) error("%p: usage: (while cond body)", p); return mkWhilex(nthEL(argl, 0), nthEL(argl, 1)); } else { /* parseexp function application and return the result 614a */ return mkApply(first, argl); } } default: assert(0); return NULL; } }
std::vector<Expr> Parser::mkVars(const std::vector<std::string> names, const Type& type, uint32_t flags) { if (d_globalDeclarations) { flags |= ExprManager::VAR_FLAG_GLOBAL; } std::vector<Expr> vars; for (unsigned i = 0; i < names.size(); ++i) { vars.push_back(mkVar(names[i], type, flags)); } return vars; }
// a != b → R( a, i_{a,b} ) = R( b, i_{a,b} ) void Egraph::ExtAxiom( Enode * a, Enode * b ) { assert( isDynamic( a ) ); assert( isDynamic( b ) ); Enode * as = dynamicToStatic( a ); Enode * bs = dynamicToStatic( b ); assert( isStatic( as ) ); assert( isStatic( bs ) ); assert( as->isDTypeArray( ) ); assert( bs->isDTypeArray( ) ); // create fresh index i_a,b for pair a,b char def_name[ 48 ]; sprintf( def_name, IND_STR, as->getId( ), bs->getId( ) ); const unsigned type = DTYPE_ARRAY_INDEX; if ( lookupSymbol( def_name ) == NULL ) newSymbol( def_name, type ); // Create new variable Enode * i = mkVar( def_name ); // Create two new selections Enode * select1 = mkSelect( as, i ); Enode * select2 = mkSelect( bs, i ); // Create new literals Enode * lit1 = mkEq( cons( as, cons( bs ) ) ); Enode * lit2_pos = mkEq( cons( select1, cons( select2 ) ) ); Enode * lit2 = mkNot( cons( lit2_pos ) ); #ifdef PRODUCE_PROOF if ( config.gconfig.print_inter > 0 ) { const uint64_t shared = getIPartitions( as ) & getIPartitions( bs ); // Mixed can't be one at this point assert( shared != 1 ); // Set AB-mixed partition if no intersection if ( shared == 0 ) { setIPartitions( i, 1 ); setIPartitions( select1, 1 ); setIPartitions( select2, 1 ); setIPartitions( lit1, 1 ); setIPartitions( lit2_pos, 1 ); setIPartitions( lit2, 1 ); } // Otherwise they share something else { setIPartitions( i, shared ); setIPartitions( select1, shared ); setIPartitions( select2, shared ); setIPartitions( lit1, shared ); setIPartitions( lit2_pos, shared ); setIPartitions( lit2, shared ); } } #endif vector< Enode * > v; v.push_back( lit1 ); v.push_back( lit2 ); #ifdef ARR_VERB cout << "Axiom Ext -> " << "( or " << lit1 << " " << lit2 << " )" << endl; #endif splitOnDemand( v, id ); handleArrayAssertedAtomTerm( select1 ); handleArrayAssertedAtomTerm( select2 ); // New contexts to propagate info about new index // Given R(a,new) look for all store users W(a,i,e) // and instantiate RoW over R(W(a,i,e),new) vector< Enode * > sela; vector< Enode * > stoa; vector< Enode * > selb; vector< Enode * > stob; Enode * select3 = NULL; // Act over a getUsers( a, sela, stoa ); for( size_t j = 0 ; j < stoa.size( ) ; j++ ) { assert( isDynamic( stoa[ j ] ) ); Enode * ss = dynamicToStatic( stoa[ j ] ); assert( isStatic( ss ) ); // Creation new select for each store user of a select3 = mkSelect( ss, i ); // RoW over new select handleArrayAssertedAtomTerm( select3 ); #ifdef PRODUCE_PROOF if ( config.gconfig.print_inter > 0 ) { const uint64_t shared = getIPartitions( ss ) & getIPartitions( i ); // Mixed can't be one at this point assert( shared != 1 ); // Set AB-mixed partition if no intersection if ( shared == 0 ) setIPartitions( select3, 1 ); // Otherwise they share something else setIPartitions( select3, shared ); } #endif } // Act over b getUsers( b, selb, stob ); for ( size_t j = 0 ; j < stob.size( ) ; j++ ) { assert( isDynamic( stoa[ j ] ) ); Enode * ss = dynamicToStatic( stob[ j ] ); assert( isStatic( ss ) ); // Creation new select for each store user of b select3 = mkSelect( ss, i ); #ifdef PRODUCE_PROOF if ( config.gconfig.print_inter > 0 ) { const uint64_t shared = getIPartitions( ss ) & getIPartitions( i ); // Mixed can't be one at this point assert( shared != 1 ); // Set AB-mixed partition if no intersection if ( shared == 0 ) setIPartitions( select3, 1 ); // Otherwise they share something else setIPartitions( select3, shared ); } #endif // RoW over new select handleArrayAssertedAtomTerm( select3 ); } }
/* parse.c 720f */ Exp parseexp(Par p) { switch (p->alt) { case ATOM: /* parseexp [[ATOM]] and return 721 */ { Name n = p->u.atom; const char *s; /* string form of n */ char *t; /* nondigits in s, if any */ long l; /* number represented by s, if any */ if (n == strtoname("#t")) return mkLiteral(truev); else if (n == strtoname("#f")) return mkLiteral(falsev); s = nametostr(n); l = strtol(s, &t, 10); if (*t == '\0' && *s != '\0') /* all the characters in s are digits base 10 */ return mkLiteral(mkNum(l)); else return mkVar(n); } case LIST: /* parseexp [[LIST]] and return 722a */ { Parlist pl; /* parenthesized list we are parsing */ Name first; /* first element, as a name (or NULL if not name) */ Explist el; /* remaining elements, as expressions */ Exp rv; /* result of parsing */ pl = p->u.list; if (pl == NULL) error("%p: empty list in input", p); first = pl->hd->alt == ATOM ? pl->hd->u.atom : NULL; if (first == strtoname("lambda")) { /* parseexp [[lambda]] and put the result in [[rv]] 722b */ Par q; if (lengthPL(pl->tl) != 2) error("%p: usage: (lambda (formals) exp)", p); q = nthPL(pl->tl, 0); if (q->alt != LIST) error("%p: usage: (lambda (formals) exp)", p); rv = mkLambdax(mkLambda(getnamelist(p, q->u.list), parseexp( nthPL(pl->tl, 1)))); } else if (first == strtoname("let") || first == strtoname("let*") || first == strtoname("letrec")) { /* parseexp let and put the result in [[rv]] 723a */ Letkeyword letword; Par letbindings; if (first == strtoname("let")) letword = LET; else if (first == strtoname("let*")) letword = LETSTAR; else if (first == strtoname("letrec")) letword = LETREC; else assert(0); if (lengthPL(pl->tl) != 2) error("%p: usage: (%n (letlist) exp)", p, first); letbindings = nthPL(pl->tl, 0); if (letbindings->alt != LIST) error("%p: usage: (%n (letlist) exp)", p, first); rv = mkLetx(letword, NULL, NULL, parseexp(nthPL(pl->tl, 1))); parseletbindings(p, letbindings->u.list, rv); } else if (first == strtoname("quote")) { /* parseexp [[quote]] and put the result in [[rv]] 723d */ { if (lengthPL(pl) != 2) error("%p: quote needs exactly one argument", p); rv = mkLiteral(parsesx(nthPL(pl, 1))); } } else { el = parselist(pl->tl); if (first == strtoname("begin")) { /* parseexp [[begin]] and put the result in [[rv]] 724e */ rv = mkBegin(el); } else if (first == strtoname("if")) { /* parseexp [[if]] and put the result in [[rv]] 724f */ if (lengthEL(el) != 3) error("%p: usage: (if cond true false)", p); rv = mkIfx(nthEL(el, 0), nthEL(el, 1), nthEL(el, 2)); } else if (first == strtoname("set")) { /* parseexp [[set]] and put the result in [[rv]] 725b */ if (lengthEL(el) != 2) error("%p: usage: (set var exp)", p); if (nthEL(el, 0)->alt != VAR) error("%p: set needs variable as first param", p); rv = mkSet(nthEL(el, 0)->u.var, nthEL(el, 1)); } else if (first == strtoname("while")) { /* parseexp [[while]] and put the result in [[rv]] 725a */ if (lengthEL(el) != 2) error("%p: usage: (while cond body)", p); rv = mkWhilex(nthEL(el, 0), nthEL(el, 1)); /* [[RBR else LBR]] possibly parse expressions that are in \uschemeplus 723e */ /* nothing happens */ } else { /* parseexp application and put the result in [[rv]] 724d */ rv = mkApply(parseexp(pl->hd), el); } } return rv; } default: assert(0); return NULL; } }
/* * <parse.c>= */ static Exp parseexp(Par p) { switch (p->alt) { case ATOM: /* * If we have a name, it must be either a literal value * or a variable. * <parseexp [[atom]] and return the result>= */ { const char *s = nametostr(p->u.atom); char *t; long l = strtol(s, &t, 10); if (*t == '\0') /* the number is the whole string */ return mkLiteral(l); else return mkVar(p->u.atom); } case LIST: /* * If we have a list, we need to look at the first * element, which must be a name. * <parseexp [[list]] and return the result>= */ { Parlist pl; Name first; Explist argl; pl = p->u.list; if (pl == NULL) error("%p: empty list in input", p); if (pl->hd->alt != ATOM) error("%p: first item of list not name", p); first = pl->hd->u.atom; argl = parselist(pl->tl); if (first == strtoname("begin")) { /* * A [[begin]] expression can have any number of * parameters. * <parseexp [[begin]] and return the result>= */ return mkBegin(argl); } else if (first == strtoname("if")) { /* * An [[if]] expression needs three parameters. * <parseexp [[if]] and return the result>= */ if (lengthEL(argl) != 3) error("%p: usage: (if cond true false)", p); return mkIfx(nthEL(argl, 0), nthEL(argl, 1), nthEL(argl, 2)); } else if (first == strtoname("set")) { /* * A [[set]] expression requires a variable and a value. * <parseexp [[set]] and return the result>= */ if (lengthEL(argl) != 2) error("%p: usage: (set var exp)", p); if (nthEL(argl, 0)->alt != VAR) error("%p: set needs variable as first param", p); return mkSet(nthEL(argl, 0)->u.var, nthEL(argl, 1)); } else if (first == strtoname("while")) { /* * A [[while]] loop needs two. * <parseexp [[while]] and return the result>= */ if (lengthEL(argl) != 2) error("%p: usage: (while cond body)", p); return mkWhilex(nthEL(argl, 0), nthEL(argl, 1)); } else { /* * Anything else must be a function application. We * can't check the number of parameters here, because * the function definition might change before * evaluation, or might not be present yet (as occurs, * for example, when defining recursive functions). * <parseexp function application and return the result>= */ return mkApply(first, argl); } } default: assert(0); return NULL; } }