lean2/src/library/basic_thms.h
Leonardo de Moura b92bbeb83b Add casting propagation and normalization
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
2013-09-06 20:45:26 -07:00

124 lines
6.1 KiB
C++

/*
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 "builtin.h"
namespace lean {
expr mk_trivial();
/** \brief (Theorem) Trivial : True */
#define Trivial mk_trivial()
expr mk_true_ne_false();
/** \brief (Theorem) TrueNeFalse : Not(True = False) */
#define TrueNeFalse mk_true_ne_false();
expr mk_em_fn();
/** \brief (Theorem) a : Bool |- EM(a) : Or(a, Not(a)) */
inline expr EM(expr const & a) { return mk_app(mk_em_fn(), a); }
expr mk_false_elim_fn();
/** \brief (Theorem) a : Bool, H : False |- FalseElim(a, H) : a */
inline expr FalseElim(expr const & a, expr const & H) { return mk_app(mk_false_elim_fn(), a, H); }
expr mk_absurd_fn();
/** \brief (Theorem) {a : Bool}, H1 : a, H2 : Not(a) |- Absurd(a, H1, H2) : False */
inline expr Absurd(expr const & a, expr const & H1, expr const & H2) { return mk_app(mk_absurd_fn(), a, H1, H2); }
expr mk_double_neg_fn();
/** \brief (Theorem) a : Bool |- DoubleNeg(a) : Neg(Neg(a)) = a */
inline expr DoubleNeg(expr const & a) { return mk_app(mk_double_neg_fn(), a); }
expr mk_double_neg_elim_fn();
/** \brief (Theorem) {a : Bool}, {P : Bool -> Bool}, H : P (Not (Not a)) |- DoubleNegElim(a, P, H) : P a */
inline expr DoubleNegElim(expr const & a, expr const & P, expr const & H) { return mk_app(mk_double_neg_elim_fn(), a, P, H); }
expr mk_mt_fn();
/** \brief (Theorem) {a b : Bool}, H1 : a => b, H2 : Not(b) |- MT(a, b, H1, H2) : Not(a) */
inline expr MT(expr const & a, expr const & b, expr const & H1, expr const & H2) { return mk_app(mk_mt_fn(), a, b, H1, H2); }
expr mk_contrapos_fn();
/** \brief (Theorem) {a b : Bool}, H : a => b |- Contrapos(a, b, H): Neg(b) => Neg(a) */
inline expr Contrapos(expr const & a, expr const & b, expr const & H) { return mk_app(mk_contrapos_fn(), a, b, H); }
expr mk_false_imp_any_fn();
/** \brief (Theorem) a : Bool, H : False |- a */
inline expr FalseImpAny(expr const & a, expr const & H) { return mk_app(mk_false_imp_any_fn(), a, H); }
expr mk_eq_mp_fn();
/** \brief (Theorem) {a b : Bool}, H1 : a = b, H2 : a |- EqMP(a, b, H1, H2) : b */
inline expr EqMP(expr const & a, expr const & b, expr const & H1, expr const & H2) { return mk_app(mk_eq_mp_fn(), a, b, H1, H2); }
expr mk_not_imp1_fn();
/** \brief (Theorem) {a b : Bool}, H : Not(Implies(a, b)) |- NotImp1(a, b, H) : a */
inline expr NotImp1(expr const & a, expr const & b, expr const & H) { return mk_app(mk_not_imp1_fn(), a, b, H); }
expr mk_not_imp2_fn();
/** \brief (Theorem) {a b : Bool}, H : Not(Implies(a, b)) |- NotImp2(a, b, H) : Not(b) */
inline expr NotImp2(expr const & a, expr const & b, expr const & H) { return mk_app(mk_not_imp2_fn(), a, b, H); }
expr mk_conj_fn();
/** \brief (Theorem) {a b : Bool}, H1 : a, H2 : b |- Conj(a, b, H1, H2) : And(a, b) */
inline expr Conj(expr const & a, expr const & b, expr const & H1, expr const & H2) { return mk_app(mk_conj_fn(), a, b, H1, H2); }
expr mk_conjunct1_fn();
/** \brief (Theorem) {a b : Bool}, H : And(a, b) |- Conjunct1(a, b, H) : a */
inline expr Conjunct1(expr const & a, expr const & b, expr const & H) { return mk_app(mk_conjunct1_fn(), a, b, H); }
expr mk_conjunct2_fn();
/** \brief (Theorem) {a b : Bool}, H : And(a, b) |- Conjunct2(a, b, H) : b */
inline expr Conjunct2(expr const & a, expr const & b, expr const & H) { return mk_app(mk_conjunct2_fn(), a, b, H); }
expr mk_disj1_fn();
/** \brief (Theorem) a b : Bool, H : a |- Disj1(a, b, H) : Or(a, b) */
inline expr Disj1(expr const & a, expr const & b, expr const & H) { return mk_app(mk_disj1_fn(), a, b, H); }
expr mk_disj2_fn();
/** \brief (Theorem) {b} a : Bool, H : b |- Disj2(a, b, H) : Or(a, b) */
inline expr Disj2(expr const & b, expr const & a, expr const & H) { return mk_app(mk_disj2_fn(), b, a, H); }
expr mk_disj_cases_fn();
/** \brief (Theorem) {a b c : Bool}, H1 : Or(a,b), H2 : a -> c, H3 : b -> c |- DisjCases(a, b, c, H1, H2, H3) : c */
inline expr DisjCases(expr const & a, expr const & b, expr const & c, expr const & H1, expr const & H2, expr const & H3) { return mk_app({mk_disj_cases_fn(), a, b, c, H1, H2, H3}); }
expr mk_eqt_elim_fn();
/** \brief (Theorem) {a : Bool}, H : a = True |- EqTElim(a, H) : a */
inline expr EqTElim(expr const & a, expr const & H) { return mk_app(mk_eqt_elim_fn(), a, H); }
expr mk_eqt_intro_fn();
/** \brief (Theorem) {a : Bool}, H : a |- EqTIntro(a, H) : a = True */
inline expr EqTIntro(expr const & a, expr const & H) { return mk_app(mk_eqt_intro_fn(), a, H); }
expr mk_congr1_fn();
/** \brief (Theorem) {A : Type u}, {B : A -> Type u}, {f g : (Pi x : A, B x)}, a : A, H : f = g |- Congr2(A, B, f, g, a, H) : f a = g a */
inline expr Congr1(expr const & A, expr const & B, expr const & f, expr const & g, expr const & a, expr const & H) { return mk_app({mk_congr1_fn(), A, B, f, g, a, H}); }
expr mk_congr2_fn();
/** \brief (Theorem) {A : Type u}, {B : A -> Type u}, {a b : A}, f : (Pi x : A, B x), H : a = b |- Congr1(A, B, f, a, b, H) : f a = f b */
inline expr Congr2(expr const & A, expr const & B, expr const & a, expr const & b, expr const & f, expr const & H) { return mk_app({mk_congr2_fn(), A, B, a, b, f, H}); }
expr mk_congr_fn();
/** \brief (Theorem) {A : Type u}, {B : A -> Type u}, {f g : (Pi x : A, B x)}, {a b : A}, H1 : f = g, H2 : a = b |- Congr(A, B, f, g, a, b, H1, H2) : f a = g b */
inline expr Congr(expr const & A, expr const & B, expr const & f, expr const & g, expr const & a, expr const & b, expr const & H1, expr const & H2) { return mk_app({mk_congr_fn(), A, B, f, g, a, b, H1, H2}); }
expr mk_forall_elim_fn();
// \brief (Theorem) {A : Type u}, {P : A -> Bool}, H : (Forall A P), a : A |- Forallelim(A, P, H, a) : P a
inline expr ForallElim(expr const & A, expr const & P, expr const & H, expr const & a) { return mk_app(mk_forall_elim_fn(), A, P, H, a); }
/** \brief Add basic theorems to Environment */
void add_basic_thms(environment & env);
#if 0
expr mk_ext_fn();
bool is_ext_fn(expr const & e);
expr mk_foralli_fn();
bool is_foralli_fn(expr const & e);
expr mk_domain_inj_fn();
bool is_domain_inj_fn(expr const & e);
expr mk_range_inj_fn();
bool is_range_inj_fn(expr const & e);
#endif
}