refactor(util/lazy_list): polish lazy_list API
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
parent
9da95dc6e6
commit
40a2f0a588
5 changed files with 82 additions and 24 deletions
|
@ -61,7 +61,7 @@ tactic now_tactic() {
|
|||
|
||||
tactic trace_tactic(std::string const & msg) {
|
||||
return mk_tactic([=](environment const &, io_state const & io, proof_state const & s) -> proof_state_seq {
|
||||
return proof_state_seq([=]() {
|
||||
return mk_proof_state_seq([=]() {
|
||||
io.get_diagnostic_channel() << msg << "\n";
|
||||
io.get_diagnostic_channel().get_stream().flush();
|
||||
return some(mk_pair(s, proof_state_seq()));
|
||||
|
|
|
@ -65,6 +65,11 @@ public:
|
|||
template<typename F>
|
||||
tactic mk_tactic(F && f) { return tactic(new simple_tactic_cell<F>(std::forward<F>(f))); }
|
||||
|
||||
template<typename F>
|
||||
inline proof_state_seq mk_proof_state_seq(F && f) {
|
||||
return mk_lazy_list<proof_state>(std::forward<F>(f));
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Create a tactic using the given functor.
|
||||
|
||||
|
@ -78,21 +83,21 @@ template<typename F>
|
|||
tactic mk_simple_tactic(F && f) {
|
||||
return
|
||||
mk_tactic([=](environment const & env, io_state const & io, proof_state const & s) {
|
||||
return proof_state_seq([=]() { return some(mk_pair(f(env, io, s), proof_state_seq())); });
|
||||
return mk_proof_state_seq([=]() { return some(mk_pair(f(env, io, s), proof_state_seq())); });
|
||||
});
|
||||
}
|
||||
|
||||
inline proof_state_seq to_proof_state_seq(proof_state const & s) {
|
||||
return proof_state_seq([=]() { return some(mk_pair(s, proof_state_seq())); });
|
||||
return mk_proof_state_seq([=]() { return some(mk_pair(s, proof_state_seq())); });
|
||||
}
|
||||
|
||||
inline proof_state_seq to_proof_state_seq(proof_state_seq::maybe_pair const & p) {
|
||||
lean_assert(p);
|
||||
return proof_state_seq([=]() { return some(mk_pair(p->first, p->second)); });
|
||||
return mk_proof_state_seq([=]() { return some(mk_pair(p->first, p->second)); });
|
||||
}
|
||||
|
||||
inline proof_state_seq to_proof_state_seq(proof_state const & s, proof_state_seq const & t) {
|
||||
return proof_state_seq([=]() { return some(mk_pair(s, t)); });
|
||||
return mk_proof_state_seq([=]() { return some(mk_pair(s, t)); });
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -17,18 +17,18 @@ Author: Leonardo de Moura
|
|||
using namespace lean;
|
||||
|
||||
lazy_list<int> seq(int s) {
|
||||
return lazy_list<int>([=]() { return some(mk_pair(s, seq(s + 1))); });
|
||||
return mk_lazy_list<int>([=]() { return some(mk_pair(s, seq(s + 1))); });
|
||||
}
|
||||
|
||||
lazy_list<int> from(int begin, int step, int end) {
|
||||
if (begin > end)
|
||||
return lazy_list<int>();
|
||||
else
|
||||
return lazy_list<int>([=]() { return some(mk_pair(begin, from(begin + step, step, end))); });
|
||||
return mk_lazy_list<int>([=]() { return some(mk_pair(begin, from(begin + step, step, end))); });
|
||||
}
|
||||
|
||||
lazy_list<mpz> fact_list_core(mpz i, mpz n) {
|
||||
return lazy_list<mpz>([=]() { return some(mk_pair(n, fact_list_core(i+1, n*(i+1)))); });
|
||||
return mk_lazy_list<mpz>([=]() { return some(mk_pair(n, fact_list_core(i+1, n*(i+1)))); });
|
||||
}
|
||||
|
||||
lazy_list<mpz> fact_list() {
|
||||
|
@ -52,7 +52,7 @@ lazy_list<int> mk_simple3() {
|
|||
}
|
||||
|
||||
lazy_list<int> loop() {
|
||||
return lazy_list<int>([=]() {
|
||||
return mk_lazy_list<int>([=]() {
|
||||
while (true) {
|
||||
check_interrupted();
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ void display(lazy_list<T> const & l) {
|
|||
}
|
||||
|
||||
static void tst1() {
|
||||
lazy_list<int> l([]() { return some(mk_pair(10, lazy_list<int>())); });
|
||||
lazy_list<int> l = mk_lazy_list<int>([]() { return some(mk_pair(10, lazy_list<int>())); });
|
||||
lazy_list<int> empty;
|
||||
lean_assert(l.pull()->first == 10);
|
||||
lean_assert(!empty.pull());
|
||||
|
@ -101,7 +101,23 @@ static void tst1() {
|
|||
#endif
|
||||
}
|
||||
|
||||
void tst2() {
|
||||
lazy_list<int> l(10);
|
||||
lean_assert(l.pull()->first == 10);
|
||||
lean_assert(!l.pull()->second.pull());
|
||||
display(l);
|
||||
lazy_list<int> l2(20, l);
|
||||
int i = 0;
|
||||
for_each(l2, [&](int v) {
|
||||
lean_assert(i != 0 || v == 20);
|
||||
lean_assert(i != 1 || v == 10);
|
||||
i++;
|
||||
});
|
||||
lean_assert(i == 2);
|
||||
}
|
||||
|
||||
int main() {
|
||||
tst1();
|
||||
return 0;
|
||||
tst2();
|
||||
return has_violations() ? 1 : 0;
|
||||
}
|
||||
|
|
|
@ -37,12 +37,37 @@ private:
|
|||
virtual maybe_pair pull() const { return m_f(); }
|
||||
};
|
||||
|
||||
class cell_singleton : public cell_base {
|
||||
T m_val;
|
||||
public:
|
||||
cell_singleton(T const & v):cell_base(), m_val(v) {}
|
||||
cell_singleton(T && v):cell_base(), m_val(std::move(v)) {}
|
||||
virtual ~cell_singleton() {}
|
||||
virtual maybe_pair pull() const {
|
||||
lazy_list empty;
|
||||
return maybe_pair(m_val, empty);
|
||||
}
|
||||
};
|
||||
|
||||
class cell_pair : public cell_base {
|
||||
T m_head;
|
||||
lazy_list m_tail;
|
||||
public:
|
||||
cell_pair(T const & h, lazy_list const & t):cell_base(), m_head(h), m_tail(t) {}
|
||||
virtual ~cell_pair() {}
|
||||
virtual maybe_pair pull() const {
|
||||
return maybe_pair(m_head, m_tail);
|
||||
}
|
||||
};
|
||||
|
||||
cell_base * m_ptr;
|
||||
public:
|
||||
lazy_list():m_ptr(nullptr) {}
|
||||
lazy_list(lazy_list const & s):m_ptr(s.m_ptr) { if (m_ptr) m_ptr->inc_ref(); }
|
||||
lazy_list(lazy_list && s):m_ptr(s.m_ptr) { s.m_ptr = nullptr; }
|
||||
template<typename F> explicit lazy_list(F && f):m_ptr(new cell<F>(std::forward<F>(f))) { m_ptr->inc_ref(); }
|
||||
lazy_list(T const & v):m_ptr(new cell_singleton(v)) { m_ptr->inc_ref(); }
|
||||
lazy_list(T && v):m_ptr(new cell_singleton(std::forward<T>(v))) { m_ptr->inc_ref(); }
|
||||
lazy_list(T const & h, lazy_list const & t):m_ptr(new cell_pair(h, t)) { m_ptr->inc_ref(); }
|
||||
~lazy_list() { if (m_ptr) m_ptr->dec_ref(); }
|
||||
|
||||
lazy_list & operator=(lazy_list const & s) { LEAN_COPY_REF(lazy_list, s); }
|
||||
|
@ -57,5 +82,17 @@ public:
|
|||
|
||||
friend T head(lazy_list const & l) { return l.pull()->first; }
|
||||
friend lazy_list tail(lazy_list const & l) { return l.pull()->second; }
|
||||
|
||||
template<typename F>
|
||||
static lazy_list mk_lazy_list_core(F && f) {
|
||||
lazy_list r;
|
||||
r.m_ptr = new cell<F>(std::forward<F>(f));
|
||||
r.m_ptr->inc_ref();
|
||||
return r;
|
||||
}
|
||||
};
|
||||
template<typename T, typename F>
|
||||
lazy_list<T> mk_lazy_list(F && f) {
|
||||
return lazy_list<T>::mk_lazy_list_core(std::forward<F>(f));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ lazy_list<T> take(unsigned sz, lazy_list<T> const & l) {
|
|||
if (sz == 0) {
|
||||
return lazy_list<T>();
|
||||
} else {
|
||||
return lazy_list<T>([=]() {
|
||||
return mk_lazy_list<T>([=]() {
|
||||
auto p = l.pull();
|
||||
if (p)
|
||||
return some(mk_pair(p->first, take(sz - 1, p->second)));
|
||||
|
@ -49,7 +49,7 @@ lazy_list<T> take(unsigned sz, lazy_list<T> const & l) {
|
|||
template<typename T>
|
||||
lazy_list<T> to_lazy(list<T> l) {
|
||||
if (l) {
|
||||
return lazy_list<T>([=]() {
|
||||
return mk_lazy_list<T>([=]() {
|
||||
return some(mk_pair(head(l), to_lazy(tail(l))));
|
||||
});
|
||||
} else {
|
||||
|
@ -62,7 +62,7 @@ lazy_list<T> to_lazy(list<T> l) {
|
|||
*/
|
||||
template<typename T>
|
||||
lazy_list<T> append(lazy_list<T> const & l1, lazy_list<T> const & l2) {
|
||||
return lazy_list<T>([=]() {
|
||||
return mk_lazy_list<T>([=]() {
|
||||
auto p = l1.pull();
|
||||
if (!p) {
|
||||
check_interrupted();
|
||||
|
@ -78,13 +78,13 @@ lazy_list<T> append(lazy_list<T> const & l1, lazy_list<T> const & l2) {
|
|||
*/
|
||||
template<typename T>
|
||||
lazy_list<T> orelse(lazy_list<T> const & l1, lazy_list<T> const & l2) {
|
||||
return lazy_list<T>([=]() {
|
||||
return mk_lazy_list<T>([=]() {
|
||||
auto p = l1.pull();
|
||||
if (!p) {
|
||||
check_interrupted();
|
||||
return l2.pull();
|
||||
} else {
|
||||
return some(mk_pair(p->first, orelse(p->second, lazy_list<T>())));
|
||||
return p;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -95,7 +95,7 @@ lazy_list<T> orelse(lazy_list<T> const & l1, lazy_list<T> const & l2) {
|
|||
*/
|
||||
template<typename T>
|
||||
lazy_list<T> interleave(lazy_list<T> const & l1, lazy_list<T> const & l2) {
|
||||
return lazy_list<T>([=]() {
|
||||
return mk_lazy_list<T>([=]() {
|
||||
auto p = l1.pull();
|
||||
if (!p) {
|
||||
check_interrupted();
|
||||
|
@ -111,7 +111,7 @@ lazy_list<T> interleave(lazy_list<T> const & l1, lazy_list<T> const & l2) {
|
|||
*/
|
||||
template<typename T, typename F>
|
||||
lazy_list<T> map(lazy_list<T> const & l, F && f) {
|
||||
return lazy_list<T>([=]() {
|
||||
return mk_lazy_list<T>([=]() {
|
||||
auto p = l.pull();
|
||||
if (!p)
|
||||
return p;
|
||||
|
@ -129,12 +129,12 @@ lazy_list<T> map(lazy_list<T> const & l, F && f) {
|
|||
*/
|
||||
template<typename T, typename P>
|
||||
lazy_list<T> filter(lazy_list<T> const & l, P && pred) {
|
||||
return lazy_list<T>([=]() {
|
||||
return mk_lazy_list<T>([=]() {
|
||||
auto p = l.pull();
|
||||
if (!p) {
|
||||
return p;
|
||||
} else if (pred(p->first)) {
|
||||
return some(mk_pair(p->first, p->second));
|
||||
return p;
|
||||
} else {
|
||||
check_interrupted();
|
||||
return filter(p->second, pred).pull();
|
||||
|
@ -147,7 +147,7 @@ lazy_list<T> filter(lazy_list<T> const & l, P && pred) {
|
|||
*/
|
||||
template<typename T, typename F>
|
||||
lazy_list<T> map_append_aux(lazy_list<T> const & h, lazy_list<T> const & l, F && f) {
|
||||
return lazy_list<T>([=]() {
|
||||
return mk_lazy_list<T>([=]() {
|
||||
auto p1 = h.pull();
|
||||
if (p1) {
|
||||
return some(mk_pair(p1->first, map_append_aux(p1->second, l, f)));
|
||||
|
@ -188,7 +188,7 @@ template<typename T>
|
|||
lazy_list<T> timeout(lazy_list<T> const & l, unsigned ms, unsigned check_ms = g_small_sleep) {
|
||||
if (check_ms == 0)
|
||||
check_ms = 1;
|
||||
return lazy_list<T>([=]() {
|
||||
return mk_lazy_list<T>([=]() {
|
||||
typename lazy_list<T>::maybe_pair r;
|
||||
std::atomic<bool> done(false);
|
||||
interruptible_thread th([&]() {
|
||||
|
@ -231,7 +231,7 @@ lazy_list<T> timeout(lazy_list<T> const & l, unsigned ms, unsigned check_ms = g_
|
|||
*/
|
||||
template<typename T>
|
||||
lazy_list<T> par(lazy_list<T> const & l1, lazy_list<T> const & l2, unsigned check_ms = g_small_sleep) {
|
||||
return lazy_list<T>([=]() {
|
||||
return mk_lazy_list<T>([=]() {
|
||||
typename lazy_list<T>::maybe_pair r1;
|
||||
typename lazy_list<T>::maybe_pair r2;
|
||||
std::atomic<bool> done1(false);
|
||||
|
|
Loading…
Reference in a new issue