/* Copyright (c) 2013 Microsoft Corporation. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Author: Leonardo de Moura */ #pragma once #include #include "util/list.h" #include "util/buffer.h" #include "util/pair.h" namespace lean { /** \brief Copy the values in the list \c l to the buffer \c r. */ template void to_buffer(list const & l, buffer & r) { for (T const & v : l) { r.push_back(v); } } /** \brief Auxiliary function for reverse function. */ template list reverse_aux(list const & l, list const & r) { if (is_nil(l)) return r; else return reverse_aux(cdr(l), cons(car(l), r)); } /** \brief Return the reverse list. */ template list reverse(list const & l) { return reverse_aux(l, list()); } /** \brief Return two lists \c l1 and \c l2 of approximately the same size s.t. append(l1, l2) == l */ template std::pair, list> split(list const & l) { if (is_nil(l)) { return mk_pair(l, l); } else if (is_nil(cdr(l))) { return mk_pair(l, list()); } else { buffer tmp; to_buffer(l, tmp); unsigned mid = tmp.size() / 2; auto beg = tmp.begin(); lean_assert(beg + mid <= tmp.end()); return mk_pair(to_list(beg, beg + mid), to_list(beg + mid, tmp.end())); } } /** \brief Return two lists \c l1 and \c l2 of approximately the same size s.t. append(l1, reverse(l2)) == l */ template std::pair, list> split_reverse_second(list const & l) { if (is_nil(l)) { return mk_pair(l, l); } else if (is_nil(cdr(l))) { return mk_pair(l, list()); } else { buffer tmp; to_buffer(l, tmp); unsigned mid = tmp.size() / 2; auto beg = tmp.begin(); lean_assert(beg + mid <= tmp.end()); return mk_pair(to_list(beg, beg + mid), reverse_to_list(beg+mid, tmp.end())); } } /** \brief Append two lists */ template list append(list const & l1, list const & l2) { buffer tmp; to_buffer(l1, tmp); to_buffer(l2, tmp); return to_list(tmp.begin(), tmp.end()); } }