expr copy(expr const & a) { switch (a.kind()) { case expr_kind::Var: return mk_var(var_idx(a)); case expr_kind::Constant: return mk_constant(const_name(a)); case expr_kind::Type: return mk_type(ty_level(a)); case expr_kind::Value: return mk_value(static_cast<expr_value*>(a.raw())->m_val); case expr_kind::App: return mk_app(num_args(a), begin_args(a)); case expr_kind::Eq: return mk_eq(eq_lhs(a), eq_rhs(a)); case expr_kind::Lambda: return mk_lambda(abst_name(a), abst_domain(a), abst_body(a)); case expr_kind::Pi: return mk_pi(abst_name(a), abst_domain(a), abst_body(a)); case expr_kind::Let: return mk_let(let_name(a), let_type(a), let_value(a), let_body(a)); case expr_kind::MetaVar: return mk_metavar(metavar_idx(a), metavar_ctx(a)); } lean_unreachable(); }
expr apply(expr const & a) { bool sh = false; if (is_shared(a)) { auto r = m_cache.find(a.raw()); if (r != m_cache.end()) return r->second; sh = true; } switch (a.kind()) { case expr_kind::Var: case expr_kind::Constant: case expr_kind::Type: case expr_kind::Value: return save_result(a, copy(a), sh); case expr_kind::App: { buffer<expr> new_args; for (expr const & old_arg : args(a)) new_args.push_back(apply(old_arg)); return save_result(a, mk_app(new_args), sh); } case expr_kind::HEq: return save_result(a, mk_heq(apply(heq_lhs(a)), apply(heq_rhs(a))), sh); case expr_kind::Pair: return save_result(a, mk_pair(apply(pair_first(a)), apply(pair_second(a)), apply(pair_type(a))), sh); case expr_kind::Proj: return save_result(a, mk_proj(proj_first(a), apply(proj_arg(a))), sh); case expr_kind::Lambda: return save_result(a, mk_lambda(abst_name(a), apply(abst_domain(a)), apply(abst_body(a))), sh); case expr_kind::Pi: return save_result(a, mk_pi(abst_name(a), apply(abst_domain(a)), apply(abst_body(a))), sh); case expr_kind::Sigma: return save_result(a, mk_sigma(abst_name(a), apply(abst_domain(a)), apply(abst_body(a))), sh); case expr_kind::Let: return save_result(a, mk_let(let_name(a), apply(let_type(a)), apply(let_value(a)), apply(let_body(a))), sh); case expr_kind::MetaVar: return save_result(a, update_metavar(a, [&](local_entry const & e) -> local_entry { if (e.is_inst()) return mk_inst(e.s(), apply(e.v())); else return e; }), sh); } lean_unreachable(); // LCOV_EXCL_LINE }
expr update_let(expr const & e, expr const & new_type, expr const & new_value, expr const & new_body) { if (!is_eqp(let_type(e), new_type) || !is_eqp(let_value(e), new_value) || !is_eqp(let_body(e), new_body)) return mk_let(let_name(e), new_type, new_value, new_body); else return e; }
static List s_l_1(Term m1) { List l,l1; l=CompoundArgN(m1,3); while(!is_empty_list(l)) { Term t1; t1=ListFirst(l); if(CompoundName(t1)==OPR_LET) { Term sub,a1,ila,ill; a1=sub=ConsumeCompoundArg(t1,2); ill=ConsumeCompoundArg(t1,1); FreeAtomic(t1); ChangeList(l,0); sub=CopyTerm(GetAtomProperty(a1,OPR_LET)); if(sub==0 || !is_compound(sub) || CompoundName(sub)!=OPR_LET) { sub=CopyTerm(GetAtomProperty(a1,PROP_TYPE)); if(sub==0 || !is_compound(sub) || CompoundName(sub)!=OPR_LET) { printf("Internal error: inconsistent substitution '"); WriteTerm(CompoundArg2(a1)); puts("'"); longjmp(alg1_jmp_buf,1); } } renewlab(sub); a1=ConsumeCompoundArg(sub,1); ila=ConsumeCompoundArg(sub,2); FreeAtomic(sub); repl_ind(a1,ila,ill); return SetLets(mk_let(m1,l,a1)); } l=ListTail(l); } l=CompoundArgN(m1,4); while(!is_empty_list(l)) { Term t1; t1=ListFirst(l); if(CompoundName(t1)==OPR_LET) { Term sub,a1,ila,ill; a1=sub=ConsumeCompoundArg(t1,2); ill=ConsumeCompoundArg(t1,1); if(ill) { puts("Integnal error (iinld)"); longjmp(alg1_jmp_buf,1); } l1=ConsumeCompoundArg(m1,4); l1=CutFromList(l1,l); SetCompoundArg(m1,4,l1); sub=CopyTerm(GetAtomProperty(a1,OPR_LET)); if(sub==0 || !is_compound(sub) || CompoundName(sub)!=OPR_LET) { sub=CopyTerm(GetAtomProperty(a1,PROP_TYPE)); if(sub==0 || !is_compound(sub) || CompoundName(sub)!=OPR_LET) { printf("Internal error: inconsistent substitution '"); WriteTerm(CompoundArg2(a1)); puts("'"); longjmp(alg1_jmp_buf,1); } } renewlab(sub); if(CompoundArgN(sub,3)==0) { ErrorInfo(378); printf("symbol '%s' can not be in denominator\n",AtomValue(a1)); longjmp(alg1_jmp_buf,1); } a1=ConsumeCompoundArg(sub,3); ila=ConsumeCompoundArg(sub,2); FreeAtomic(sub); if(ila) { puts("Internal error (iidl1)"); longjmp(alg1_jmp_buf,1); } return SetLets(mk_let_d(m1,a1)); } l=ListTail(l); } return AppendFirst(NewList(),m1); }