/* 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 "sexpr.h" #include "debug.h" namespace lean { template void for_each(sexpr const & l, F f) { static_assert(std::is_same::type, void>::value, "foreach: return type of f is not void"); lean_assert(is_list(l)); sexpr const * h = &l; while (!is_nil(*h)) { lean_assert(is_cons(*h)); f(head(*h)); h = &tail(*h); } } template sexpr map(sexpr const & l, F f) { static_assert(std::is_same::type, sexpr>::value, "map: return type of f is not sxpr"); lean_assert(is_list(l)); if (is_nil(l)) { return l; } else { lean_assert(is_cons(l)); return sexpr(f(head(l)), map(tail(l), f)); } } template sexpr filter(sexpr const & l, P p) { static_assert(std::is_same::type, bool>::value, "filter: return type of p is not bool"); lean_assert(is_list(l)); if (is_nil(l)) { return l; } else { lean_assert(is_cons(l)); if (p(head(l))) return sexpr(head(l), filter(tail(l), p)); else return filter(tail(l), p); } } template T foldl(sexpr const & l, T init, BOP op) { static_assert(std::is_same::type, T>::value, "foldl: return type of op is not T"); lean_assert(is_list(l)); if (is_nil(l)) { return init; } else { lean_assert(is_cons(l)); return foldl(tail(l), op(init, head(l)), op); } } template T foldr(sexpr const & l, T init, BOP op) { static_assert(std::is_same::type, T>::value, "foldr: return type of op is not T"); lean_assert(is_list(l)); if (is_nil(l)) { return init; } else { lean_assert(is_cons(l)); return op(head(l), foldr(tail(l), init, op)); } } template bool forall(sexpr const & l, P p) { static_assert(std::is_same::type, bool>::value, "forall: return type of p is not bool"); lean_assert(is_list(l)); if (is_nil(l)) { return true; } else { lean_assert(is_cons(l)); return p(head(l)) && forall(tail(l), p); } } template bool contains(sexpr const & l, P p) { static_assert(std::is_same::type, bool>::value, "contains: return type of p is not bool"); lean_assert(is_list(l)); sexpr const * h = &l; while (!is_nil(*h)) { lean_assert(is_cons(*h)); if (p(head(*h))) return true; h = &tail(*h); } return false; } template bool member(T const & e, sexpr const & l) { lean_assert(is_list(l)); sexpr const * curr = &l; while (!is_nil(*curr)) { if (head(*curr) == e) return true; curr = &tail(*curr); } return false; } template sexpr const * find(sexpr const & l, P p) { static_assert(std::is_same::type, bool>::value, "find: return type of p is not bool"); lean_assert(is_list(l)); sexpr const * h = &l; while (!is_nil(*h)) { lean_assert(is_cons(*h)); if (p(head(*h))) return &(head(*h)); h = &tail(*h); } return nullptr; } sexpr append(sexpr const & l1, sexpr const & l2); sexpr reverse(sexpr const & l); }