feat(library/simplifier): cast elimination in the simplifier
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
parent
cd87cb3de4
commit
dbc100cc2e
14 changed files with 175 additions and 40 deletions
|
@ -101,4 +101,5 @@ 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" "")
|
||||
update_interface("heq.olean" "library" "")
|
||||
update_interface("heq.olean" "library" "")
|
||||
update_interface("cast.olean" "library" "")
|
|
@ -41,7 +41,7 @@
|
|||
name_to_cpp_decl(obj:get_name())
|
||||
io.write("(expr const & e) { return is_app(e) && is_");
|
||||
name_to_cpp_decl(obj:get_name())
|
||||
print("_fn(arg(e, 0)); }")
|
||||
print("_fn(arg(e, 0)) && num_args(e) == " .. (arity+1) .. "; }")
|
||||
end
|
||||
if is_fn then
|
||||
io.write("inline expr mk_")
|
||||
|
|
|
@ -36,7 +36,7 @@ bool is_false(expr const & e);
|
|||
expr mk_eq_fn();
|
||||
bool is_eq_fn(expr const & e);
|
||||
inline expr mk_eq(expr const & A, expr const & lhs, expr const & rhs) { return mk_app(mk_eq_fn(), A, lhs, rhs); }
|
||||
inline bool is_eq(expr const & e) { return is_app(e) && is_eq_fn(arg(e, 0)); }
|
||||
inline bool is_eq(expr const & e) { return is_app(e) && is_eq_fn(arg(e, 0)) && num_args(e) == 4; }
|
||||
|
||||
inline expr Implies(expr const & e1, expr const & e2) { return mk_implies(e1, e2); }
|
||||
inline expr And(expr const & e1, expr const & e2) { return mk_and(e1, e2); }
|
||||
|
|
|
@ -11,35 +11,35 @@ expr mk_Bool();
|
|||
bool is_Bool(expr const & e);
|
||||
expr mk_not_fn();
|
||||
bool is_not_fn(expr const & e);
|
||||
inline bool is_not(expr const & e) { return is_app(e) && is_not_fn(arg(e, 0)); }
|
||||
inline bool is_not(expr const & e) { return is_app(e) && is_not_fn(arg(e, 0)) && num_args(e) == 2; }
|
||||
inline expr mk_not(expr const & e1) { return mk_app({mk_not_fn(), e1}); }
|
||||
expr mk_or_fn();
|
||||
bool is_or_fn(expr const & e);
|
||||
inline bool is_or(expr const & e) { return is_app(e) && is_or_fn(arg(e, 0)); }
|
||||
inline bool is_or(expr const & e) { return is_app(e) && is_or_fn(arg(e, 0)) && num_args(e) == 3; }
|
||||
inline expr mk_or(expr const & e1, expr const & e2) { return mk_app({mk_or_fn(), e1, e2}); }
|
||||
expr mk_and_fn();
|
||||
bool is_and_fn(expr const & e);
|
||||
inline bool is_and(expr const & e) { return is_app(e) && is_and_fn(arg(e, 0)); }
|
||||
inline bool is_and(expr const & e) { return is_app(e) && is_and_fn(arg(e, 0)) && num_args(e) == 3; }
|
||||
inline expr mk_and(expr const & e1, expr const & e2) { return mk_app({mk_and_fn(), e1, e2}); }
|
||||
expr mk_implies_fn();
|
||||
bool is_implies_fn(expr const & e);
|
||||
inline bool is_implies(expr const & e) { return is_app(e) && is_implies_fn(arg(e, 0)); }
|
||||
inline bool is_implies(expr const & e) { return is_app(e) && is_implies_fn(arg(e, 0)) && num_args(e) == 3; }
|
||||
inline expr mk_implies(expr const & e1, expr const & e2) { return mk_app({mk_implies_fn(), e1, e2}); }
|
||||
expr mk_neq_fn();
|
||||
bool is_neq_fn(expr const & e);
|
||||
inline bool is_neq(expr const & e) { return is_app(e) && is_neq_fn(arg(e, 0)); }
|
||||
inline bool is_neq(expr const & e) { return is_app(e) && is_neq_fn(arg(e, 0)) && num_args(e) == 4; }
|
||||
inline expr mk_neq(expr const & e1, expr const & e2, expr const & e3) { return mk_app({mk_neq_fn(), e1, e2, e3}); }
|
||||
expr mk_iff_fn();
|
||||
bool is_iff_fn(expr const & e);
|
||||
inline bool is_iff(expr const & e) { return is_app(e) && is_iff_fn(arg(e, 0)); }
|
||||
inline bool is_iff(expr const & e) { return is_app(e) && is_iff_fn(arg(e, 0)) && num_args(e) == 3; }
|
||||
inline expr mk_iff(expr const & e1, expr const & e2) { return mk_app({mk_iff_fn(), e1, e2}); }
|
||||
expr mk_exists_fn();
|
||||
bool is_exists_fn(expr const & e);
|
||||
inline bool is_exists(expr const & e) { return is_app(e) && is_exists_fn(arg(e, 0)); }
|
||||
inline bool is_exists(expr const & e) { return is_app(e) && is_exists_fn(arg(e, 0)) && num_args(e) == 3; }
|
||||
inline expr mk_exists(expr const & e1, expr const & e2) { return mk_app({mk_exists_fn(), e1, e2}); }
|
||||
expr mk_nonempty_fn();
|
||||
bool is_nonempty_fn(expr const & e);
|
||||
inline bool is_nonempty(expr const & e) { return is_app(e) && is_nonempty_fn(arg(e, 0)); }
|
||||
inline bool is_nonempty(expr const & e) { return is_app(e) && is_nonempty_fn(arg(e, 0)) && num_args(e) == 2; }
|
||||
inline expr mk_nonempty(expr const & e1) { return mk_app({mk_nonempty_fn(), e1}); }
|
||||
expr mk_nonempty_intro_fn();
|
||||
bool is_nonempty_intro_fn(expr const & e);
|
||||
|
@ -64,7 +64,7 @@ bool is_allext_fn(expr const & e);
|
|||
inline expr mk_allext_th(expr const & e1, expr const & e2, expr const & e3, expr const & e4) { return mk_app({mk_allext_fn(), e1, e2, e3, e4}); }
|
||||
expr mk_eps_fn();
|
||||
bool is_eps_fn(expr const & e);
|
||||
inline bool is_eps(expr const & e) { return is_app(e) && is_eps_fn(arg(e, 0)); }
|
||||
inline bool is_eps(expr const & e) { return is_app(e) && is_eps_fn(arg(e, 0)) && num_args(e) == 4; }
|
||||
inline expr mk_eps(expr const & e1, expr const & e2, expr const & e3) { return mk_app({mk_eps_fn(), e1, e2, e3}); }
|
||||
expr mk_eps_ax_fn();
|
||||
bool is_eps_ax_fn(expr const & e);
|
||||
|
|
|
@ -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 equality.cpp io_state_stream.cpp printer.cpp
|
||||
hop_match.cpp ite.cpp heq_decls.cpp)
|
||||
hop_match.cpp ite.cpp heq_decls.cpp cast_decls.cpp)
|
||||
|
||||
target_link_libraries(library ${LEAN_LIBS})
|
||||
|
|
|
@ -9,42 +9,42 @@ expr mk_Int();
|
|||
bool is_Int(expr const & e);
|
||||
expr mk_Int_ge_fn();
|
||||
bool is_Int_ge_fn(expr const & e);
|
||||
inline bool is_Int_ge(expr const & e) { return is_app(e) && is_Int_ge_fn(arg(e, 0)); }
|
||||
inline bool is_Int_ge(expr const & e) { return is_app(e) && is_Int_ge_fn(arg(e, 0)) && num_args(e) == 3; }
|
||||
inline expr mk_Int_ge(expr const & e1, expr const & e2) { return mk_app({mk_Int_ge_fn(), e1, e2}); }
|
||||
expr mk_Int_lt_fn();
|
||||
bool is_Int_lt_fn(expr const & e);
|
||||
inline bool is_Int_lt(expr const & e) { return is_app(e) && is_Int_lt_fn(arg(e, 0)); }
|
||||
inline bool is_Int_lt(expr const & e) { return is_app(e) && is_Int_lt_fn(arg(e, 0)) && num_args(e) == 3; }
|
||||
inline expr mk_Int_lt(expr const & e1, expr const & e2) { return mk_app({mk_Int_lt_fn(), e1, e2}); }
|
||||
expr mk_Int_gt_fn();
|
||||
bool is_Int_gt_fn(expr const & e);
|
||||
inline bool is_Int_gt(expr const & e) { return is_app(e) && is_Int_gt_fn(arg(e, 0)); }
|
||||
inline bool is_Int_gt(expr const & e) { return is_app(e) && is_Int_gt_fn(arg(e, 0)) && num_args(e) == 3; }
|
||||
inline expr mk_Int_gt(expr const & e1, expr const & e2) { return mk_app({mk_Int_gt_fn(), e1, e2}); }
|
||||
expr mk_Int_sub_fn();
|
||||
bool is_Int_sub_fn(expr const & e);
|
||||
inline bool is_Int_sub(expr const & e) { return is_app(e) && is_Int_sub_fn(arg(e, 0)); }
|
||||
inline bool is_Int_sub(expr const & e) { return is_app(e) && is_Int_sub_fn(arg(e, 0)) && num_args(e) == 3; }
|
||||
inline expr mk_Int_sub(expr const & e1, expr const & e2) { return mk_app({mk_Int_sub_fn(), e1, e2}); }
|
||||
expr mk_Int_neg_fn();
|
||||
bool is_Int_neg_fn(expr const & e);
|
||||
inline bool is_Int_neg(expr const & e) { return is_app(e) && is_Int_neg_fn(arg(e, 0)); }
|
||||
inline bool is_Int_neg(expr const & e) { return is_app(e) && is_Int_neg_fn(arg(e, 0)) && num_args(e) == 2; }
|
||||
inline expr mk_Int_neg(expr const & e1) { return mk_app({mk_Int_neg_fn(), e1}); }
|
||||
expr mk_Int_mod_fn();
|
||||
bool is_Int_mod_fn(expr const & e);
|
||||
inline bool is_Int_mod(expr const & e) { return is_app(e) && is_Int_mod_fn(arg(e, 0)); }
|
||||
inline bool is_Int_mod(expr const & e) { return is_app(e) && is_Int_mod_fn(arg(e, 0)) && num_args(e) == 3; }
|
||||
inline expr mk_Int_mod(expr const & e1, expr const & e2) { return mk_app({mk_Int_mod_fn(), e1, e2}); }
|
||||
expr mk_Int_divides_fn();
|
||||
bool is_Int_divides_fn(expr const & e);
|
||||
inline bool is_Int_divides(expr const & e) { return is_app(e) && is_Int_divides_fn(arg(e, 0)); }
|
||||
inline bool is_Int_divides(expr const & e) { return is_app(e) && is_Int_divides_fn(arg(e, 0)) && num_args(e) == 3; }
|
||||
inline expr mk_Int_divides(expr const & e1, expr const & e2) { return mk_app({mk_Int_divides_fn(), e1, e2}); }
|
||||
expr mk_Int_abs_fn();
|
||||
bool is_Int_abs_fn(expr const & e);
|
||||
inline bool is_Int_abs(expr const & e) { return is_app(e) && is_Int_abs_fn(arg(e, 0)); }
|
||||
inline bool is_Int_abs(expr const & e) { return is_app(e) && is_Int_abs_fn(arg(e, 0)) && num_args(e) == 2; }
|
||||
inline expr mk_Int_abs(expr const & e1) { return mk_app({mk_Int_abs_fn(), e1}); }
|
||||
expr mk_Nat_sub_fn();
|
||||
bool is_Nat_sub_fn(expr const & e);
|
||||
inline bool is_Nat_sub(expr const & e) { return is_app(e) && is_Nat_sub_fn(arg(e, 0)); }
|
||||
inline bool is_Nat_sub(expr const & e) { return is_app(e) && is_Nat_sub_fn(arg(e, 0)) && num_args(e) == 3; }
|
||||
inline expr mk_Nat_sub(expr const & e1, expr const & e2) { return mk_app({mk_Nat_sub_fn(), e1, e2}); }
|
||||
expr mk_Nat_neg_fn();
|
||||
bool is_Nat_neg_fn(expr const & e);
|
||||
inline bool is_Nat_neg(expr const & e) { return is_app(e) && is_Nat_neg_fn(arg(e, 0)); }
|
||||
inline bool is_Nat_neg(expr const & e) { return is_app(e) && is_Nat_neg_fn(arg(e, 0)) && num_args(e) == 2; }
|
||||
inline expr mk_Nat_neg(expr const & e1) { return mk_app({mk_Nat_neg_fn(), e1}); }
|
||||
}
|
||||
|
|
|
@ -9,19 +9,19 @@ expr mk_Nat();
|
|||
bool is_Nat(expr const & e);
|
||||
expr mk_Nat_ge_fn();
|
||||
bool is_Nat_ge_fn(expr const & e);
|
||||
inline bool is_Nat_ge(expr const & e) { return is_app(e) && is_Nat_ge_fn(arg(e, 0)); }
|
||||
inline bool is_Nat_ge(expr const & e) { return is_app(e) && is_Nat_ge_fn(arg(e, 0)) && num_args(e) == 3; }
|
||||
inline expr mk_Nat_ge(expr const & e1, expr const & e2) { return mk_app({mk_Nat_ge_fn(), e1, e2}); }
|
||||
expr mk_Nat_lt_fn();
|
||||
bool is_Nat_lt_fn(expr const & e);
|
||||
inline bool is_Nat_lt(expr const & e) { return is_app(e) && is_Nat_lt_fn(arg(e, 0)); }
|
||||
inline bool is_Nat_lt(expr const & e) { return is_app(e) && is_Nat_lt_fn(arg(e, 0)) && num_args(e) == 3; }
|
||||
inline expr mk_Nat_lt(expr const & e1, expr const & e2) { return mk_app({mk_Nat_lt_fn(), e1, e2}); }
|
||||
expr mk_Nat_gt_fn();
|
||||
bool is_Nat_gt_fn(expr const & e);
|
||||
inline bool is_Nat_gt(expr const & e) { return is_app(e) && is_Nat_gt_fn(arg(e, 0)); }
|
||||
inline bool is_Nat_gt(expr const & e) { return is_app(e) && is_Nat_gt_fn(arg(e, 0)) && num_args(e) == 3; }
|
||||
inline expr mk_Nat_gt(expr const & e1, expr const & e2) { return mk_app({mk_Nat_gt_fn(), e1, e2}); }
|
||||
expr mk_Nat_id_fn();
|
||||
bool is_Nat_id_fn(expr const & e);
|
||||
inline bool is_Nat_id(expr const & e) { return is_app(e) && is_Nat_id_fn(arg(e, 0)); }
|
||||
inline bool is_Nat_id(expr const & e) { return is_app(e) && is_Nat_id_fn(arg(e, 0)) && num_args(e) == 2; }
|
||||
inline expr mk_Nat_id(expr const & e1) { return mk_app({mk_Nat_id_fn(), e1}); }
|
||||
expr mk_Nat_succ_nz_fn();
|
||||
bool is_Nat_succ_nz_fn(expr const & e);
|
||||
|
|
|
@ -9,30 +9,30 @@ expr mk_Real();
|
|||
bool is_Real(expr const & e);
|
||||
expr mk_nat_to_real_fn();
|
||||
bool is_nat_to_real_fn(expr const & e);
|
||||
inline bool is_nat_to_real(expr const & e) { return is_app(e) && is_nat_to_real_fn(arg(e, 0)); }
|
||||
inline bool is_nat_to_real(expr const & e) { return is_app(e) && is_nat_to_real_fn(arg(e, 0)) && num_args(e) == 2; }
|
||||
inline expr mk_nat_to_real(expr const & e1) { return mk_app({mk_nat_to_real_fn(), e1}); }
|
||||
expr mk_Real_ge_fn();
|
||||
bool is_Real_ge_fn(expr const & e);
|
||||
inline bool is_Real_ge(expr const & e) { return is_app(e) && is_Real_ge_fn(arg(e, 0)); }
|
||||
inline bool is_Real_ge(expr const & e) { return is_app(e) && is_Real_ge_fn(arg(e, 0)) && num_args(e) == 3; }
|
||||
inline expr mk_Real_ge(expr const & e1, expr const & e2) { return mk_app({mk_Real_ge_fn(), e1, e2}); }
|
||||
expr mk_Real_lt_fn();
|
||||
bool is_Real_lt_fn(expr const & e);
|
||||
inline bool is_Real_lt(expr const & e) { return is_app(e) && is_Real_lt_fn(arg(e, 0)); }
|
||||
inline bool is_Real_lt(expr const & e) { return is_app(e) && is_Real_lt_fn(arg(e, 0)) && num_args(e) == 3; }
|
||||
inline expr mk_Real_lt(expr const & e1, expr const & e2) { return mk_app({mk_Real_lt_fn(), e1, e2}); }
|
||||
expr mk_Real_gt_fn();
|
||||
bool is_Real_gt_fn(expr const & e);
|
||||
inline bool is_Real_gt(expr const & e) { return is_app(e) && is_Real_gt_fn(arg(e, 0)); }
|
||||
inline bool is_Real_gt(expr const & e) { return is_app(e) && is_Real_gt_fn(arg(e, 0)) && num_args(e) == 3; }
|
||||
inline expr mk_Real_gt(expr const & e1, expr const & e2) { return mk_app({mk_Real_gt_fn(), e1, e2}); }
|
||||
expr mk_Real_sub_fn();
|
||||
bool is_Real_sub_fn(expr const & e);
|
||||
inline bool is_Real_sub(expr const & e) { return is_app(e) && is_Real_sub_fn(arg(e, 0)); }
|
||||
inline bool is_Real_sub(expr const & e) { return is_app(e) && is_Real_sub_fn(arg(e, 0)) && num_args(e) == 3; }
|
||||
inline expr mk_Real_sub(expr const & e1, expr const & e2) { return mk_app({mk_Real_sub_fn(), e1, e2}); }
|
||||
expr mk_Real_neg_fn();
|
||||
bool is_Real_neg_fn(expr const & e);
|
||||
inline bool is_Real_neg(expr const & e) { return is_app(e) && is_Real_neg_fn(arg(e, 0)); }
|
||||
inline bool is_Real_neg(expr const & e) { return is_app(e) && is_Real_neg_fn(arg(e, 0)) && num_args(e) == 2; }
|
||||
inline expr mk_Real_neg(expr const & e1) { return mk_app({mk_Real_neg_fn(), e1}); }
|
||||
expr mk_Real_abs_fn();
|
||||
bool is_Real_abs_fn(expr const & e);
|
||||
inline bool is_Real_abs(expr const & e) { return is_app(e) && is_Real_abs_fn(arg(e, 0)); }
|
||||
inline bool is_Real_abs(expr const & e) { return is_app(e) && is_Real_abs_fn(arg(e, 0)) && num_args(e) == 2; }
|
||||
inline expr mk_Real_abs(expr const & e1) { return mk_app({mk_Real_abs_fn(), e1}); }
|
||||
}
|
||||
|
|
15
src/library/cast_decls.cpp
Normal file
15
src/library/cast_decls.cpp
Normal file
|
@ -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(cast_fn, name("cast"));
|
||||
MK_CONSTANT(cast_heq_fn, name("cast_heq"));
|
||||
MK_CONSTANT(cast_app_fn, name("cast_app"));
|
||||
MK_CONSTANT(cast_eq_fn, name("cast_eq"));
|
||||
MK_CONSTANT(cast_trans_fn, name("cast_trans"));
|
||||
MK_CONSTANT(cast_pull_fn, name("cast_pull"));
|
||||
}
|
27
src/library/cast_decls.h
Normal file
27
src/library/cast_decls.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
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_cast_fn();
|
||||
bool is_cast_fn(expr const & e);
|
||||
inline bool is_cast(expr const & e) { return is_app(e) && is_cast_fn(arg(e, 0)) && num_args(e) == 5; }
|
||||
inline expr mk_cast(expr const & e1, expr const & e2, expr const & e3, expr const & e4) { return mk_app({mk_cast_fn(), e1, e2, e3, e4}); }
|
||||
expr mk_cast_heq_fn();
|
||||
bool is_cast_heq_fn(expr const & e);
|
||||
inline expr mk_cast_heq_th(expr const & e1, expr const & e2, expr const & e3, expr const & e4) { return mk_app({mk_cast_heq_fn(), e1, e2, e3, e4}); }
|
||||
expr mk_cast_app_fn();
|
||||
bool is_cast_app_fn(expr const & e);
|
||||
inline expr mk_cast_app_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) { return mk_app({mk_cast_app_fn(), e1, e2, e3, e4, e5, e6, e7, e8}); }
|
||||
expr mk_cast_eq_fn();
|
||||
bool is_cast_eq_fn(expr const & e);
|
||||
inline expr mk_cast_eq_th(expr const & e1, expr const & e2, expr const & e3) { return mk_app({mk_cast_eq_fn(), e1, e2, e3}); }
|
||||
expr mk_cast_trans_fn();
|
||||
bool is_cast_trans_fn(expr const & e);
|
||||
inline expr mk_cast_trans_th(expr const & e1, expr const & e2, expr const & e3, expr const & e4, expr const & e5, expr const & e6) { return mk_app({mk_cast_trans_fn(), e1, e2, e3, e4, e5, e6}); }
|
||||
expr mk_cast_pull_fn();
|
||||
bool is_cast_pull_fn(expr const & e);
|
||||
inline expr mk_cast_pull_th(expr const & e1, expr const & e2, expr const & e3, expr const & e4, expr const & e5, expr const & e6, expr const & e7) { return mk_app({mk_cast_pull_fn(), e1, e2, e3, e4, e5, e6, e7}); }
|
||||
}
|
|
@ -7,7 +7,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
namespace lean {
|
||||
expr mk_heq_fn();
|
||||
bool is_heq_fn(expr const & e);
|
||||
inline bool is_heq(expr const & e) { return is_app(e) && is_heq_fn(arg(e, 0)); }
|
||||
inline bool is_heq(expr const & e) { return is_app(e) && is_heq_fn(arg(e, 0)) && num_args(e) == 5; }
|
||||
inline expr mk_heq(expr const & e1, expr const & e2, expr const & e3, expr const & e4) { return mk_app({mk_heq_fn(), e1, e2, e3, e4}); }
|
||||
expr mk_heq_eq_fn();
|
||||
bool is_heq_eq_fn(expr const & e);
|
||||
|
|
|
@ -17,6 +17,7 @@ Author: Leonardo de Moura
|
|||
#include "kernel/kernel.h"
|
||||
#include "kernel/max_sharing.h"
|
||||
#include "library/heq_decls.h"
|
||||
#include "library/cast_decls.h"
|
||||
#include "library/kernel_bindings.h"
|
||||
#include "library/expr_pair.h"
|
||||
#include "library/hop_match.h"
|
||||
|
@ -120,6 +121,7 @@ class simplifier_fn {
|
|||
ro_environment m_env;
|
||||
type_checker m_tc;
|
||||
bool m_has_heq;
|
||||
bool m_has_cast;
|
||||
context m_ctx;
|
||||
rule_sets m_rule_sets;
|
||||
cache m_cache;
|
||||
|
@ -300,6 +302,38 @@ class simplifier_fn {
|
|||
}
|
||||
|
||||
result simplify_app(expr const & e) {
|
||||
if (m_has_cast && is_cast(e)) {
|
||||
// e is of the form (cast A B H a)
|
||||
expr A = arg(e, 1);
|
||||
expr B = arg(e, 2);
|
||||
expr H = arg(e, 3);
|
||||
expr a = arg(e, 4);
|
||||
if (m_proofs_enabled) {
|
||||
result res_a = simplify(a);
|
||||
expr c = res_a.m_out;
|
||||
if (res_a.m_proof) {
|
||||
expr Hec;
|
||||
expr Hac = *res_a.m_proof;
|
||||
if (!res_a.m_heq_proof) {
|
||||
Hec = ::lean::mk_htrans_th(A, B, B, e, a, c,
|
||||
update_app(e, 0, mk_cast_heq_fn()), // cast A B H a == a
|
||||
mk_to_heq_th(B, a, c, Hac)); // a == c
|
||||
} else {
|
||||
Hec = ::lean::mk_htrans_th(A, B, infer_type(c), e, a, c,
|
||||
update_app(e, 0, mk_cast_heq_fn()), // cast A B H a == a
|
||||
Hac); // a == c
|
||||
}
|
||||
return result(c, Hec, true);
|
||||
|
||||
} else {
|
||||
// c is definitionally equal to a
|
||||
// So, we use cast_heq theorem cast_heq : cast A B H a == a
|
||||
return result(c, update_app(e, 0, mk_cast_heq_fn()), true);
|
||||
}
|
||||
} else {
|
||||
return simplify(arg(e, 4));
|
||||
}
|
||||
}
|
||||
if (m_contextual) {
|
||||
expr const & f = arg(e, 0);
|
||||
for (auto congr_th : m_congr_thms) {
|
||||
|
@ -496,10 +530,13 @@ class simplifier_fn {
|
|||
if (i == 0) {
|
||||
pr = *(proofs[0]);
|
||||
heq_proof = m_has_heq && heq_proofs[0];
|
||||
} else if (m_has_heq && heq_proofs[i]) {
|
||||
} else if (m_has_heq && (heq_proofs[i] || !is_arrow(f_types[i-1]))) {
|
||||
expr f = mk_app_prefix(i, new_args);
|
||||
expr pr_i = *proofs[i];
|
||||
if (!heq_proofs[i])
|
||||
pr_i = mk_to_heq_th(abst_domain(f_types[i-1]), arg(e, i), new_args[i], pr_i);
|
||||
pr = mk_hcongr_th(f_types[i-1], f_types[i-1], f, f, arg(e, i), new_args[i],
|
||||
mk_hrefl_th(f_types[i-1], f), *(proofs[i]));
|
||||
mk_hrefl_th(f_types[i-1], f), pr_i);
|
||||
heq_proof = true;
|
||||
} else {
|
||||
expr f = mk_app_prefix(i, new_args);
|
||||
|
@ -510,13 +547,17 @@ class simplifier_fn {
|
|||
expr f = mk_app_prefix(i, e);
|
||||
expr new_f = mk_app_prefix(i, new_args);
|
||||
if (proofs[i]) {
|
||||
expr pr_i = *proofs[i];
|
||||
if (m_has_heq && heq_proofs[i]) {
|
||||
if (!heq_proof)
|
||||
pr = mk_to_heq_th(f_types[i], f, new_f, pr);
|
||||
pr = mk_hcongr_th(f_types[i-1], new_f_types[i-1], f, new_f, arg(e, i), new_args[i], pr, *(proofs[i]));
|
||||
pr = mk_hcongr_th(f_types[i-1], new_f_types[i-1], f, new_f, arg(e, i), new_args[i], pr, pr_i);
|
||||
heq_proof = true;
|
||||
} else if (heq_proof) {
|
||||
pr_i = mk_to_heq_th(abst_domain(f_types[i-1]), arg(e, i), new_args[i], pr_i);
|
||||
pr = mk_hcongr_th(f_types[i-1], new_f_types[i-1], f, new_f, arg(e, i), new_args[i], pr, pr_i);
|
||||
} else {
|
||||
pr = mk_congr_th(f_types[i-1], f, new_f, arg(e, i), new_args[i], pr, *(proofs[i]));
|
||||
pr = mk_congr_th(f_types[i-1], f, new_f, arg(e, i), new_args[i], pr, pr_i);
|
||||
}
|
||||
} else if (heq_proof) {
|
||||
pr = mk_hcongr_th(f_types[i-1], new_f_types[i-1], f, new_f, arg(e, i), arg(e, i),
|
||||
|
@ -916,7 +957,8 @@ class simplifier_fn {
|
|||
public:
|
||||
simplifier_fn(ro_environment const & env, options const & o, unsigned num_rs, rewrite_rule_set const * rs):
|
||||
m_env(env), m_tc(env) {
|
||||
m_has_heq = m_env->imported("heq");
|
||||
m_has_heq = m_env->imported("heq");
|
||||
m_has_cast = m_env->imported("cast");
|
||||
set_options(o);
|
||||
if (m_contextual) {
|
||||
// add a set of rewrite rules for contextual rewriting
|
||||
|
|
29
tests/lean/simp18.lean
Normal file
29
tests/lean/simp18.lean
Normal file
|
@ -0,0 +1,29 @@
|
|||
import cast
|
||||
variable vec : Nat → Type
|
||||
variable concat {n m : Nat} (v : vec n) (w : vec m) : vec (n + m)
|
||||
infixl 65 ; : concat
|
||||
axiom concat_assoc {n1 n2 n3 : Nat} (v1 : vec n1) (v2 : vec n2) (v3 : vec n3) :
|
||||
(v1 ; v2) ; v3 = cast (congr2 vec (symm (Nat::add_assoc n1 n2 n3)))
|
||||
(v1 ; (v2 ; v3))
|
||||
variable empty : vec 0
|
||||
axiom concat_empty {n : Nat} (v : vec n) :
|
||||
v ; empty = cast (congr2 vec (symm (Nat::add_zeror n)))
|
||||
v
|
||||
|
||||
rewrite_set simple
|
||||
add_rewrite concat_assoc concat_empty Nat::add_assoc Nat::add_zeror : simple
|
||||
|
||||
variable n : Nat
|
||||
variable v : vec n
|
||||
variable w : vec n
|
||||
|
||||
(*
|
||||
local t = parse_lean([[ (v ; w) ; empty ; (v ; empty) ]])
|
||||
print(t)
|
||||
print("===>")
|
||||
local t2, pr = simplify(t, "simple")
|
||||
print(t2)
|
||||
print(pr)
|
||||
get_environment():type_check(pr)
|
||||
*)
|
||||
|
21
tests/lean/simp18.lean.expected.out
Normal file
21
tests/lean/simp18.lean.expected.out
Normal file
|
@ -0,0 +1,21 @@
|
|||
Set: pp::colors
|
||||
Set: pp::unicode
|
||||
Imported 'cast'
|
||||
Assumed: vec
|
||||
Assumed: concat
|
||||
Assumed: concat_assoc
|
||||
Assumed: empty
|
||||
Assumed: concat_empty
|
||||
Assumed: n
|
||||
Assumed: v
|
||||
Assumed: w
|
||||
v ; w ; empty ; (v ; empty)
|
||||
===>
|
||||
v ; (w ; v)
|
||||
htrans (htrans (hcongr (hcongr (hcongr (hcongr (hrefl @concat) (to_heq (Nat::add_zeror (n + n))))
|
||||
(to_heq (Nat::add_zeror n)))
|
||||
(htrans (to_heq (concat_empty (v ; w)))
|
||||
(cast_heq (congr2 vec (symm (Nat::add_zeror (n + n)))) (v ; w))))
|
||||
(htrans (to_heq (concat_empty v)) (cast_heq (congr2 vec (symm (Nat::add_zeror n))) v)))
|
||||
(to_heq (concat_assoc v w v)))
|
||||
(cast_heq (congr2 vec (symm (Nat::add_assoc n n n))) (v ; (w ; v)))
|
Loading…
Reference in a new issue