diff --git a/src/builtin/CMakeLists.txt b/src/builtin/CMakeLists.txt
index 2670aca66..16dd5d3e3 100644
--- a/src/builtin/CMakeLists.txt
+++ b/src/builtin/CMakeLists.txt
@@ -95,7 +95,8 @@ add_theory("Real.lean" "${CMAKE_CURRENT_BINARY_DIR}/Int.olean")
add_theory("specialfn.lean" "${CMAKE_CURRENT_BINARY_DIR}/Real.olean")
add_theory("cast.lean" "${CMAKE_CURRENT_BINARY_DIR}/Nat.olean")
-update_interface("kernel.olean" "kernel" "-n")
-update_interface("Nat.olean" "library/arith" "-n")
-update_interface("Int.olean" "library/arith" "")
-update_interface("Real.olean" "library/arith" "")
\ No newline at end of file
+update_interface("kernel.olean" "kernel" "-n")
+update_interface("Nat.olean" "library/arith" "-n")
+update_interface("Int.olean" "library/arith" "")
+update_interface("Real.olean" "library/arith" "")
+update_interface("if_then_else.olean" "library" "")
\ No newline at end of file
diff --git a/src/builtin/if_then_else.lean b/src/builtin/if_then_else.lean
index ad5f76853..a7a9a03ef 100644
--- a/src/builtin/if_then_else.lean
+++ b/src/builtin/if_then_else.lean
@@ -1,3 +1,5 @@
+import macros
+
-- if_then_else expression support
builtin ite {A : (Type U)} : Bool → A → A → A
notation 60 if _ then _ else _ : ite
@@ -25,4 +27,15 @@ theorem if_congr {A : TypeU} {b c : Bool} {x y u v : A} (H_bc : b = c) (H_xu :
... = (if false then u else v) : symm (if_false _ _)
... = (if c then u else v) : { symm (eqf_intro H_nc) })
+theorem if_imp_then {a b c : Bool} (H : if a then b else c) : a → b
+:= assume Ha : a, eqt_elim (calc b = (if true then b else c) : symm (if_true b c)
+ ... = (if a then b else c) : { symm (eqt_intro Ha) }
+ ... = true : eqt_intro H)
+
+theorem if_imp_else {a b c : Bool} (H : if a then b else c) : ¬ a → c
+:= assume Hna : ¬ a, eqt_elim (calc c = (if false then b else c) : symm (if_false b c)
+ ... = (if a then b else c) : { symm (eqf_intro Hna) }
+ ... = true : eqt_intro H)
+
+
set_opaque ite true
\ No newline at end of file
diff --git a/src/builtin/obj/if_then_else.olean b/src/builtin/obj/if_then_else.olean
index 438a5a495..b6f6a6011 100644
Binary files a/src/builtin/obj/if_then_else.olean and b/src/builtin/obj/if_then_else.olean differ
diff --git a/src/kernel/builtin.cpp b/src/kernel/builtin.cpp
index ffb33a973..1da2866fd 100644
--- a/src/kernel/builtin.cpp
+++ b/src/kernel/builtin.cpp
@@ -78,44 +78,6 @@ bool is_false(expr const & e) {
}
// =======================================
-// =======================================
-// If-then-else builtin operator
-static name g_if_name("ite");
-static format g_if_fmt(g_if_name);
-/**
- \brief Semantic attachment for if-then-else operator with type
- Pi (A : Type), Bool -> A -> A -> A
-*/
-class if_fn_value : public value {
- expr m_type;
- static expr mk_type() {
- expr A = Const("A");
- // Pi (A: Type), bool -> A -> A -> A
- return Pi({A, TypeU}, Bool >> (A >> (A >> A)));
- }
-public:
- if_fn_value():m_type(mk_type()) {}
- virtual ~if_fn_value() {}
- virtual expr get_type() const { return m_type; }
- virtual name get_name() const { return g_if_name; }
- virtual optional normalize(unsigned num_args, expr const * args) const {
- if (num_args == 5 && is_bool_value(args[2]) && is_value(args[3]) && is_value(args[4])) {
- if (to_bool(args[2]))
- return some_expr(args[3]); // if A true a b --> a
- else
- return some_expr(args[4]); // if A false a b --> b
- } else {
- return none_expr();
- }
- }
- virtual void write(serializer & s) const { s << "ite"; }
-};
-MK_BUILTIN(if_fn, if_fn_value);
-MK_IS_BUILTIN(is_if_fn, mk_if_fn());
-static register_builtin_fn if_blt("ite", []() { return mk_if_fn(); });
-static value::register_deserializer_fn if_ds("ite", [](deserializer & ) { return mk_if_fn(); });
-// =======================================
-
void import_kernel(environment const & env, io_state const & ios) {
env->import("kernel", ios);
}
diff --git a/src/library/CMakeLists.txt b/src/library/CMakeLists.txt
index 142aea695..687d75052 100644
--- a/src/library/CMakeLists.txt
+++ b/src/library/CMakeLists.txt
@@ -1,6 +1,6 @@
add_library(library kernel_bindings.cpp deep_copy.cpp
context_to_lambda.cpp placeholder.cpp expr_lt.cpp substitution.cpp
fo_unify.cpp bin_op.cpp eq_heq.cpp io_state_stream.cpp printer.cpp
- hop_match.cpp)
+ hop_match.cpp ite.cpp)
target_link_libraries(library ${LEAN_LIBS})
diff --git a/src/library/if_then_else_decls.cpp b/src/library/if_then_else_decls.cpp
new file mode 100644
index 000000000..57c5b08dc
--- /dev/null
+++ b/src/library/if_then_else_decls.cpp
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2013 Microsoft Corporation. All rights reserved.
+Released under Apache 2.0 license as described in the file LICENSE.
+*/
+// Automatically generated file, DO NOT EDIT
+#include "kernel/environment.h"
+#include "kernel/decl_macros.h"
+namespace lean {
+MK_CONSTANT(if_true_fn, name("if_true"));
+MK_CONSTANT(if_false_fn, name("if_false"));
+MK_CONSTANT(if_a_a_fn, name("if_a_a"));
+MK_CONSTANT(if_congr_fn, name("if_congr"));
+MK_CONSTANT(if_imp_then_fn, name("if_imp_then"));
+MK_CONSTANT(if_imp_else_fn, name("if_imp_else"));
+}
diff --git a/src/library/if_then_else_decls.h b/src/library/if_then_else_decls.h
new file mode 100644
index 000000000..cc511ccca
--- /dev/null
+++ b/src/library/if_then_else_decls.h
@@ -0,0 +1,26 @@
+/*
+Copyright (c) 2013 Microsoft Corporation. All rights reserved.
+Released under Apache 2.0 license as described in the file LICENSE.
+*/
+// Automatically generated file, DO NOT EDIT
+#include "kernel/expr.h"
+namespace lean {
+expr mk_if_true_fn();
+bool is_if_true_fn(expr const & e);
+inline expr mk_if_true_th(expr const & e1, expr const & e2, expr const & e3) { return mk_app({mk_if_true_fn(), e1, e2, e3}); }
+expr mk_if_false_fn();
+bool is_if_false_fn(expr const & e);
+inline expr mk_if_false_th(expr const & e1, expr const & e2, expr const & e3) { return mk_app({mk_if_false_fn(), e1, e2, e3}); }
+expr mk_if_a_a_fn();
+bool is_if_a_a_fn(expr const & e);
+inline expr mk_if_a_a_th(expr const & e1, expr const & e2, expr const & e3) { return mk_app({mk_if_a_a_fn(), e1, e2, e3}); }
+expr mk_if_congr_fn();
+bool is_if_congr_fn(expr const & e);
+inline expr mk_if_congr_th(expr const & e1, expr const & e2, expr const & e3, expr const & e4, expr const & e5, expr const & e6, expr const & e7, expr const & e8, expr const & e9, expr const & e10) { return mk_app({mk_if_congr_fn(), e1, e2, e3, e4, e5, e6, e7, e8, e9, e10}); }
+expr mk_if_imp_then_fn();
+bool is_if_imp_then_fn(expr const & e);
+inline expr mk_if_imp_then_th(expr const & e1, expr const & e2, expr const & e3, expr const & e4, expr const & e5) { return mk_app({mk_if_imp_then_fn(), e1, e2, e3, e4, e5}); }
+expr mk_if_imp_else_fn();
+bool is_if_imp_else_fn(expr const & e);
+inline expr mk_if_imp_else_th(expr const & e1, expr const & e2, expr const & e3, expr const & e4, expr const & e5) { return mk_app({mk_if_imp_else_fn(), e1, e2, e3, e4, e5}); }
+}
diff --git a/src/library/ite.cpp b/src/library/ite.cpp
new file mode 100644
index 000000000..e171635e8
--- /dev/null
+++ b/src/library/ite.cpp
@@ -0,0 +1,55 @@
+/*
+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 "kernel/builtin.h"
+#include "kernel/abstract.h"
+#include "kernel/decl_macros.h"
+#include "library/if_then_else_decls.h"
+#include "library/if_then_else_decls.cpp"
+
+namespace lean {
+// =======================================
+// If-then-else builtin operator
+static name g_if_name("ite");
+static format g_if_fmt(g_if_name);
+/**
+ \brief Semantic attachment for if-then-else operator with type
+ Pi (A : Type), Bool -> A -> A -> A
+*/
+class if_fn_value : public value {
+ expr m_type;
+ static expr mk_type() {
+ expr A = Const("A");
+ // Pi (A: Type), bool -> A -> A -> A
+ return Pi({A, TypeU}, Bool >> (A >> (A >> A)));
+ }
+public:
+ if_fn_value():m_type(mk_type()) {}
+ virtual ~if_fn_value() {}
+ virtual expr get_type() const { return m_type; }
+ virtual name get_name() const { return g_if_name; }
+ virtual optional normalize(unsigned num_args, expr const * args) const {
+ if (num_args == 5 && is_bool_value(args[2]) && is_value(args[3]) && is_value(args[4])) {
+ if (to_bool(args[2]))
+ return some_expr(args[3]); // if A true a b --> a
+ else
+ return some_expr(args[4]); // if A false a b --> b
+ } else {
+ return none_expr();
+ }
+ }
+ virtual void write(serializer & s) const { s << "ite"; }
+};
+MK_BUILTIN(if_fn, if_fn_value);
+MK_IS_BUILTIN(is_if_fn, mk_if_fn());
+static register_builtin_fn if_blt("ite", []() { return mk_if_fn(); });
+static value::register_deserializer_fn if_ds("ite", [](deserializer & ) { return mk_if_fn(); });
+// =======================================
+
+void import_ite(environment const & env, io_state const & ios) {
+ env->import("if_then_else", ios);
+}
+}
diff --git a/src/library/ite.h b/src/library/ite.h
new file mode 100644
index 000000000..14e47891d
--- /dev/null
+++ b/src/library/ite.h
@@ -0,0 +1,16 @@
+/*
+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 "kernel/io_state.h"
+#include "library/if_then_else_decls.h"
+
+namespace lean {
+expr mk_ite_fn();
+bool is_ite_fn(expr const & e);
+inline expr mk_ite(expr const & e1, expr const & e2, expr const & e3, expr const & e4) { return mk_app(mk_ite_fn, e1, e2, e3, e4); }
+void import_ite(environment const & env, io_state const & ios);
+}