void checkInflate(buffer const& input, buffer const& original) { for(std::size_t i = 0; i < input.size(); ++i) { buffer output(original.size()); inflate_stream zs; zs.avail_in = 0; zs.next_in = 0; zs.next_out = output.data(); zs.avail_out = output.capacity(); if(i > 0) { zs.next_in = (Byte*)input.data(); zs.avail_in = i; auto result = zs.write(Z_FULL_FLUSH); expect(result == Z_OK); } zs.next_in = (Byte*)input.data() + i; zs.avail_in = input.size() - i; auto result = zs.write(Z_FULL_FLUSH); output.resize(output.capacity() - zs.avail_out); expect(result == Z_OK); expect(output.size() == original.size()); expect(std::memcmp( output.data(), original.data(), original.size()) == 0); } }
static expr parse_notation_expr(parser & p, buffer<expr> const & locals) { auto pos = p.pos(); expr r = p.parse_expr(); r = abstract(r, locals.size(), locals.data()); check_notation_expr(r, pos); return r; }
/* Collect (and sort) dependencies of collected parameters */ void collect_and_normalize_dependencies(buffer<expr> & norm_params) { name_map<expr> new_types; for (unsigned i = 0; i < m_params.size(); i++) { expr x = m_params[i]; expr new_type = collect(m_ctx.instantiate_mvars(m_ctx.infer(x))); new_types.insert(mlocal_name(x), new_type); } local_context const & lctx = m_ctx.lctx(); std::sort(m_params.begin(), m_params.end(), [&](expr const & l1, expr const & l2) { return lctx.get_local_decl(l1)->get_idx() < lctx.get_local_decl(l2)->get_idx(); }); for (unsigned i = 0; i < m_params.size(); i++) { expr x = m_params[i]; expr type = *new_types.find(mlocal_name(x)); expr new_type = replace_locals(type, i, m_params.data(), norm_params.data()); expr new_param = m_ctx.push_local(local_pp_name(x), new_type, local_info(x)); norm_params.push_back(new_param); } }
void parse_table::for_each(buffer<transition> & ts, std::function<void(unsigned, transition const *, list<accepting> const &)> const & fn) const { if (!is_nil(m_ptr->m_accept)) fn(ts.size(), ts.data(), m_ptr->m_accept); m_ptr->m_children.for_each([&](name const & k, list<pair<action, parse_table>> const & lst) { for (auto const & p : lst) { ts.push_back(transition(k, p.first)); p.second.for_each(ts, fn); ts.pop_back(); } }); }
expr mk_structure_instance(name const & s, buffer<name> const & fns, buffer<expr> const & fvs) { lean_assert(fns.size() == fvs.size()); return mk_structure_instance_core(s, to_list(fns), fvs.size(), fvs.data()); }
inline bool operator==(const buffer& lhs, const buffer& rhs) { if (lhs.size() == rhs.size()) { return memcmp(lhs.data(), rhs.data(), lhs.size()) == 0; } return false; }
/* Given a cases_on application, distribute extra arguments over minor premisses. cases_on major minor_1 ... minor_n a_1 ... a_n We apply a similar transformation at erase_irrelevant, but its effect can be undone in subsequent compilation steps. */ void distribute_extra_args_over_minors(name const & I_name, buffer<name> const & cnames, buffer<expr> & args) { lean_assert(args.size() > cnames.size() + 1); unsigned nparams = *inductive::get_num_params(env(), I_name); for (unsigned i = 0; i < cnames.size(); i++) { unsigned carity = get_constructor_arity(env(), cnames[i]); unsigned data_sz = carity - nparams; type_context::tmp_locals locals(ctx()); expr new_minor = args[i+1]; for (unsigned j = 0; j < data_sz; j++) { if (!is_lambda(new_minor)) throw exception("unexpected occurrence of 'cases_on' expression, " "the minor premise is expected to be a lambda-expression"); expr local = locals.push_local_from_binding(new_minor); new_minor = instantiate(binding_body(new_minor), local); } new_minor = beta_reduce(mk_app(new_minor, args.size() - cnames.size() - 1, args.data() + cnames.size() + 1)); args[i+1] = locals.mk_lambda(new_minor); } args.shrink(cnames.size() + 1); }
inline void cipher_stream::reallocate(size_t alloc) { m_buffer.data().resize(alloc); }
expr replace_locals(expr const & e, buffer<expr> const & locals, buffer<expr> const & terms) { lean_assert(locals.size() == terms.size()); lean_assert(std::all_of(locals.begin(), locals.end(), is_local)); return replace_locals(e, locals.size(), locals.data(), terms.data()); }
buffer<T>::buffer(const buffer& rhs) : size_{rhs.size_} , buf_{type_trait<T>::alloc(size_)} { memcpy(data(), rhs.data(), size_ * sizeof(T)); }
inline size_t buffer_size(const buffer& buf) { return buf.data().size(); }
inline bool operator<(const buffer& lhs, const buffer& rhs) { return lhs.data() < rhs.data(); }
inline bool operator!=(const buffer& lhs, const buffer& rhs) { return lhs.data() != rhs.data(); }
T buffer_cast(const buffer& buf) { return reinterpret_cast<T>(&buf.data()[0]); }
table(buffer& a) : p(a.data()), sz(a.size()) {}
array(buffer& a) : p(a.data()), sz(a.size()) {}
void write(const buffer& buf) { write(buf.size(), buf.data()); }
static proof_state_seq apply_tactic_core(environment const & env, io_state const & ios, proof_state const & s, expr const & _e, buffer<constraint> & cs, add_meta_kind add_meta, subgoals_action_kind subgoals_action, optional<unifier_kind> const & uk = optional<unifier_kind>()) { goals const & gs = s.get_goals(); if (empty(gs)) { throw_no_goal_if_enabled(s); return proof_state_seq(); } bool class_inst = get_apply_class_instance(ios.get_options()); name_generator ngen = s.get_ngen(); std::shared_ptr<type_checker> tc(mk_type_checker(env, ngen.mk_child())); goal g = head(gs); goals tail_gs = tail(gs); expr t = g.get_type(); expr e = _e; auto e_t_cs = tc->infer(e); e_t_cs.second.linearize(cs); expr e_t = e_t_cs.first; buffer<expr> metas; local_context ctx; bool initialized_ctx = false; unifier_config cfg(ios.get_options()); if (uk) cfg.m_kind = *uk; if (add_meta != DoNotAdd) { unsigned num_e_t = get_expect_num_args(*tc, e_t); if (add_meta == AddDiff) { unsigned num_t = get_expect_num_args(*tc, t); if (num_t <= num_e_t) num_e_t -= num_t; else num_e_t = 0; } else { lean_assert(add_meta == AddAll); } for (unsigned i = 0; i < num_e_t; i++) { auto e_t_cs = tc->whnf(e_t); e_t_cs.second.linearize(cs); e_t = e_t_cs.first; expr meta; if (class_inst && binding_info(e_t).is_inst_implicit()) { if (!initialized_ctx) { ctx = g.to_local_context(); initialized_ctx = true; } bool use_local_insts = true; bool is_strict = false; auto mc = mk_class_instance_elaborator( env, ios, ctx, ngen.next(), optional<name>(), use_local_insts, is_strict, some_expr(head_beta_reduce(binding_domain(e_t))), e.get_tag(), cfg, nullptr); meta = mc.first; cs.push_back(mc.second); } else { meta = g.mk_meta(ngen.next(), head_beta_reduce(binding_domain(e_t))); } e = mk_app(e, meta); e_t = instantiate(binding_body(e_t), meta); metas.push_back(meta); } } metavar_closure cls(t); cls.mk_constraints(s.get_subst(), justification()); pair<bool, constraint_seq> dcs = tc->is_def_eq(t, e_t); if (!dcs.first) { throw_tactic_exception_if_enabled(s, [=](formatter const & fmt) { format r = format("invalid 'apply' tactic, failed to unify"); r += pp_indent_expr(fmt, t); r += compose(line(), format("with")); r += pp_indent_expr(fmt, e_t); return r; }); return proof_state_seq(); } dcs.second.linearize(cs); unify_result_seq rseq = unify(env, cs.size(), cs.data(), ngen.mk_child(), s.get_subst(), cfg); list<expr> meta_lst = to_list(metas.begin(), metas.end()); return map2<proof_state>(rseq, [=](pair<substitution, constraints> const & p) -> proof_state { substitution const & subst = p.first; constraints const & postponed = p.second; name_generator new_ngen(ngen); substitution new_subst = subst; expr new_e = new_subst.instantiate_all(e); assign(new_subst, g, new_e); goals new_gs = tail_gs; if (subgoals_action != IgnoreSubgoals) { buffer<expr> metas; for (auto m : meta_lst) { if (!new_subst.is_assigned(get_app_fn(m))) metas.push_back(m); } if (subgoals_action == AddRevSubgoals) { for (unsigned i = 0; i < metas.size(); i++) new_gs = cons(goal(metas[i], new_subst.instantiate_all(tc->infer(metas[i]).first)), new_gs); } else { lean_assert(subgoals_action == AddSubgoals || subgoals_action == AddAllSubgoals); if (subgoals_action == AddSubgoals) remove_redundant_metas(metas); unsigned i = metas.size(); while (i > 0) { --i; new_gs = cons(goal(metas[i], new_subst.instantiate_all(tc->infer(metas[i]).first)), new_gs); } } } return proof_state(s, new_gs, new_subst, new_ngen, postponed); }); }
int html_encoder::encode(const char* string, size_t len, buffer& buf) { const char* src = string; const char* end = string + len; // Compute bytes needed. size_t needed = 0; while (src < end) { unsigned char c = (unsigned char) *src++; if ((c == '<') || (c == '>')) { needed += 4; } else if ((c == '&') || (c == '\'')) { needed += 5; } else if (c == '"') { needed += 6; } else { needed++; } } if (!buf.allocate(needed)) { return -1; } char* dst = buf.data() + buf.count(); // Encode. while (string < end) { unsigned char c = (unsigned char) *string++; if (c == '<') { *dst++ = '&'; *dst++ = 'l'; *dst++ = 't'; *dst++ = ';'; } else if (c == '>') { *dst++ = '&'; *dst++ = 'g'; *dst++ = 't'; *dst++ = ';'; } else if (c == '&') { *dst++ = '&'; *dst++ = 'a'; *dst++ = 'm'; *dst++ = 'p'; *dst++ = ';'; } else if (c == '"') { *dst++ = '&'; *dst++ = 'q'; *dst++ = 'u'; *dst++ = 'o'; *dst++ = 't'; *dst++ = ';'; } else if (c == '\'') { *dst++ = '&'; *dst++ = '#'; *dst++ = '3'; *dst++ = '9'; *dst++ = ';'; } else { *dst++ = c; } } buf.increment_count(needed); return needed; }