diff --git a/src/sexpr/CMakeLists.txt b/src/sexpr/CMakeLists.txt index 48c379a3a..7a965ada1 100644 --- a/src/sexpr/CMakeLists.txt +++ b/src/sexpr/CMakeLists.txt @@ -1,2 +1,2 @@ -add_library(sexpr sexpr.cpp) +add_library(sexpr sexpr.cpp sexpr_funcs.cpp) target_link_libraries(sexpr ${EXTRA_LIBS}) diff --git a/src/sexpr/sexpr.h b/src/sexpr/sexpr.h index 2f740fe83..c5f1ef63a 100644 --- a/src/sexpr/sexpr.h +++ b/src/sexpr/sexpr.h @@ -112,8 +112,14 @@ unsigned length(sexpr const & s); inline unsigned len(sexpr const & s) { return length(s); } bool operator==(sexpr const & a, sexpr const & b); +inline bool operator==(sexpr const & a, int b) { return is_int(a) && to_int(a) == b; } +inline bool operator==(sexpr const & a, double b) { return is_double(a) && to_double(a) == b; } +inline bool operator==(sexpr const & a, std::string const & b) { return is_string(a) && to_string(a) == b; } +inline bool operator==(sexpr const & a, name const & b) { return is_name(a) && to_name(a) == b; } +inline bool operator==(sexpr const & a, mpz const & b) { return is_mpz(a) && to_mpz(a) == b; } +inline bool operator==(sexpr const & a, mpq const & b) { return is_mpq(a) && to_mpq(a) == b; } +template inline bool operator!=(sexpr const & a, T const & b) { return !(a == b); } bool operator<(sexpr const & a, sexpr const & b); -inline bool operator!=(sexpr const & a, sexpr const & b) { return !(a == b); } inline bool operator>(sexpr const & a, sexpr const & b) { return b < a; } inline bool operator<=(sexpr const & a, sexpr const & b) { return !(a > b); } inline bool operator>=(sexpr const & a, sexpr const & b) { return !(a < b); } diff --git a/src/sexpr/sexpr_funcs.cpp b/src/sexpr/sexpr_funcs.cpp new file mode 100644 index 000000000..b739f1ed1 --- /dev/null +++ b/src/sexpr/sexpr_funcs.cpp @@ -0,0 +1,30 @@ +/* +Copyright (c) 2013 Microsoft Corporation. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. + +Author: Leonardo de Moura +*/ +#include "sexpr_funcs.h" + +namespace lean { + +sexpr append(sexpr const & l1, sexpr const & l2) { + lean_assert(is_list(l1)); + if (is_nil(l1)) + return l2; + else + return sexpr(head(l1), append(tail(l1), l2)); +} + +sexpr reverse_it(sexpr const & a, sexpr const & l) { + if (is_nil(l)) + return a; + else + return reverse_it(sexpr(head(l), a), tail(l)); +} + +sexpr reverse(sexpr const & l) { + return reverse_it(nil(), l); +} + +} diff --git a/src/sexpr/sexpr_funcs.h b/src/sexpr/sexpr_funcs.h new file mode 100644 index 000000000..97b3653f5 --- /dev/null +++ b/src/sexpr/sexpr_funcs.h @@ -0,0 +1,68 @@ +/* +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 +sexpr map(sexpr const & l, F f) { + 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) { + 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 +bool contains(sexpr const & l, P p) { + lean_assert(is_list(l)); + if (is_nil(l)) { + return false; + } + else { + lean_assert(is_cons(l)); + return p(head(l)) || contains(tail(l), p); + } +} + +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; +} + +sexpr append(sexpr const & l1, sexpr const & l2); + +sexpr reverse(sexpr const & l); + +} diff --git a/src/tests/sexpr/sexpr.cpp b/src/tests/sexpr/sexpr.cpp index 6b7c61f3e..9d9be8c40 100644 --- a/src/tests/sexpr/sexpr.cpp +++ b/src/tests/sexpr/sexpr.cpp @@ -5,6 +5,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Author: Leonardo de Moura */ #include "sexpr.h" +#include "sexpr_funcs.h" #include "mpq.h" #include "name.h" #include "test.h" @@ -48,6 +49,26 @@ static void tst1() { std::cout << sexpr{ sexpr(1,2), sexpr(2,3), sexpr(0,1) } << "\n"; // list of lists std::cout << sexpr{ sexpr{1,2}, sexpr{2,3}, sexpr{0,1} } << "\n"; + lean_assert(reverse(sexpr{1, 2, 3}) == (sexpr{3, 2, 1})); + sexpr l = map(sexpr{1, 2, 3}, + [](sexpr e) { + return sexpr(to_int(e) + 10); + }); + std::cout << l << std::endl; + lean_assert(l == (sexpr{11, 12, 13})); + { + sexpr l = filter(sexpr{10, -2, 3, -1, 0}, [](sexpr e) { return to_int(e) >= 0; }); + std::cout << l << std::endl; + lean_assert(l == (sexpr{10, 3, 0})); + } + lean_assert(member(3, sexpr{10, 2, 3, 1})); + lean_assert(!member(3, nil())); + lean_assert(!member(3, sexpr{10, 2, 1})); + lean_assert(append(sexpr{1,2}, sexpr{3,4}) == (sexpr{1,2,3,4})); + lean_assert(append(l, nil()) == l); + lean_assert(append(nil(), l) == l); + lean_assert(contains(sexpr{10,20,-2,0,10}, [](sexpr e) { return to_int(e) < 0; })); + lean_assert(!contains(sexpr{10,20,-2,0,10}, [](sexpr e) { return to_int(e) < -10; })); } int main() {