|
6 | 6 |
|
7 | 7 | using namespace std;
|
8 | 8 |
|
| 9 | +static const RegisteredProver idi_rp = LibraryToolbox::register_prover({}, "|- ( ph -> ph )"); |
| 10 | +static const RegisteredProver concl_rp = LibraryToolbox::register_prover({"|- ( ps -> ch )"}, "|- ( ph -> ( ps -> ch ) )"); |
9 | 11 | struct CNFCallbackImpl : public CNFCallback {
|
10 |
| - void prove_clause(size_t idx, const Clause &context) {} |
11 |
| - void prove_not_or_elim(size_t idx, const Clause &context) {} |
12 |
| - void prove_imp_intr(const Clause &clause, const Clause &context) {} |
13 |
| - void prove_unit_res(const Clause &clause, size_t unsolved_idx, const Clause &context) {} |
14 |
| - void prove_absurdum(const Literal &lit, const Clause &context) {} |
| 12 | + void prove_clause(size_t idx, const Clause &context) { |
| 13 | + pwff concl = this->clause_to_pwff(this->orig_clauses.at(idx)); |
| 14 | + pwff loc_ctx = Not::create(this->clause_to_pwff(context)); |
| 15 | + this->prover_stack.push_back(imp_intr_prover(concl, this->orig_provers.at(idx), this->glob_ctx, loc_ctx, this->tb)); |
| 16 | + } |
| 17 | + |
| 18 | + void prove_not_or_elim(size_t idx, const Clause &context) { |
| 19 | + pwff loc_ctx = Not::create(this->clause_to_pwff(context)); |
| 20 | + pwff concl = this->atoms[context[idx].second]; |
| 21 | + if (!context[idx].first) { |
| 22 | + concl = Not::create(concl); |
| 23 | + } |
| 24 | + vector< pwff > orands; |
| 25 | + for (const auto lit : context) { |
| 26 | + pwff new_lit = this->atoms[lit.second]; |
| 27 | + if (!lit.first) { |
| 28 | + new_lit = Not::create(new_lit); |
| 29 | + } |
| 30 | + orands.push_back(new_lit); |
| 31 | + } |
| 32 | + auto p1 = this->tb.build_registered_prover(idi_rp, {{"ph", loc_ctx->get_type_prover(this->tb)}}, {}); |
| 33 | + auto p2 = not_or_elim_prover(orands, idx, context[idx].first, p1, loc_ctx, this->tb); |
| 34 | + auto p3 = this->tb.build_registered_prover(concl_rp, {{"ph", this->glob_ctx->get_type_prover(this->tb)}, {"ps", loc_ctx->get_type_prover(this->tb)}, {"ch", concl->get_type_prover(this->tb)}}, {p2}); |
| 35 | + this->prover_stack.push_back(p3); |
| 36 | + } |
| 37 | + |
| 38 | + void prove_imp_intr(const Clause &clause, const Clause &context) { |
| 39 | + pwff loc_ctx = Not::create(this->clause_to_pwff(context)); |
| 40 | + pwff concl = this->clause_to_pwff(clause); |
| 41 | + auto p1 = this->prover_stack.back(); |
| 42 | + this->prover_stack.pop_back(); |
| 43 | + auto p2 = imp_intr_prover(concl, p1, this->glob_ctx, loc_ctx, this->tb); |
| 44 | + this->prover_stack.push_back(p2); |
| 45 | + } |
| 46 | + |
| 47 | + void prove_unit_res(const Clause &clause, size_t unsolved_idx, const Clause &context) { |
| 48 | + pwff loc_ctx = Not::create(this->clause_to_pwff(context)); |
| 49 | + vector< pwff > orands; |
| 50 | + for (const auto lit : clause) { |
| 51 | + pwff new_lit = this->atoms[lit.second]; |
| 52 | + if (!lit.first) { |
| 53 | + new_lit = Not::create(new_lit); |
| 54 | + } |
| 55 | + orands.push_back(new_lit); |
| 56 | + } |
| 57 | + vector< bool > orand_sign; |
| 58 | + for (size_t i = 0; i < clause.size(); i++) { |
| 59 | + if (i != unsolved_idx) { |
| 60 | + orand_sign.push_back(clause[i].first); |
| 61 | + } |
| 62 | + } |
| 63 | + auto p1 = this->prover_stack[this->prover_stack.size()-clause.size()]; |
| 64 | + vector< Prover< CheckpointedProofEngine > > provers(this->prover_stack.end()-clause.size()+1, this->prover_stack.end()); |
| 65 | + this->prover_stack.resize(this->prover_stack.size()-clause.size()); |
| 66 | + auto p2 = unit_res_prover(orands, orand_sign, unsolved_idx, p1, provers, this->glob_ctx, loc_ctx, this->tb); |
| 67 | + this->prover_stack.push_back(p2); |
| 68 | + } |
15 | 69 |
|
| 70 | + void prove_absurdum(const Literal &lit, const Clause &context) { |
| 71 | + pwff loc_ctx = Not::create(this->clause_to_pwff(context)); |
| 72 | + pwff concl = this->atoms[lit.second]; |
| 73 | + auto neg_prover = this->prover_stack.back(); |
| 74 | + this->prover_stack.pop_back(); |
| 75 | + auto pos_prover = this->prover_stack.back(); |
| 76 | + this->prover_stack.pop_back(); |
| 77 | + auto p = absurdum_prover(concl, pos_prover, neg_prover, this->glob_ctx, loc_ctx, this->tb); |
| 78 | + this->prover_stack.push_back(p); |
| 79 | + } |
| 80 | + |
| 81 | + const LibraryToolbox &tb; |
16 | 82 | std::vector< Clause > orig_clauses;
|
17 | 83 | vector< Prover< CheckpointedProofEngine > > orig_provers;
|
| 84 | + vector< Prover< CheckpointedProofEngine > > prover_stack; |
18 | 85 | pwff glob_ctx;
|
| 86 | + vector< pwff > atoms; |
| 87 | + |
| 88 | + CNFCallbackImpl(const LibraryToolbox &tb) : tb(tb) {} |
| 89 | + |
| 90 | + pwff clause_to_pwff(const Clause &c) { |
| 91 | + if (c.empty()) { |
| 92 | + return False::create(); |
| 93 | + } |
| 94 | + pwff ret = this->atoms[c[0].second]; |
| 95 | + if (!c[0].first) { |
| 96 | + ret = Not::create(ret); |
| 97 | + } |
| 98 | + for (size_t i = 1; i < c.size(); i++) { |
| 99 | + pwff new_lit = this->atoms[c[i].second]; |
| 100 | + if (!c[i].first) { |
| 101 | + new_lit = Not::create(new_lit); |
| 102 | + } |
| 103 | + ret = Or::create(ret, new_lit); |
| 104 | + } |
| 105 | + return ret; |
| 106 | + } |
19 | 107 | };
|
20 | 108 |
|
21 | 109 | std::pair<bool, Prover<CheckpointedProofEngine> > get_sat_prover(pwff wff, const LibraryToolbox &tb)
|
22 | 110 | {
|
23 | 111 | auto glob_ctx = Not::create(wff);
|
24 | 112 | auto tseitin = glob_ctx->get_tseitin_cnf_problem(tb);
|
25 |
| - auto cnf = get<0>(tseitin); |
26 |
| - //auto ts_map = get<1>(tseitin); |
27 |
| - auto provers = get<2>(tseitin); |
| 113 | + auto &cnf = get<0>(tseitin); |
| 114 | + auto &ts_map = get<1>(tseitin); |
| 115 | + auto &provers = get<2>(tseitin); |
28 | 116 | /*cnf.print_dimacs(cout);
|
29 | 117 | for (const auto &x : ts_map) {
|
30 | 118 | cout << (x.second + 1) << " : " << x.first->to_string() << endl;
|
31 | 119 | }*/
|
32 |
| - CNFCallbackImpl cnf_cb; |
| 120 | + CNFCallbackImpl cnf_cb(tb); |
33 | 121 | cnf_cb.orig_clauses = cnf.clauses;
|
34 | 122 | cnf_cb.orig_provers = provers;
|
35 | 123 | cnf_cb.glob_ctx = glob_ctx;
|
| 124 | + for (const auto &x : ts_map) { |
| 125 | + cnf_cb.atoms[x.second] = x.first; |
| 126 | + } |
36 | 127 | cnf.callback = &cnf_cb;
|
37 | 128 | const auto res = cnf.solve();
|
38 | 129 | if (res.first) {
|
39 | 130 | return make_pair(false, null_prover);
|
40 | 131 | } else {
|
41 | 132 | cout << "The formula is UNSATisfiable" << endl;
|
42 | 133 | cout << "Unwinding the proof..." << endl;
|
43 |
| - //res.second(); |
44 |
| - return make_pair(true, null_prover); |
| 134 | + res.second(); |
| 135 | + assert(cnf_cb.prover_stack.size() == 1); |
| 136 | + return make_pair(true, cnf_cb.prover_stack[0]); |
45 | 137 | }
|
46 | 138 | }
|
0 commit comments