2013-11-21 01:02:41 +00:00
|
|
|
/*
|
|
|
|
Copyright (c) 2013 Microsoft Corporation. All rights reserved.
|
|
|
|
Released under Apache 2.0 license as described in the file LICENSE.
|
|
|
|
|
|
|
|
Author: Leonardo de Moura
|
|
|
|
*/
|
2013-11-22 02:39:33 +00:00
|
|
|
#include <string>
|
2013-11-21 01:02:41 +00:00
|
|
|
#include "util/test.h"
|
2013-11-22 02:39:33 +00:00
|
|
|
#include "util/interrupt.h"
|
2013-11-21 23:31:55 +00:00
|
|
|
#include "kernel/builtin.h"
|
2013-11-25 05:00:38 +00:00
|
|
|
#include "kernel/kernel_exception.h"
|
2013-11-21 01:02:41 +00:00
|
|
|
#include "library/tactic/goal.h"
|
|
|
|
#include "library/tactic/proof_builder.h"
|
|
|
|
#include "library/tactic/proof_state.h"
|
|
|
|
#include "library/tactic/tactic.h"
|
2013-12-05 13:03:18 +00:00
|
|
|
#include "library/tactic/boolean_tactics.h"
|
2013-12-29 10:44:49 +00:00
|
|
|
#include "frontends/lean/frontend.h"
|
2013-11-21 01:02:41 +00:00
|
|
|
using namespace lean;
|
|
|
|
|
2013-11-22 02:39:33 +00:00
|
|
|
tactic loop_tactic() {
|
2013-12-13 00:33:31 +00:00
|
|
|
return mk_tactic1([=](ro_environment const &, io_state const &, proof_state const & s) -> proof_state {
|
2013-11-22 02:39:33 +00:00
|
|
|
while (true) {
|
|
|
|
check_interrupted();
|
|
|
|
}
|
2013-11-24 01:03:59 +00:00
|
|
|
return s;
|
2013-11-22 02:39:33 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2013-12-09 22:56:48 +00:00
|
|
|
tactic set_tactic(atomic<bool> * flag) {
|
2013-12-13 00:33:31 +00:00
|
|
|
return mk_tactic1([=](ro_environment const &, io_state const &, proof_state const & s) -> proof_state {
|
2013-11-22 02:39:33 +00:00
|
|
|
*flag = true;
|
2013-11-24 01:03:59 +00:00
|
|
|
return s;
|
2013-11-22 02:39:33 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2013-11-25 00:29:04 +00:00
|
|
|
tactic show_opts_tactic() {
|
2013-12-13 00:33:31 +00:00
|
|
|
return mk_tactic1([=](ro_environment const &, io_state const & io, proof_state const & s) -> proof_state {
|
2013-11-25 00:29:04 +00:00
|
|
|
io.get_diagnostic_channel() << "options: " << io.get_options() << "\n";
|
|
|
|
io.get_diagnostic_channel().get_stream().flush();
|
|
|
|
return s;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2013-12-13 00:33:31 +00:00
|
|
|
static void check_failure(tactic t, ro_environment const & env, io_state const & io, context const & ctx, expr const & ty) {
|
2013-11-25 21:04:09 +00:00
|
|
|
solve_result r(t.solve(env, io, ctx, ty));
|
|
|
|
lean_assert(r.kind() == solve_result_kind::Failure);
|
2013-11-22 02:39:33 +00:00
|
|
|
}
|
|
|
|
|
2013-11-21 23:31:55 +00:00
|
|
|
static void tst1() {
|
|
|
|
environment env;
|
2013-11-22 00:44:31 +00:00
|
|
|
io_state io(options(), mk_simple_formatter());
|
2013-12-29 10:44:49 +00:00
|
|
|
init_frontend(env);
|
2013-12-13 00:33:31 +00:00
|
|
|
env->add_var("p", Bool);
|
|
|
|
env->add_var("q", Bool);
|
2013-11-21 23:31:55 +00:00
|
|
|
expr p = Const("p");
|
|
|
|
expr q = Const("q");
|
|
|
|
context ctx;
|
|
|
|
ctx = extend(ctx, "H1", p);
|
|
|
|
ctx = extend(ctx, "H2", q);
|
2013-11-22 00:44:31 +00:00
|
|
|
proof_state s = to_proof_state(env, ctx, p);
|
|
|
|
std::cout << s.pp(mk_simple_formatter(), options()) << "\n";
|
|
|
|
tactic t = then(assumption_tactic(), now_tactic());
|
2013-11-25 21:04:09 +00:00
|
|
|
std::cout << "proof 1: " << t.solve(env, io, s).get_proof() << "\n";
|
|
|
|
std::cout << "proof 2: " << t.solve(env, io, ctx, q).get_proof() << "\n";
|
2013-11-22 02:39:33 +00:00
|
|
|
check_failure(now_tactic(), env, io, ctx, q);
|
2013-11-25 21:04:09 +00:00
|
|
|
std::cout << "proof 2: " << orelse(fail_tactic(), t).solve(env, io, ctx, q).get_proof() << "\n";
|
2013-11-23 00:39:25 +00:00
|
|
|
|
2013-12-09 22:56:48 +00:00
|
|
|
#if !defined(__APPLE__) && defined(LEAN_MULTI_THREAD)
|
2013-11-22 02:39:33 +00:00
|
|
|
check_failure(try_for(loop_tactic(), 100), env, io, ctx, q);
|
2013-11-25 21:04:09 +00:00
|
|
|
std::cout << "proof 1: " << try_for(t, 10000).solve(env, io, s).get_proof() << "\n";
|
2013-11-22 02:39:33 +00:00
|
|
|
check_failure(try_for(orelse(try_for(loop_tactic(), 10000),
|
2013-11-23 23:33:25 +00:00
|
|
|
trace_tactic(std::string("hello world"))),
|
2013-11-22 02:39:33 +00:00
|
|
|
100),
|
|
|
|
env, io, ctx, q);
|
2013-12-09 22:56:48 +00:00
|
|
|
atomic<bool> flag1(false);
|
2013-11-22 02:39:33 +00:00
|
|
|
check_failure(try_for(orelse(try_for(loop_tactic(), 10000),
|
|
|
|
set_tactic(&flag1)),
|
|
|
|
100),
|
|
|
|
env, io, ctx, q);
|
|
|
|
lean_assert(!flag1);
|
2013-11-24 01:03:59 +00:00
|
|
|
std::cout << "Before nested try_for...\n";
|
2013-11-22 02:39:33 +00:00
|
|
|
check_failure(orelse(try_for(try_for(loop_tactic(), 10000), 100),
|
|
|
|
set_tactic(&flag1)),
|
|
|
|
env, io, ctx, q);
|
|
|
|
lean_assert(flag1);
|
2013-11-24 01:03:59 +00:00
|
|
|
std::cout << "Before parallel 3 parallel tactics...\n";
|
2013-11-25 21:04:09 +00:00
|
|
|
std::cout << "proof 2: " << par(loop_tactic(), par(loop_tactic(), t)).solve(env, io, ctx, q).get_proof() << "\n";
|
2013-11-22 02:39:33 +00:00
|
|
|
#endif
|
2013-11-24 01:03:59 +00:00
|
|
|
std::cout << "Before hello1 and 2...\n";
|
2013-11-23 23:33:25 +00:00
|
|
|
std::cout << "proof 2: " << orelse(then(repeat_at_most(append(trace_tactic("hello1"), trace_tactic("hello2")), 5), fail_tactic()),
|
2013-11-25 21:04:09 +00:00
|
|
|
t).solve(env, io, ctx, q).get_proof() << "\n";
|
2013-11-23 01:05:18 +00:00
|
|
|
std::cout << "------------------\n";
|
2013-11-23 23:33:25 +00:00
|
|
|
std::cout << "proof 2: " << ((trace_tactic("hello1.1") + trace_tactic("hello1.2") + trace_tactic("hello1.3") + trace_tactic("hello1.4")) <<
|
|
|
|
(trace_tactic("hello2.1") + trace_tactic("hello2.2")) <<
|
|
|
|
(trace_tactic("hello3.1") || trace_tactic("hello3.2")) <<
|
2013-11-25 21:04:09 +00:00
|
|
|
assumption_tactic()).solve(env, io, ctx, q).get_proof() << "\n";
|
2013-11-23 23:33:25 +00:00
|
|
|
std::cout << "------------------\n";
|
2013-12-13 00:33:31 +00:00
|
|
|
std::cout << "proof 2: " << then(cond([](ro_environment const &, io_state const &, proof_state const &) { return true; },
|
2013-11-24 20:04:32 +00:00
|
|
|
trace_tactic("then branch.1") + trace_tactic("then branch.2"),
|
|
|
|
trace_tactic("else branch")),
|
2013-11-25 21:04:09 +00:00
|
|
|
t).solve(env, io, ctx, q).get_proof() << "\n";
|
2013-11-24 20:04:32 +00:00
|
|
|
|
2013-12-13 00:33:31 +00:00
|
|
|
std::cout << "proof 2: " << then(when([](ro_environment const &, io_state const &, proof_state const &) { return true; },
|
2013-11-24 20:04:32 +00:00
|
|
|
trace_tactic("when branch.1") + trace_tactic("when branch.2")),
|
2013-11-25 21:04:09 +00:00
|
|
|
t).solve(env, io, ctx, q).get_proof() << "\n";
|
2013-11-25 00:29:04 +00:00
|
|
|
std::cout << "------------------\n";
|
|
|
|
std::cout << "proof 2: " << (suppress_trace(trace_tactic("msg1") << trace_tactic("msg2")) <<
|
2013-11-25 21:04:09 +00:00
|
|
|
trace_tactic("msg3") << t).solve(env, io, ctx, q).get_proof() << "\n";
|
2013-11-25 00:29:04 +00:00
|
|
|
std::cout << "------------------\n";
|
|
|
|
std::cout << "proof 2: " << (show_opts_tactic() << using_params(show_opts_tactic(), options(name({"pp", "colors"}), true)) <<
|
2013-11-25 21:04:09 +00:00
|
|
|
show_opts_tactic() << t).solve(env, io, ctx, q).get_proof() << "\n";
|
2013-11-22 02:39:33 +00:00
|
|
|
std::cout << "done\n";
|
2013-11-21 23:31:55 +00:00
|
|
|
}
|
|
|
|
|
2013-11-25 00:29:04 +00:00
|
|
|
static void tst2() {
|
|
|
|
environment env;
|
|
|
|
io_state io(options(), mk_simple_formatter());
|
2013-12-29 10:44:49 +00:00
|
|
|
init_frontend(env);
|
2013-12-13 00:33:31 +00:00
|
|
|
env->add_var("p", Bool);
|
|
|
|
env->add_var("q", Bool);
|
|
|
|
env->add_var("r", Bool);
|
|
|
|
env->add_var("s", Bool);
|
2013-11-25 00:29:04 +00:00
|
|
|
expr p = Const("p");
|
|
|
|
expr q = Const("q");
|
2013-11-25 05:00:38 +00:00
|
|
|
expr r = Const("r");
|
|
|
|
expr s = Const("s");
|
2013-11-25 00:29:04 +00:00
|
|
|
context ctx;
|
|
|
|
ctx = extend(ctx, "H1", p);
|
|
|
|
ctx = extend(ctx, "H2", q);
|
2013-11-25 21:04:09 +00:00
|
|
|
std::cout << "proof: " << (repeat(conj_tactic()) << assumption_tactic()).solve(env, io, ctx, And(And(p, q), And(p, p))).get_proof()
|
2013-11-25 00:29:04 +00:00
|
|
|
<< "\n";
|
2013-11-25 00:44:02 +00:00
|
|
|
std::cout << "-------------\n";
|
2013-11-25 00:29:04 +00:00
|
|
|
// Theorem to be proved
|
2013-11-25 05:00:38 +00:00
|
|
|
expr F = Implies(And(p, And(r, s)), Implies(q, And(And(p, q), And(r, p))));
|
2013-11-25 00:29:04 +00:00
|
|
|
// Tactic
|
2013-11-25 21:04:09 +00:00
|
|
|
tactic T = append(id_tactic() << assumption_tactic(),
|
|
|
|
repeat(conj_tactic() || conj_hyp_tactic() || imp_tactic()) << trace_state_tactic() << assumption_tactic());
|
2013-11-25 00:29:04 +00:00
|
|
|
// Generate proof using tactic
|
2013-11-25 21:04:09 +00:00
|
|
|
expr pr = T.solve(env, io, context(), F).get_proof();
|
2013-11-25 00:29:04 +00:00
|
|
|
// Print proof
|
|
|
|
std::cout << pr << "\n";
|
|
|
|
// Check whether the proof is correct or not.
|
2013-12-22 19:51:38 +00:00
|
|
|
std::cout << env->type_check(pr) << "\n";
|
2013-11-25 00:29:04 +00:00
|
|
|
}
|
|
|
|
|
2013-11-21 01:02:41 +00:00
|
|
|
int main() {
|
2013-12-01 20:42:32 +00:00
|
|
|
save_stack_info();
|
2013-11-21 23:31:55 +00:00
|
|
|
tst1();
|
2013-11-25 00:29:04 +00:00
|
|
|
tst2();
|
2013-11-21 01:02:41 +00:00
|
|
|
return has_violations() ? 1 : 0;
|
|
|
|
}
|