feat(library): add mk_int_val_ne_proof
This commit is contained in:
parent
58ca9a3059
commit
3061d8b9a3
14 changed files with 345 additions and 22 deletions
|
|
@ -13,9 +13,18 @@ namespace int
|
|||
|
||||
/- 1. Lemmas for reducing the problem to the case where the numerals are positive -/
|
||||
|
||||
protected lemma ne_neg_of_ne (a b : ℤ) : a ≠ b → -a ≠ -b :=
|
||||
protected lemma ne_neg_of_ne {a b : ℤ} : a ≠ b → -a ≠ -b :=
|
||||
λ h₁ h₂, absurd (neg_inj h₂) h₁
|
||||
|
||||
protected lemma neg_ne_zero_of_ne {a : ℤ} : a ≠ 0 → -a ≠ 0 :=
|
||||
λ h₁ h₂,
|
||||
have -a = -0, by rwa neg_zero,
|
||||
have a = 0, from neg_inj this,
|
||||
by contradiction
|
||||
|
||||
protected lemma zero_ne_neg_of_ne {a : ℤ} (h : 0 ≠ a) : 0 ≠ -a :=
|
||||
ne.symm (int.neg_ne_zero_of_ne (ne.symm h))
|
||||
|
||||
protected lemma neg_ne_of_pos {a b : ℤ} : a > 0 → b > 0 → -a ≠ b :=
|
||||
λ h₁ h₂ h,
|
||||
begin
|
||||
|
|
@ -69,9 +78,9 @@ assume h,
|
|||
have of_nat (nat_abs a) = of_nat (nat_abs b), by rwa [of_nat_nat_abs_eq_of_nonneg ha, of_nat_nat_abs_eq_of_nonneg hb],
|
||||
begin injection this, contradiction end
|
||||
|
||||
protected lemma ne_of_nat_ne_pos_case {a b : ℤ} {n m : nat} (ha : a > 0) (hb : b > 0) (e1 : nat_abs a = n) (e2 : nat_abs b = m) (h : n ≠ m) : a ≠ b :=
|
||||
protected lemma ne_of_nat_ne_nonneg_case {a b : ℤ} {n m : nat} (ha : a ≥ 0) (hb : b ≥ 0) (e1 : nat_abs a = n) (e2 : nat_abs b = m) (h : n ≠ m) : a ≠ b :=
|
||||
have nat_abs a ≠ nat_abs b, by rwa [e1, e2],
|
||||
ne_of_nat_abs_ne_nat_abs_of_nonneg (le_of_lt ha) (le_of_lt hb) this
|
||||
ne_of_nat_abs_ne_nat_abs_of_nonneg ha hb this
|
||||
|
||||
/- 4. Aux lemmas for pushing nat_abs inside numerals
|
||||
nat_abs_zero and nat_abs_one are defined at init/data/int/basic.lean -/
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ meta constant mk_nat_val_le_proof : expr → expr → option expr
|
|||
meta constant mk_fin_val_ne_proof : expr → expr → option expr
|
||||
meta constant mk_char_val_ne_proof : expr → expr → option expr
|
||||
meta constant mk_string_val_ne_proof : expr → expr → option expr
|
||||
meta constant mk_int_val_ne_proof : expr → expr → option expr
|
||||
|
||||
namespace tactic
|
||||
open expr
|
||||
|
|
@ -50,6 +51,11 @@ do t ← target,
|
|||
pr ← returnopt (mk_string_val_ne_proof a b),
|
||||
exact pr)
|
||||
<|>
|
||||
(do is_def_eq type (const `int []),
|
||||
(a, b) ← returnopt (is_ne t),
|
||||
pr ← returnopt (mk_int_val_ne_proof a b),
|
||||
exact pr)
|
||||
<|>
|
||||
(do type ← whnf type,
|
||||
guard (is_napp_of type `fin 1),
|
||||
(a, b) ← returnopt (is_ne t),
|
||||
|
|
|
|||
|
|
@ -8,6 +8,12 @@ Author: Leonardo de Moura
|
|||
#include "library/string.h"
|
||||
#include "library/util.h"
|
||||
#include "library/constants.h"
|
||||
#include "library/comp_val.h"
|
||||
#include "library/expr_pair.h"
|
||||
#include "library/trace.h"
|
||||
|
||||
/* Remark: we can improve performance by using Lean macros for delaying the
|
||||
proof construction. */
|
||||
|
||||
namespace lean {
|
||||
optional<expr> mk_nat_val_ne_proof(expr const & a, expr const & b) {
|
||||
|
|
@ -178,6 +184,110 @@ optional<expr> mk_string_val_ne_proof(expr a, expr b) {
|
|||
return none_expr();
|
||||
}
|
||||
|
||||
optional<expr> mk_int_val_nonneg_proof(expr const & a) {
|
||||
if (auto a1 = is_bit0(a)) {
|
||||
if (auto pr = mk_int_val_nonneg_proof(*a1))
|
||||
return some_expr(mk_app(mk_constant(get_int_bit0_nonneg_name()), *a1, *pr));
|
||||
} else if (auto a1 = is_bit1(a)) {
|
||||
if (auto pr = mk_int_val_nonneg_proof(*a1))
|
||||
return some_expr(mk_app(mk_constant(get_int_bit1_nonneg_name()), *a1, *pr));
|
||||
} else if (is_one(a)) {
|
||||
return some_expr(mk_constant(get_int_one_nonneg_name()));
|
||||
} else if (is_zero(a)) {
|
||||
return some_expr(mk_constant(get_int_zero_nonneg_name()));
|
||||
}
|
||||
return none_expr();
|
||||
}
|
||||
|
||||
optional<expr> mk_int_val_pos_proof(expr const & a) {
|
||||
if (auto a1 = is_bit0(a)) {
|
||||
if (auto pr = mk_int_val_pos_proof(*a1))
|
||||
return some_expr(mk_app(mk_constant(get_int_bit0_pos_name()), *a1, *pr));
|
||||
} else if (auto a1 = is_bit1(a)) {
|
||||
if (auto pr = mk_int_val_nonneg_proof(*a1))
|
||||
return some_expr(mk_app(mk_constant(get_int_bit1_pos_name()), *a1, *pr));
|
||||
} else if (is_one(a)) {
|
||||
return some_expr(mk_constant(get_int_one_pos_name()));
|
||||
}
|
||||
return none_expr();
|
||||
}
|
||||
|
||||
/* Given a nonnegative int numeral a, return a pair (n, H)
|
||||
where n is a nat numeral, and (H : nat_abs a = n) */
|
||||
optional<expr_pair> mk_nat_abs_eq(expr const & a) {
|
||||
if (is_zero(a)) {
|
||||
return optional<expr_pair>(mk_pair(mk_nat_zero(), mk_constant(get_int_nat_abs_zero_name())));
|
||||
} else if (is_one(a)) {
|
||||
return optional<expr_pair>(mk_pair(mk_nat_one(), mk_constant(get_int_nat_abs_one_name())));
|
||||
} else if (auto a1 = is_bit0(a)) {
|
||||
if (auto p = mk_nat_abs_eq(*a1))
|
||||
return optional<expr_pair>(mk_pair(mk_nat_bit0(p->first),
|
||||
mk_app(mk_constant(get_int_nat_abs_bit0_step_name()), *a1, p->first, p->second)));
|
||||
} else if (auto a1 = is_bit1(a)) {
|
||||
if (auto p = mk_nat_abs_eq(*a1)) {
|
||||
expr new_n = mk_nat_bit1(p->first);
|
||||
expr Hnonneg = *mk_int_val_nonneg_proof(*a1);
|
||||
expr new_H = mk_app(mk_constant(get_int_nat_abs_bit1_nonneg_step_name()), *a1, p->first, Hnonneg, p->second);
|
||||
return optional<expr_pair>(mk_pair(new_n, new_H));
|
||||
}
|
||||
}
|
||||
return optional<expr_pair>();
|
||||
}
|
||||
|
||||
/* Given nonneg int numerals a and b, create a proof for a != b IF they are not equal. */
|
||||
optional<expr> mk_int_nonneg_val_ne_proof(expr const & a, expr const & b) {
|
||||
auto p1 = mk_nat_abs_eq(a);
|
||||
if (!p1) return none_expr();
|
||||
auto p2 = mk_nat_abs_eq(b);
|
||||
if (!p2) return none_expr();
|
||||
auto Ha_nonneg = mk_int_val_nonneg_proof(a);
|
||||
if (!Ha_nonneg) return none_expr();
|
||||
auto Hb_nonneg = mk_int_val_nonneg_proof(a);
|
||||
if (!Hb_nonneg) return none_expr();
|
||||
auto H_nat_ne = mk_nat_val_ne_proof(p1->first, p2->first);
|
||||
if (!H_nat_ne) return none_expr();
|
||||
expr H = mk_app({mk_constant(get_int_ne_of_nat_ne_nonneg_case_name()), a, b, p1->first, p2->first,
|
||||
*Ha_nonneg, *Hb_nonneg, p1->second, p2->second, *H_nat_ne});
|
||||
return some_expr(H);
|
||||
}
|
||||
|
||||
optional<expr> mk_int_val_ne_proof(expr const & a, expr const & b) {
|
||||
if (auto a1 = is_neg(a)) {
|
||||
if (auto b1 = is_neg(b)) {
|
||||
auto H = mk_int_nonneg_val_ne_proof(*a1, *b1);
|
||||
if (!H) return none_expr();
|
||||
return some_expr(mk_app(mk_constant(get_int_ne_neg_of_ne_name()), *a1, *b1, *H));
|
||||
} else {
|
||||
if (is_zero(b)) {
|
||||
auto H = mk_int_nonneg_val_ne_proof(*a1, b);
|
||||
if (!H) return none_expr();
|
||||
return some_expr(mk_app(mk_constant(get_int_neg_ne_zero_of_ne_name()), *a1, *H));
|
||||
} else {
|
||||
auto Ha1_nonneg = mk_int_val_pos_proof(*a1);
|
||||
if (!Ha1_nonneg) return none_expr();
|
||||
auto Hb_nonneg = mk_int_val_pos_proof(b);
|
||||
if (!Hb_nonneg) return none_expr();
|
||||
return some_expr(mk_app(mk_constant(get_int_neg_ne_of_pos_name()), *a1, b, *Ha1_nonneg, *Hb_nonneg));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (auto b1 = is_neg(b)) {
|
||||
if (is_zero(a)) {
|
||||
auto H = mk_int_nonneg_val_ne_proof(a, *b1);
|
||||
if (!H) return none_expr();
|
||||
return some_expr(mk_app(mk_constant(get_int_zero_ne_neg_of_ne_name()), *b1, *H));
|
||||
} else {
|
||||
auto Ha_nonneg = mk_int_val_pos_proof(a);
|
||||
if (!Ha_nonneg) return none_expr();
|
||||
auto Hb1_nonneg = mk_int_val_pos_proof(*b1);
|
||||
return some_expr(mk_app(mk_constant(get_int_ne_neg_of_pos_name()), a, *b1, *Ha_nonneg, *Hb1_nonneg));
|
||||
}
|
||||
} else {
|
||||
return mk_int_nonneg_val_ne_proof(a, b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void initialize_comp_val() {
|
||||
g_char_sz = new expr(to_nat_expr(mpz(256)));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,12 +31,25 @@ optional<expr> mk_nat_val_le_proof(expr const & a, expr const & b);
|
|||
/* Similar to mk_nat_val_ne_proof, but for fin type */
|
||||
optional<expr> mk_fin_val_ne_proof(expr const & a, expr const & b);
|
||||
|
||||
/* Similar to mk_char_val_ne_proof, but for char type */
|
||||
/* Similar to mk_nat_val_ne_proof, but for char type */
|
||||
optional<expr> mk_char_val_ne_proof(expr const & a, expr const & b);
|
||||
|
||||
/* Similar to mk_char_val_ne_proof, but for string type */
|
||||
/* Similar to mk_nat_val_ne_proof, but for string type */
|
||||
optional<expr> mk_string_val_ne_proof(expr a, expr b);
|
||||
|
||||
/* Return a proof for e >= 0 if e is a nonnegative int numeral.
|
||||
|
||||
\pre typeof(e) is int. */
|
||||
optional<expr> mk_int_val_nonneg_proof(expr const & e);
|
||||
|
||||
/* Return a proof for e > 0 if e is a nonnegative int numeral.
|
||||
|
||||
\pre typeof(e) is int. */
|
||||
optional<expr> mk_int_val_pos_proof(expr const & a);
|
||||
|
||||
/* Similar to mk_nat_val_ne_proof, but for int type */
|
||||
optional<expr> mk_int_val_ne_proof(expr const & a, expr const & b);
|
||||
|
||||
void initialize_comp_val();
|
||||
void finalize_comp_val();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -147,6 +147,23 @@ name const * g_int_has_le = nullptr;
|
|||
name const * g_int_has_lt = nullptr;
|
||||
name const * g_int_has_neg = nullptr;
|
||||
name const * g_int_has_mod = nullptr;
|
||||
name const * g_int_bit0_nonneg = nullptr;
|
||||
name const * g_int_bit1_nonneg = nullptr;
|
||||
name const * g_int_one_nonneg = nullptr;
|
||||
name const * g_int_zero_nonneg = nullptr;
|
||||
name const * g_int_bit0_pos = nullptr;
|
||||
name const * g_int_bit1_pos = nullptr;
|
||||
name const * g_int_one_pos = nullptr;
|
||||
name const * g_int_nat_abs_zero = nullptr;
|
||||
name const * g_int_nat_abs_one = nullptr;
|
||||
name const * g_int_nat_abs_bit0_step = nullptr;
|
||||
name const * g_int_nat_abs_bit1_nonneg_step = nullptr;
|
||||
name const * g_int_ne_of_nat_ne_nonneg_case = nullptr;
|
||||
name const * g_int_ne_neg_of_ne = nullptr;
|
||||
name const * g_int_neg_ne_of_pos = nullptr;
|
||||
name const * g_int_ne_neg_of_pos = nullptr;
|
||||
name const * g_int_neg_ne_zero_of_ne = nullptr;
|
||||
name const * g_int_zero_ne_neg_of_ne = nullptr;
|
||||
name const * g_int_decidable_linear_ordered_comm_group = nullptr;
|
||||
name const * g_io = nullptr;
|
||||
name const * g_io_functor = nullptr;
|
||||
|
|
@ -579,6 +596,23 @@ void initialize_constants() {
|
|||
g_int_has_lt = new name{"int", "has_lt"};
|
||||
g_int_has_neg = new name{"int", "has_neg"};
|
||||
g_int_has_mod = new name{"int", "has_mod"};
|
||||
g_int_bit0_nonneg = new name{"int", "bit0_nonneg"};
|
||||
g_int_bit1_nonneg = new name{"int", "bit1_nonneg"};
|
||||
g_int_one_nonneg = new name{"int", "one_nonneg"};
|
||||
g_int_zero_nonneg = new name{"int", "zero_nonneg"};
|
||||
g_int_bit0_pos = new name{"int", "bit0_pos"};
|
||||
g_int_bit1_pos = new name{"int", "bit1_pos"};
|
||||
g_int_one_pos = new name{"int", "one_pos"};
|
||||
g_int_nat_abs_zero = new name{"int", "nat_abs_zero"};
|
||||
g_int_nat_abs_one = new name{"int", "nat_abs_one"};
|
||||
g_int_nat_abs_bit0_step = new name{"int", "nat_abs_bit0_step"};
|
||||
g_int_nat_abs_bit1_nonneg_step = new name{"int", "nat_abs_bit1_nonneg_step"};
|
||||
g_int_ne_of_nat_ne_nonneg_case = new name{"int", "ne_of_nat_ne_nonneg_case"};
|
||||
g_int_ne_neg_of_ne = new name{"int", "ne_neg_of_ne"};
|
||||
g_int_neg_ne_of_pos = new name{"int", "neg_ne_of_pos"};
|
||||
g_int_ne_neg_of_pos = new name{"int", "ne_neg_of_pos"};
|
||||
g_int_neg_ne_zero_of_ne = new name{"int", "neg_ne_zero_of_ne"};
|
||||
g_int_zero_ne_neg_of_ne = new name{"int", "zero_ne_neg_of_ne"};
|
||||
g_int_decidable_linear_ordered_comm_group = new name{"int_decidable_linear_ordered_comm_group"};
|
||||
g_io = new name{"io"};
|
||||
g_io_functor = new name{"io", "functor"};
|
||||
|
|
@ -1012,6 +1046,23 @@ void finalize_constants() {
|
|||
delete g_int_has_lt;
|
||||
delete g_int_has_neg;
|
||||
delete g_int_has_mod;
|
||||
delete g_int_bit0_nonneg;
|
||||
delete g_int_bit1_nonneg;
|
||||
delete g_int_one_nonneg;
|
||||
delete g_int_zero_nonneg;
|
||||
delete g_int_bit0_pos;
|
||||
delete g_int_bit1_pos;
|
||||
delete g_int_one_pos;
|
||||
delete g_int_nat_abs_zero;
|
||||
delete g_int_nat_abs_one;
|
||||
delete g_int_nat_abs_bit0_step;
|
||||
delete g_int_nat_abs_bit1_nonneg_step;
|
||||
delete g_int_ne_of_nat_ne_nonneg_case;
|
||||
delete g_int_ne_neg_of_ne;
|
||||
delete g_int_neg_ne_of_pos;
|
||||
delete g_int_ne_neg_of_pos;
|
||||
delete g_int_neg_ne_zero_of_ne;
|
||||
delete g_int_zero_ne_neg_of_ne;
|
||||
delete g_int_decidable_linear_ordered_comm_group;
|
||||
delete g_io;
|
||||
delete g_io_functor;
|
||||
|
|
@ -1444,6 +1495,23 @@ name const & get_int_has_le_name() { return *g_int_has_le; }
|
|||
name const & get_int_has_lt_name() { return *g_int_has_lt; }
|
||||
name const & get_int_has_neg_name() { return *g_int_has_neg; }
|
||||
name const & get_int_has_mod_name() { return *g_int_has_mod; }
|
||||
name const & get_int_bit0_nonneg_name() { return *g_int_bit0_nonneg; }
|
||||
name const & get_int_bit1_nonneg_name() { return *g_int_bit1_nonneg; }
|
||||
name const & get_int_one_nonneg_name() { return *g_int_one_nonneg; }
|
||||
name const & get_int_zero_nonneg_name() { return *g_int_zero_nonneg; }
|
||||
name const & get_int_bit0_pos_name() { return *g_int_bit0_pos; }
|
||||
name const & get_int_bit1_pos_name() { return *g_int_bit1_pos; }
|
||||
name const & get_int_one_pos_name() { return *g_int_one_pos; }
|
||||
name const & get_int_nat_abs_zero_name() { return *g_int_nat_abs_zero; }
|
||||
name const & get_int_nat_abs_one_name() { return *g_int_nat_abs_one; }
|
||||
name const & get_int_nat_abs_bit0_step_name() { return *g_int_nat_abs_bit0_step; }
|
||||
name const & get_int_nat_abs_bit1_nonneg_step_name() { return *g_int_nat_abs_bit1_nonneg_step; }
|
||||
name const & get_int_ne_of_nat_ne_nonneg_case_name() { return *g_int_ne_of_nat_ne_nonneg_case; }
|
||||
name const & get_int_ne_neg_of_ne_name() { return *g_int_ne_neg_of_ne; }
|
||||
name const & get_int_neg_ne_of_pos_name() { return *g_int_neg_ne_of_pos; }
|
||||
name const & get_int_ne_neg_of_pos_name() { return *g_int_ne_neg_of_pos; }
|
||||
name const & get_int_neg_ne_zero_of_ne_name() { return *g_int_neg_ne_zero_of_ne; }
|
||||
name const & get_int_zero_ne_neg_of_ne_name() { return *g_int_zero_ne_neg_of_ne; }
|
||||
name const & get_int_decidable_linear_ordered_comm_group_name() { return *g_int_decidable_linear_ordered_comm_group; }
|
||||
name const & get_io_name() { return *g_io; }
|
||||
name const & get_io_functor_name() { return *g_io_functor; }
|
||||
|
|
|
|||
|
|
@ -149,6 +149,23 @@ name const & get_int_has_le_name();
|
|||
name const & get_int_has_lt_name();
|
||||
name const & get_int_has_neg_name();
|
||||
name const & get_int_has_mod_name();
|
||||
name const & get_int_bit0_nonneg_name();
|
||||
name const & get_int_bit1_nonneg_name();
|
||||
name const & get_int_one_nonneg_name();
|
||||
name const & get_int_zero_nonneg_name();
|
||||
name const & get_int_bit0_pos_name();
|
||||
name const & get_int_bit1_pos_name();
|
||||
name const & get_int_one_pos_name();
|
||||
name const & get_int_nat_abs_zero_name();
|
||||
name const & get_int_nat_abs_one_name();
|
||||
name const & get_int_nat_abs_bit0_step_name();
|
||||
name const & get_int_nat_abs_bit1_nonneg_step_name();
|
||||
name const & get_int_ne_of_nat_ne_nonneg_case_name();
|
||||
name const & get_int_ne_neg_of_ne_name();
|
||||
name const & get_int_neg_ne_of_pos_name();
|
||||
name const & get_int_ne_neg_of_pos_name();
|
||||
name const & get_int_neg_ne_zero_of_ne_name();
|
||||
name const & get_int_zero_ne_neg_of_ne_name();
|
||||
name const & get_int_decidable_linear_ordered_comm_group_name();
|
||||
name const & get_io_name();
|
||||
name const & get_io_functor_name();
|
||||
|
|
|
|||
|
|
@ -142,6 +142,23 @@ int.has_le
|
|||
int.has_lt
|
||||
int.has_neg
|
||||
int.has_mod
|
||||
int.bit0_nonneg
|
||||
int.bit1_nonneg
|
||||
int.one_nonneg
|
||||
int.zero_nonneg
|
||||
int.bit0_pos
|
||||
int.bit1_pos
|
||||
int.one_pos
|
||||
int.nat_abs_zero
|
||||
int.nat_abs_one
|
||||
int.nat_abs_bit0_step
|
||||
int.nat_abs_bit1_nonneg_step
|
||||
int.ne_of_nat_ne_nonneg_case
|
||||
int.ne_neg_of_ne
|
||||
int.neg_ne_of_pos
|
||||
int.ne_neg_of_pos
|
||||
int.neg_ne_zero_of_ne
|
||||
int.zero_ne_neg_of_ne
|
||||
int_decidable_linear_ordered_comm_group
|
||||
io
|
||||
io.functor
|
||||
|
|
|
|||
|
|
@ -80,8 +80,6 @@ public:
|
|||
expr from_mpq(mpq const &, expr const &);
|
||||
};
|
||||
|
||||
inline bool is_neg(expr const & e);
|
||||
|
||||
inline bool is_numeral(type_context & type_ctx, expr const & e) {
|
||||
return norm_num_context(type_ctx).is_numeral(e);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,6 +73,15 @@ bool is_num(expr const & e) {
|
|||
return is_num(e, true);
|
||||
}
|
||||
|
||||
bool is_signed_num(expr const & e) {
|
||||
if (is_num(e))
|
||||
return true;
|
||||
else if (auto r = is_neg(e))
|
||||
return is_num(*r);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
static optional<mpz> to_num(expr const & e, bool first) {
|
||||
if (is_zero(e)) {
|
||||
return first ? some(mpz(0)) : optional<mpz>();
|
||||
|
|
|
|||
|
|
@ -13,10 +13,14 @@ bool is_const_app(expr const &, name const &, unsigned);
|
|||
/** \brief Return true iff the given expression encodes a numeral. */
|
||||
bool is_num(expr const & e);
|
||||
|
||||
/** \brief Return true iff is_num(e) or \c e is of the form (- e') where to_num(e') */
|
||||
bool is_signed_num(expr const & e);
|
||||
|
||||
bool is_zero(expr const & e);
|
||||
bool is_one(expr const & e);
|
||||
optional<expr> is_bit0(expr const & e);
|
||||
optional<expr> is_bit1(expr const & e);
|
||||
optional<expr> is_neg(expr const & e);
|
||||
|
||||
/** \brief Return true iff \c n is zero, one, bit0 or bit1 */
|
||||
bool is_numeral_const_name(name const & n);
|
||||
|
|
|
|||
|
|
@ -461,24 +461,37 @@ expr mk_snd(abstract_type_context & ctx, expr const & p) {
|
|||
return mk_app(mk_constant(get_prod_snd_name(), const_levels(get_app_fn(AxB))), A, B, p);
|
||||
}
|
||||
|
||||
static expr * g_nat = nullptr;
|
||||
static expr * g_nat = nullptr;
|
||||
static expr * g_nat_zero = nullptr;
|
||||
static expr * g_nat_one = nullptr;
|
||||
static expr * g_nat_bit0_fn = nullptr;
|
||||
static expr * g_nat_bit1_fn = nullptr;
|
||||
static expr * g_nat_add_fn = nullptr;
|
||||
|
||||
expr mk_nat() {
|
||||
return *g_nat;
|
||||
static void initialize_nat() {
|
||||
g_nat = new expr(mk_constant(get_nat_name()));
|
||||
g_nat_zero = new expr(mk_app(mk_constant(get_zero_name(), {mk_level_one()}), {*g_nat, mk_constant(get_nat_has_zero_name())}));
|
||||
g_nat_one = new expr(mk_app(mk_constant(get_one_name(), {mk_level_one()}), {*g_nat, mk_constant(get_nat_has_one_name())}));
|
||||
g_nat_bit0_fn = new expr(mk_app(mk_constant(get_bit0_name(), {mk_level_one()}), {*g_nat, mk_constant(get_nat_has_add_name())}));
|
||||
g_nat_bit1_fn = new expr(mk_app(mk_constant(get_bit1_name(), {mk_level_one()}), {*g_nat, mk_constant(get_nat_has_one_name()), mk_constant(get_nat_has_add_name())}));
|
||||
g_nat_add_fn = new expr(mk_app(mk_constant(get_add_name(), {mk_level_one()}), {*g_nat, mk_constant(get_nat_has_add_name())}));
|
||||
}
|
||||
|
||||
expr mk_nat_zero() {
|
||||
return mk_app(mk_constant(get_zero_name(), {mk_level_one()}), {*g_nat, mk_constant(get_nat_has_zero_name())});
|
||||
static void finalize_nat() {
|
||||
delete g_nat;
|
||||
delete g_nat_zero;
|
||||
delete g_nat_one;
|
||||
delete g_nat_bit0_fn;
|
||||
delete g_nat_bit1_fn;
|
||||
delete g_nat_add_fn;
|
||||
}
|
||||
|
||||
expr mk_nat_one() {
|
||||
return mk_app(mk_constant(get_one_name(), {mk_level_one()}), {*g_nat, mk_constant(get_nat_has_one_name())});
|
||||
}
|
||||
|
||||
expr mk_nat_add(expr const & e1, expr const & e2) {
|
||||
expr nat_add = mk_app(mk_constant(get_add_name(), {mk_level_one()}), {*g_nat, mk_constant(get_nat_has_add_name())});
|
||||
return mk_app(nat_add, e1, e2);
|
||||
}
|
||||
expr mk_nat() { return *g_nat; }
|
||||
expr mk_nat_zero() { return *g_nat_zero; }
|
||||
expr mk_nat_one() { return *g_nat_one; }
|
||||
expr mk_nat_bit0(expr const & e) { return mk_app(*g_nat_bit0_fn, e); }
|
||||
expr mk_nat_bit1(expr const & e) { return mk_app(*g_nat_bit1_fn, e); }
|
||||
expr mk_nat_add(expr const & e1, expr const & e2) { return mk_app(*g_nat_add_fn, e1, e2); }
|
||||
|
||||
expr mk_unit(level const & l, bool prop) { return prop ? mk_true() : mk_unit(l); }
|
||||
expr mk_unit_mk(level const & l, bool prop) { return prop ? mk_true_intro() : mk_unit_mk(l); }
|
||||
|
|
@ -948,11 +961,11 @@ void initialize_library_util() {
|
|||
g_and_intro = new expr(mk_constant(get_and_intro_name()));
|
||||
g_and_elim_left = new expr(mk_constant(get_and_elim_left_name()));
|
||||
g_and_elim_right = new expr(mk_constant(get_and_elim_right_name()));
|
||||
g_nat = new expr(mk_constant(get_nat_name()));
|
||||
initialize_nat();
|
||||
}
|
||||
|
||||
void finalize_library_util() {
|
||||
delete g_nat;
|
||||
finalize_nat();
|
||||
delete g_true;
|
||||
delete g_true_intro;
|
||||
delete g_and;
|
||||
|
|
|
|||
|
|
@ -176,6 +176,8 @@ expr mk_snd(abstract_type_context & ctx, expr const & p, bool prop);
|
|||
expr mk_nat();
|
||||
expr mk_nat_zero();
|
||||
expr mk_nat_one();
|
||||
expr mk_nat_bit0(expr const & e);
|
||||
expr mk_nat_bit1(expr const & e);
|
||||
expr mk_nat_add(expr const & e1, expr const & e2);
|
||||
|
||||
bool is_ite(expr const & e, expr & c, expr & H, expr & A, expr & t, expr & f);
|
||||
|
|
|
|||
|
|
@ -397,6 +397,10 @@ vm_obj vm_mk_string_val_ne_proof(vm_obj const & a, vm_obj const & b) {
|
|||
return to_obj(mk_string_val_ne_proof(to_expr(a), to_expr(b)));
|
||||
}
|
||||
|
||||
vm_obj vm_mk_int_val_ne_proof(vm_obj const & a, vm_obj const & b) {
|
||||
return to_obj(mk_int_val_ne_proof(to_expr(a), to_expr(b)));
|
||||
}
|
||||
|
||||
void initialize_vm_expr() {
|
||||
DECLARE_VM_BUILTIN(name({"expr", "var"}), expr_var);
|
||||
DECLARE_VM_BUILTIN(name({"expr", "sort"}), expr_sort);
|
||||
|
|
@ -438,6 +442,7 @@ void initialize_vm_expr() {
|
|||
DECLARE_VM_BUILTIN(name("mk_fin_val_ne_proof"), vm_mk_fin_val_ne_proof);
|
||||
DECLARE_VM_BUILTIN(name("mk_char_val_ne_proof"), vm_mk_char_val_ne_proof);
|
||||
DECLARE_VM_BUILTIN(name("mk_string_val_ne_proof"), vm_mk_string_val_ne_proof);
|
||||
DECLARE_VM_BUILTIN(name("mk_int_val_ne_proof"), vm_mk_int_val_ne_proof);
|
||||
|
||||
// Not sure if we should expose these or what?
|
||||
DECLARE_VM_BUILTIN(name({"expr", "is_internal_cnstr"}), expr_is_internal_cnstr);
|
||||
|
|
|
|||
52
tests/lean/run/comp_val3.lean
Normal file
52
tests/lean/run/comp_val3.lean
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
open tactic
|
||||
|
||||
example : (1:int) ≠ 2 :=
|
||||
by comp_val
|
||||
|
||||
example : (1:int) ≠ 0 :=
|
||||
by comp_val
|
||||
|
||||
example : (0:int) ≠ 1 :=
|
||||
by comp_val
|
||||
|
||||
example : (3:int) ≠ 0 :=
|
||||
by comp_val
|
||||
|
||||
example : (2:int) ≠ 1 :=
|
||||
by comp_val
|
||||
|
||||
example : (3:int) ≠ -4 :=
|
||||
by comp_val
|
||||
|
||||
example : (3:int) ≠ 4 :=
|
||||
by comp_val
|
||||
|
||||
example : (100:int) ≠ 42919 :=
|
||||
by comp_val
|
||||
|
||||
example : 42919 ≠ (100:int) :=
|
||||
by comp_val
|
||||
|
||||
example : -(3:int) ≠ 49391 :=
|
||||
by comp_val
|
||||
|
||||
example : -(3:int) ≠ 3 :=
|
||||
by comp_val
|
||||
|
||||
example : -(100:int) ≠ -42919 :=
|
||||
by comp_val
|
||||
|
||||
example : 0 ≠ -(1:int) :=
|
||||
by comp_val
|
||||
|
||||
example : 0 ≠ -(100:int) :=
|
||||
by comp_val
|
||||
|
||||
example : 0 ≠ -(2:int) :=
|
||||
by comp_val
|
||||
|
||||
example : -(23:int) ≠ 0 :=
|
||||
by comp_val
|
||||
|
||||
example : -(1 : int) ≠ 0 :=
|
||||
by comp_val
|
||||
Loading…
Add table
Reference in a new issue