feat(library/tactic): add append, interleave and par tacticals
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
parent
df96068caa
commit
8bece1b53d
3 changed files with 123 additions and 0 deletions
|
@ -149,4 +149,68 @@ tactic try_for(tactic t, unsigned ms, unsigned check_ms) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tactic append(tactic t1, tactic t2) {
|
||||||
|
return mk_tactic([=](environment const & env, io_state const & io, proof_state const & s) -> proof_state_seq {
|
||||||
|
tactic _t1(t1);
|
||||||
|
tactic _t2(t2);
|
||||||
|
return append(_t1(env, io, s), _t2(env, io, s));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
tactic interleave(tactic t1, tactic t2) {
|
||||||
|
return mk_tactic([=](environment const & env, io_state const & io, proof_state const & s) -> proof_state_seq {
|
||||||
|
tactic _t1(t1);
|
||||||
|
tactic _t2(t2);
|
||||||
|
return interleave(_t1(env, io, s), _t2(env, io, s));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
tactic par(tactic t1, tactic t2, unsigned check_ms) {
|
||||||
|
return mk_tactic([=](environment const & env, io_state const & io, proof_state const & s) -> proof_state_seq {
|
||||||
|
tactic _t1(t1);
|
||||||
|
tactic _t2(t2);
|
||||||
|
proof_state_seq r1;
|
||||||
|
proof_state_seq r2;
|
||||||
|
std::atomic<bool> done1(false);
|
||||||
|
std::atomic<bool> done2(false);
|
||||||
|
interruptible_thread th1([&]() {
|
||||||
|
try {
|
||||||
|
r1 = _t1(env, io, s);
|
||||||
|
} catch (...) {
|
||||||
|
r1 = proof_state_seq();
|
||||||
|
}
|
||||||
|
done1 = true;
|
||||||
|
});
|
||||||
|
interruptible_thread th2([&]() {
|
||||||
|
try {
|
||||||
|
r2 = _t2(env, io, s);
|
||||||
|
} catch (...) {
|
||||||
|
r2 = proof_state_seq();
|
||||||
|
}
|
||||||
|
done2 = true;
|
||||||
|
});
|
||||||
|
try {
|
||||||
|
std::chrono::milliseconds small(check_ms);
|
||||||
|
while (!done1 && !done2) {
|
||||||
|
check_interrupted();
|
||||||
|
std::this_thread::sleep_for(small);
|
||||||
|
}
|
||||||
|
th1.request_interrupt();
|
||||||
|
th2.request_interrupt();
|
||||||
|
th1.join();
|
||||||
|
th2.join();
|
||||||
|
if (r1)
|
||||||
|
return r1;
|
||||||
|
else
|
||||||
|
return r2;
|
||||||
|
} catch (...) {
|
||||||
|
th1.request_interrupt();
|
||||||
|
th2.request_interrupt();
|
||||||
|
th1.join();
|
||||||
|
th2.join();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,15 +53,73 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Create a tactic using the given functor.
|
||||||
|
The functor must contain the operator:
|
||||||
|
|
||||||
|
<code>
|
||||||
|
proof_state_seq operator()(environment const & env, io_state const & io, proof_state const & s)
|
||||||
|
</code>
|
||||||
|
*/
|
||||||
template<typename F>
|
template<typename F>
|
||||||
tactic mk_tactic(F && f) { return tactic(new simple_tactic_cell<F>(std::forward<F>(f))); }
|
tactic mk_tactic(F && f) { return tactic(new simple_tactic_cell<F>(std::forward<F>(f))); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Return a "do nothing" tactic (aka skip).
|
||||||
|
*/
|
||||||
tactic id_tactic();
|
tactic id_tactic();
|
||||||
|
/**
|
||||||
|
\brief Return a tactic the always fails.
|
||||||
|
*/
|
||||||
tactic fail_tactic();
|
tactic fail_tactic();
|
||||||
|
/**
|
||||||
|
\brief Return a tactic that fails if there are unsolved goals.
|
||||||
|
*/
|
||||||
tactic now_tactic();
|
tactic now_tactic();
|
||||||
|
/**
|
||||||
|
\brief Return a tactic that solves any goal of the form <tt>..., H : A, ... |- A</tt>.
|
||||||
|
*/
|
||||||
tactic assumption_tactic();
|
tactic assumption_tactic();
|
||||||
|
/**
|
||||||
|
\brief Return a tactic that performs \c t1 followed by \c t2.
|
||||||
|
*/
|
||||||
tactic then(tactic t1, tactic t2);
|
tactic then(tactic t1, tactic t2);
|
||||||
|
/**
|
||||||
|
\brief Return a tactic that applies \c t1, and if \c t1 returns the empty sequence of states,
|
||||||
|
then applies \c t2.
|
||||||
|
*/
|
||||||
tactic orelse(tactic t1, tactic t2);
|
tactic orelse(tactic t1, tactic t2);
|
||||||
|
/**
|
||||||
|
\brief Return a tactic that tries the tactic \c t for at most \c ms milliseconds.
|
||||||
|
If the tactic does not terminate in \c ms milliseconds, then the empty
|
||||||
|
sequence is returned.
|
||||||
|
|
||||||
|
\remark the tactic \c t is executed in a separate execution thread.
|
||||||
|
|
||||||
|
\remark \c check_ms is how often the main thread checks whether the child
|
||||||
|
thread finished.
|
||||||
|
*/
|
||||||
tactic try_for(tactic t, unsigned ms, unsigned check_ms = 1);
|
tactic try_for(tactic t, unsigned ms, unsigned check_ms = 1);
|
||||||
|
/**
|
||||||
|
\brief Execute both tactics and and combines their results.
|
||||||
|
The results produced by tactic \c t1 are listed before the ones
|
||||||
|
from tactic \c t2.
|
||||||
|
*/
|
||||||
|
tactic append(tactic t1, tactic t2);
|
||||||
|
/**
|
||||||
|
\brief Execute both tactics and and combines their results.
|
||||||
|
The results produced by tactics \c t1 and \c t2 are interleaved
|
||||||
|
to guarantee fairness.
|
||||||
|
*/
|
||||||
|
tactic interleave(tactic t1, tactic t2);
|
||||||
|
/**
|
||||||
|
\brief Return a tactic that executs \c t1 and \c t2 in parallel.
|
||||||
|
It returns the sequence produced by the first to terminate.
|
||||||
|
|
||||||
|
\remark \c check_ms is how often the main thread checks whether the children
|
||||||
|
threads finished.
|
||||||
|
*/
|
||||||
|
tactic par(tactic t1, tactic t2, unsigned check_ms = 1);
|
||||||
|
|
||||||
tactic repeat(tactic t1);
|
tactic repeat(tactic t1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,6 +83,7 @@ static void tst1() {
|
||||||
set_tactic(&flag1)),
|
set_tactic(&flag1)),
|
||||||
env, io, ctx, q);
|
env, io, ctx, q);
|
||||||
lean_assert(flag1);
|
lean_assert(flag1);
|
||||||
|
std::cout << "proof 2: " << par(loop_tactic(), par(loop_tactic(), t)).solve(env, io, ctx, q) << "\n";
|
||||||
#endif
|
#endif
|
||||||
std::cout << "done\n";
|
std::cout << "done\n";
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue