int main(int argc, char** argv) { double begin; double end; size_t nsym; size_t nactive; size_t n; size_t max_succ; cfg_t* cfg; bool print; int seed = 0; progname = argv[0]; if (argc == 7) { nsym = atoi(argv[1]); n = atoi(argv[2]); max_succ = atoi(argv[3]); nactive = atoi(argv[4]); print = atoi(argv[6]); } else { nsym = 100; n = 10; max_succ = 4; nactive = 10; print = 1; } printf("nsymbol = %zu\n", nsym); printf("nvertex = %zu\n", n); printf("max-succ = %zu\n", max_succ); printf("nactive = %zu\n", nactive); if (seed == 1) init_random(seed); else { printf("pid %d\n", getpid()); init_random(getpid()); } printf("generating cfg...\n"); cfg = new_cfg(n, nsym, max_succ); generate_cfg(cfg, n, max_succ); printf("generating usedefs...\n"); generate_usedefs(cfg, n, nsym, nactive); printf("liveness...\n\n"); begin = sec(); liveness(cfg); end = sec(); printf("T = %8.4lf s\n\n", end-begin); if (print) print_sets(cfg, stdout); free_cfg(cfg); return 0; }
optional<expr> mk_class_instance(environment const & env, io_state const & ios, local_context const & ctx, name const & prefix, expr const & type, bool relax_opaque, bool use_local_instances, unifier_config const & cfg) { auto C = std::make_shared<class_instance_context>(env, ios, prefix, relax_opaque, use_local_instances); if (!is_ext_class(C->tc(), type)) return none_expr(); expr meta = ctx.mk_meta(C->m_ngen, some_expr(type), type.get_tag()); unsigned depth = 0; constraint c = mk_class_instance_cnstr(C, ctx, meta, depth); unifier_config new_cfg(cfg); new_cfg.m_discard = true; new_cfg.m_use_exceptions = true; new_cfg.m_pattern = true; new_cfg.m_kind = C->m_conservative ? unifier_kind::VeryConservative : unifier_kind::Liberal; try { auto seq = unify(env, 1, &c, C->m_ngen.mk_child(), substitution(), new_cfg); while (true) { auto p = seq.pull(); lean_assert(p); substitution s = p->first.first; expr r = s.instantiate_all(meta); if (!has_expr_metavar_relaxed(r)) return some_expr(r); seq = p->second; } } catch (exception &) { return none_expr(); } }
mh_history_params* load_params(const char *path) { mh_history_params *p = allocate(1, sizeof(*p)); config_t *cfg = new_cfg(); cfg_loadfile(cfg, path); const char *input; config_setting_t *inputs = cfg_findsetting(cfg, "inputs"); input = cfg_getstring(inputs, "matches_512_256"); p->matches_512_256 = strdup(input); check_file_harsh(p->matches_512_256, "Wrong matches_512_256 in configs"); input = cfg_getstring(inputs, "matches_1024_512"); p->matches_1024_512 = strdup(input); check_file_harsh(p->matches_1024_512, "Wrong matches_1024_512 in configs"); const char *raw_matches_256_path = cfg_getstring(inputs, "matches_256"); const char *raw_matches_512_path = cfg_getstring(inputs, "matches_512"); const char *raw_matches_1024_path = cfg_getstring(inputs, "matches_1024"); p->num_match_files = cfg_getint(inputs, "num_of_match_files"); p->matches_256 = allocate(p->num_match_files, sizeof(char*)); p->matches_512 = allocate(p->num_match_files, sizeof(char*)); p->matches_1024 = allocate(p->num_match_files, sizeof(char*)); int i; char match_fname[1024], *errormsg; for(i = 0; i < p->num_match_files; i++){ sprintf(match_fname, raw_matches_256_path, i, i+1); p->matches_256[i] = strdup(match_fname); errormsg = concat(2, match_fname, " does not exist"); check_file_harsh(p->matches_256[i], errormsg); sprintf(match_fname, raw_matches_512_path, i, i+1); p->matches_512[i] = strdup(match_fname); errormsg = concat(2, match_fname, " does not exist"); check_file_harsh(p->matches_512[i], errormsg); sprintf(match_fname, raw_matches_1024_path, i, i+1); p->matches_1024[i] = strdup(match_fname); errormsg = concat(2, match_fname, " does not exist"); check_file_harsh(p->matches_1024[i], errormsg); } const char *raw_halos_256_path = cfg_getstring(inputs, "halos_256"); const char *raw_halos_512_path = cfg_getstring(inputs, "halos_512"); const char *raw_halos_1024_path = cfg_getstring(inputs, "halos_1024"); p->num_halo_files = cfg_getint(inputs, "num_of_halo_files"); p->halos_256 = allocate(p->num_halo_files, sizeof(char*)); p->halos_512 = allocate(p->num_halo_files, sizeof(char*)); p->halos_1024 = allocate(p->num_halo_files, sizeof(char*)); char halo_fname[1024]; for(i = 0; i < p->num_halo_files; i++){ sprintf(halo_fname, raw_halos_256_path, i); p->halos_256[i] = strdup(halo_fname); errormsg = concat(2, halo_fname, " does not exist"); check_file_harsh(p->halos_256[i], errormsg); sprintf(halo_fname, raw_halos_512_path, i); p->halos_512[i] = strdup(halo_fname); errormsg = concat(2, halo_fname, " does not exist"); check_file_harsh(p->halos_512[i], errormsg); sprintf(halo_fname, raw_halos_1024_path, i); p->halos_1024[i] = strdup(halo_fname); errormsg = concat(2, halo_fname, " does not exist"); check_file_harsh(p->halos_1024[i], errormsg); } const char *output; config_setting_t *outputs = cfg_findsetting(cfg, "outputs"); output = cfg_getstring(outputs, "ascii"); p->ascii_output = strdup(output); char *for_dir_check = strdup(output); if(check_dir(dirname(for_dir_check)) != CD_DIR_EXIST){ printf("[Error! Wrong ascii_output dir in configs]\n"); exit(EXIT_FAILURE); } return p; }
constraint mk_class_instance_root_cnstr(std::shared_ptr<class_instance_context> const & C, local_context const & _ctx, expr const & m, bool is_strict, unifier_config const & cfg, delay_factor const & factor) { environment const & env = C->env(); justification j = mk_failed_to_synthesize_jst(env, m); auto choice_fn = [=](expr const & meta, expr const & meta_type, substitution const & s, name_generator const & ngen) { environment const & env = C->env(); auto cls_name_it = is_ext_class(C->tc(), meta_type); if (!cls_name_it) { // do nothing, since type is not a class. return lazy_list<constraints>(constraints()); } local_context ctx = _ctx.instantiate(substitution(s)); pair<expr, justification> mj = update_meta(meta, s); expr new_meta = mj.first; justification new_j = mj.second; unsigned depth = 0; constraint c = mk_class_instance_cnstr(C, ctx, new_meta, depth); unifier_config new_cfg(cfg); new_cfg.m_discard = false; new_cfg.m_use_exceptions = false; new_cfg.m_pattern = true; new_cfg.m_kind = C->m_conservative ? unifier_kind::VeryConservative : unifier_kind::Liberal; auto to_cnstrs_fn = [=](substitution const & subst, constraints const & cnstrs) -> constraints { substitution new_s = subst; // some constraints may have been postponed (example: universe level constraints) constraints postponed = map(cnstrs, [&](constraint const & c) { // we erase internal justifications return update_justification(c, mk_composite1(j, new_j)); }); metavar_closure cls(new_meta); cls.add(meta_type); bool relax = C->m_relax; constraints cs = cls.mk_constraints(new_s, new_j, relax); return append(cs, postponed); }; auto no_solution_fn = [=]() { if (is_strict) return lazy_list<constraints>(); else return lazy_list<constraints>(constraints()); }; unify_result_seq seq1 = unify(env, 1, &c, ngen, substitution(), new_cfg); unify_result_seq seq2 = filter(seq1, [=](pair<substitution, constraints> const & p) { substitution new_s = p.first; expr result = new_s.instantiate(new_meta); // We only keep complete solutions (modulo universe metavariables) return !has_expr_metavar_relaxed(result); }); if (get_class_unique_class_instances(C->m_ios.get_options())) { optional<expr> solution; substitution subst; constraints cnstrs; for_each(seq2, [&](pair<substitution, constraints> const & p) { subst = p.first; cnstrs = p.second; expr next_solution = subst.instantiate(new_meta); if (solution) { throw_class_exception(m, [=](formatter const & fmt) { format r = format("ambiguous class-instance resolution, " "there is more than one solution"); r += pp_indent_expr(fmt, *solution); r += compose(line(), format("and")); r += pp_indent_expr(fmt, next_solution); return r; }); } else { solution = next_solution; } }); if (!solution) { return no_solution_fn(); } else { // some constraints may have been postponed (example: universe level constraints) return lazy_list<constraints>(to_cnstrs_fn(subst, cnstrs)); } } else { if (try_multiple_instances(env, *cls_name_it)) { lazy_list<constraints> seq3 = map2<constraints>(seq2, [=](pair<substitution, constraints> const & p) { return to_cnstrs_fn(p.first, p.second); }); if (is_strict) { return seq3; } else { // make sure it does not fail by appending empty set of constraints return append(seq3, lazy_list<constraints>(constraints())); } } else { auto p = seq2.pull(); if (!p) return no_solution_fn(); else return lazy_list<constraints>(to_cnstrs_fn(p->first.first, p->first.second)); } } }; bool owner = false; bool relax = C->m_relax; return mk_choice_cnstr(m, choice_fn, factor, owner, j, relax); }
/** \brief Create a "choice" constraint that postpones the resolution of a calc proof step. By delaying it, we can perform quick fixes such as: - adding symmetry - adding ! - adding subst */ constraint mk_calc_proof_cnstr(environment const & env, options const & opts, old_local_context const & _ctx, expr const & m, expr const & _e, constraint_seq const & cs, unifier_config const & cfg, info_manager * im, update_type_info_fn const & fn) { justification j = mk_failed_to_synthesize_jst(env, m); auto choice_fn = [=](expr const & meta, expr const & _meta_type, substitution const & _s) { old_local_context ctx = _ctx; expr e = _e; substitution s = _s; expr meta_type = _meta_type; type_checker_ptr tc = mk_type_checker(env); constraint_seq new_cs = cs; expr e_type = tc->infer(e, new_cs); e_type = s.instantiate(e_type); tag g = e.get_tag(); bool calc_assistant = get_elaborator_calc_assistant(opts); if (calc_assistant) { // add '!' is needed while (is_norm_pi(*tc, e_type, new_cs)) { binder_info bi = binding_info(e_type); if (!bi.is_implicit() && !bi.is_inst_implicit()) { if (!has_free_var(binding_body(e_type), 0)) { // if the rest of the type does not reference argument, // then we also stop consuming arguments break; } } expr imp_arg = ctx.mk_meta(some_expr(binding_domain(e_type)), g); e = mk_app(e, imp_arg, g); e_type = instantiate(binding_body(e_type), imp_arg); } if (im) fn(e); } e_type = head_beta_reduce(e_type); expr const & meta_type_fn = get_app_fn(meta_type); expr const & e_type_fn = get_app_fn(e_type); if (is_constant(meta_type_fn) && (!is_constant(e_type_fn) || const_name(e_type_fn) != const_name(meta_type_fn))) { // try to make sure meta_type and e_type have the same head symbol if (!try_normalize_to_head(env, const_name(meta_type_fn), e_type, new_cs) && is_constant(e_type_fn)) { try_normalize_to_head(env, const_name(e_type_fn), meta_type, new_cs); } } auto try_alternative = [&](expr const & e, expr const & e_type, constraint_seq fcs, bool conservative) { justification new_j = mk_type_mismatch_jst(e, e_type, meta_type); if (!tc->is_def_eq(e_type, meta_type, new_j, fcs)) throw unifier_exception(new_j, s); buffer<constraint> cs_buffer; fcs.linearize(cs_buffer); metavar_closure cls(meta); cls.add(meta_type); cls.mk_constraints(s, j, cs_buffer); unifier_config new_cfg(cfg); new_cfg.m_discard = false; new_cfg.m_kind = conservative ? unifier_kind::Conservative : unifier_kind::Liberal; unify_result_seq seq = unify(env, cs_buffer.size(), cs_buffer.data(), substitution(), new_cfg); auto p = seq.pull(); lean_assert(p); substitution new_s = p->first.first; constraints postponed = map(p->first.second, [&](constraint const & c) { // we erase internal justifications return update_justification(c, j); }); expr new_e = new_s.instantiate(e); if (conservative && has_expr_metavar_relaxed(new_s.instantiate_all(e))) throw_elaborator_exception("solution contains metavariables", e); if (im) im->instantiate(new_s); constraints r = cls.mk_constraints(new_s, j); buffer<expr> locals; expr mvar = get_app_args(meta, locals); expr val = Fun(locals, new_e); r = cons(mk_eq_cnstr(mvar, val, j), r); return append(r, postponed); }; if (!get_elaborator_calc_assistant(opts)) { bool conservative = false; return try_alternative(e, e_type, new_cs, conservative); } else { // TODO(Leo): after we have the simplifier and rewriter tactic, we should revise // this code. It is "abusing" the higher-order unifier. { // Try the following possible intrepretations using a "conservative" unification procedure. // That is, we only unfold definitions marked as reducible. // Assume pr is the proof provided. // 1. pr bool conservative = true; try { return try_alternative(e, e_type, new_cs, conservative); } catch (exception & ex) {} // 2. eq.symm pr constraint_seq symm_cs = new_cs; auto symm = apply_symmetry(env, ctx, tc, e, e_type, symm_cs, g); if (symm) { try { return try_alternative(symm->first, symm->second, symm_cs, conservative); } catch (exception &) {} } // 3. subst pr (eq.refl lhs) constraint_seq subst_cs = new_cs; if (auto subst = apply_subst(env, ctx, tc, e, e_type, meta_type, subst_cs, g)) { try { return try_alternative(subst->first, subst->second, subst_cs, conservative); } catch (exception&) {} } // 4. subst (eq.symm pr) (eq.refl lhs) if (symm) { constraint_seq subst_cs = symm_cs; if (auto subst = apply_subst(env, ctx, tc, symm->first, symm->second, meta_type, subst_cs, g)) { try { return try_alternative(subst->first, subst->second, subst_cs, conservative); } catch (exception&) {} } } } { // Try the following possible insterpretations using the default unification procedure. // 1. pr bool conservative = false; std::unique_ptr<throwable> saved_ex; try { return try_alternative(e, e_type, new_cs, conservative); } catch (exception & ex) { saved_ex.reset(ex.clone()); } // 2. eq.symm pr constraint_seq symm_cs = new_cs; auto symm = apply_symmetry(env, ctx, tc, e, e_type, symm_cs, g); if (symm) { try { return try_alternative(symm->first, symm->second, symm_cs, conservative); } catch (exception &) {} } // We use the exception for the first alternative as the error message saved_ex->rethrow(); lean_unreachable(); } } }; bool owner = false; return mk_choice_cnstr(m, choice_fn, to_delay_factor(cnstr_group::Epilogue), owner, j); }