refactor(frontends/lean): remove notation for creating tuples

Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
Leonardo de Moura 2014-02-10 09:03:42 -08:00
parent 4e08a3233e
commit a2d2e36f04
21 changed files with 76 additions and 127 deletions

View file

@ -778,8 +778,6 @@ theorem proj2_congr {A B : (Type U)} {a b : A # B} (H : a = b) : proj2 a = proj2
theorem hproj2_congr {A : (Type U)} {B : A → (Type U)} {a b : sig x, B x} (H : a = b) : proj2 a == proj2 b theorem hproj2_congr {A : (Type U)} {B : A → (Type U)} {a b : sig x, B x} (H : a = b) : proj2 a == proj2 b
:= subst (hrefl (proj2 a)) H := subst (hrefl (proj2 a)) H
definition pair {A : (Type U)} {B : A → (Type U)} (a : A) (b : B a) := tuple (sig x : A, B x) : a, b
-- Up to this point, we proved all theorems using just reflexivity, substitution and case (proof by cases) -- Up to this point, we proved all theorems using just reflexivity, substitution and case (proof by cases)
-- Function extensionality -- Function extensionality

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -14,7 +14,7 @@ definition abst {A : (Type U)} {P : A → Bool} (r : A) (H : inhabited (subtype
theorem subtype_inhabited {A : (Type U)} {P : A → Bool} (H : ∃ x, P x) : inhabited (subtype A P) theorem subtype_inhabited {A : (Type U)} {P : A → Bool} (H : ∃ x, P x) : inhabited (subtype A P)
:= obtain (w : A) (Hw : P w), from H, := obtain (w : A) (Hw : P w), from H,
inhabited_intro (tuple (subtype A P) : w, Hw) inhabited_intro (pair w Hw)
theorem P_rep {A : (Type U)} {P : A → Bool} (a : subtype A P) : P (rep a) theorem P_rep {A : (Type U)} {P : A → Bool} (a : subtype A P) : P (rep a)
:= proj2 a := proj2 a
@ -23,7 +23,7 @@ theorem rep_inj {A : (Type U)} {P : A → Bool} {a b : subtype A P} (H : rep a =
:= pairext _ _ H (hproof_irrel (proj2 a) (proj2 b)) := pairext _ _ H (hproof_irrel (proj2 a) (proj2 b))
theorem ex_abst {A : (Type U)} {P : A → Bool} {r : A} (H : P r) : ∃ a, rep a = r theorem ex_abst {A : (Type U)} {P : A → Bool} {r : A} (H : P r) : ∃ a, rep a = r
:= exists_intro (tuple (subtype A P) : r, H) (refl r) := exists_intro (pair r H) (refl r)
theorem abst_rep {A : (Type U)} {P : A → Bool} (H : inhabited (subtype A P)) (a : subtype A P) theorem abst_rep {A : (Type U)} {P : A → Bool} (H : inhabited (subtype A P)) (a : subtype A P)
: abst (rep a) H = a : abst (rep a) H = a
@ -33,7 +33,7 @@ theorem abst_rep {A : (Type U)} {P : A → Bool} (H : inhabited (subtype A P)) (
theorem rep_abst {A : (Type U)} {P : A → Bool} (H : inhabited (subtype A P)) : ∀ r, P r → rep (abst r H) = r theorem rep_abst {A : (Type U)} {P : A → Bool} (H : inhabited (subtype A P)) : ∀ r, P r → rep (abst r H) = r
:= take r, assume Hl : P r, := take r, assume Hl : P r,
@eps_ax (subtype A P) H (λ x, rep x = r) (tuple (subtype A P) : r, Hl) (refl r) @eps_ax (subtype A P) H (λ x, rep x = r) (pair r Hl) (refl r)
theorem abst_inj {A : (Type U)} {P : A → Bool} (H : inhabited (subtype A P)) {r r' : A} : theorem abst_inj {A : (Type U)} {P : A → Bool} (H : inhabited (subtype A P)) {r r' : A} :
P r → P r' → abst r H = abst r' H → r = r' P r → P r' → abst r H = abst r' H → r = r'

View file

@ -861,61 +861,26 @@ expr parser_imp::parse_type(bool level_expected) {
} }
} }
expr parser_imp::parse_tuple() { expr parser_imp::parse_pair() {
auto p = pos(); auto p = pos();
next(); next();
buffer<expr> args; buffer<expr> args;
expr first = parse_expr(); expr first = parse_expr(g_app_precedence);
expr second = parse_expr(g_app_precedence);
expr type; expr type;
if (curr_is_colon()) { if (curr_is_colon()) {
next(); next();
type = first; type = parse_expr();
args.push_back(parse_expr());
} else { } else {
args.push_back(first);
type = save(mk_placeholder(), p); type = save(mk_placeholder(), p);
} }
while (curr_is_comma()) { return save(mk_pair(first, second, type), p);
next();
args.push_back(parse_expr());
}
unsigned num = args.size();
if (num < 2)
throw parser_error("invalid tuple/pair, it must have at least two arguments", p);
if (num == 2) {
return save(mk_pair(args[num-2], args[num-1], type), p);
} else {
expr r = save(mk_pair(args[num-2], args[num-1], save(mk_placeholder(), p)), p);
unsigned i = num-2;
while (true) {
lean_assert(i > 0);
--i;
if (i == 0) {
return save(mk_pair(args[0], r, type), p);
} else {
r = save(mk_pair(args[i], r, save(mk_placeholder(), p)), p);
}
}
}
} }
expr parser_imp::parse_proj(bool first) { expr parser_imp::parse_proj(bool first) {
auto p = pos(); auto p = pos();
next(); next();
unsigned i = 0;
if (curr() == scanner::token::IntVal) {
i = parse_unsigned("invalid tuple/pair projection, index does not fit in a machine integer");
if (i == 0)
throw parser_error("invalid tuple/pair projection, optional index must be >= 1", p);
if (i > LEAN_MAX_PROJECTION)
throw parser_error(sstream() << "invalid tuple/pair projection, optional index is >= "
<< LEAN_MAX_PROJECTION << " (internal limit)", p);
}
expr t = parse_expr(g_app_precedence); expr t = parse_expr(g_app_precedence);
while (i > 0) {
--i;
t = save(mk_proj2(t), p);
}
if (first) if (first)
return save(mk_proj1(t), p); return save(mk_proj1(t), p);
else else
@ -1069,7 +1034,7 @@ expr parser_imp::parse_nud() {
case scanner::token::Show: return parse_show_expr(); case scanner::token::Show: return parse_show_expr();
case scanner::token::Have: return parse_have_expr(); case scanner::token::Have: return parse_have_expr();
case scanner::token::By: return parse_by_expr(); case scanner::token::By: return parse_by_expr();
case scanner::token::Tuple: return parse_tuple(); case scanner::token::Pair: return parse_pair();
case scanner::token::Proj1: return parse_proj(true); case scanner::token::Proj1: return parse_proj(true);
case scanner::token::Proj2: return parse_proj(false); case scanner::token::Proj2: return parse_proj(false);
default: default:

View file

@ -326,7 +326,7 @@ private:
expr parse_exists(); expr parse_exists();
expr parse_let(); expr parse_let();
expr parse_type(bool level_expected); expr parse_type(bool level_expected);
expr parse_tuple(); expr parse_pair();
expr parse_proj(bool first); expr parse_proj(bool first);
tactic parse_tactic_macro(name tac_id, pos_info const & p); tactic parse_tactic_macro(name tac_id, pos_info const & p);
expr parse_show_expr(); expr parse_show_expr();

View file

@ -76,7 +76,7 @@ static format g_ellipsis_n_fmt= highlight(format("\u2026"));
static format g_ellipsis_fmt = highlight(format("...")); static format g_ellipsis_fmt = highlight(format("..."));
static format g_let_fmt = highlight_keyword(format("let")); static format g_let_fmt = highlight_keyword(format("let"));
static format g_in_fmt = highlight_keyword(format("in")); static format g_in_fmt = highlight_keyword(format("in"));
static format g_tuple_fmt = highlight_keyword(format("tuple")); static format g_pair_fmt = highlight_keyword(format("pair"));
static format g_proj1_fmt = highlight_keyword(format("proj1")); static format g_proj1_fmt = highlight_keyword(format("proj1"));
static format g_proj2_fmt = highlight_keyword(format("proj2")); static format g_proj2_fmt = highlight_keyword(format("proj2"));
static format g_assign_fmt = highlight_keyword(format(":=")); static format g_assign_fmt = highlight_keyword(format(":="));
@ -1120,33 +1120,24 @@ class pp_fn {
} }
} }
result pp_tuple(expr a, unsigned depth) { result pp_pair(expr a, unsigned depth) {
buffer<expr> args; buffer<expr> args;
args.push_back(pair_first(a)); unsigned indent = 5;
expr t = pair_type(a); format r_format = g_pair_fmt;
bool cartesian = is_cartesian(t);
while (is_dep_pair(pair_second(a)) && !has_metavar(pair_second(a))) {
a = pair_second(a);
if (!is_cartesian(pair_type(a)))
cartesian = false;
args.push_back(pair_first(a));
}
args.push_back(pair_second(a));
unsigned indent = 6;
format r_format = g_tuple_fmt;
unsigned r_weight = 1; unsigned r_weight = 1;
if (!cartesian) {
auto f_r = pp_child(pair_first(a), depth);
auto s_r = pp_child(pair_second(a), depth);
r_format += nest(indent, compose(line(), f_r.first));
r_format += nest(indent, compose(line(), s_r.first));
r_weight += f_r.second + s_r.second;
expr t = pair_type(a);
if (!is_cartesian(t)) {
auto t_r = pp_child(t, depth); auto t_r = pp_child(t, depth);
r_format += nest(indent, compose(line(), format{t_r.first, space(), colon()})); r_format += nest(indent, compose(line(), format{colon(), space(), t_r.first}));
r_weight += t_r.second; r_weight += t_r.second;
} }
for (unsigned i = 0; i < args.size(); i++) {
auto arg_r = pp_child(args[i], depth);
if (i > 0)
r_format += comma();
r_format += nest(indent, compose(line(), arg_r.first));
r_weight += arg_r.second;
}
return result(group(r_format), r_weight); return result(group(r_format), r_weight);
} }
@ -1211,7 +1202,7 @@ class pp_fn {
case expr_kind::Let: r = pp_let(e, depth); break; case expr_kind::Let: r = pp_let(e, depth); break;
case expr_kind::MetaVar: r = pp_metavar(e, depth); break; case expr_kind::MetaVar: r = pp_metavar(e, depth); break;
case expr_kind::HEq: r = pp_heq(e, depth); break; case expr_kind::HEq: r = pp_heq(e, depth); break;
case expr_kind::Pair: r = pp_tuple(e, depth); break; case expr_kind::Pair: r = pp_pair(e, depth); break;
case expr_kind::Proj: r = pp_proj(e, depth); break; case expr_kind::Proj: r = pp_proj(e, depth); break;
} }
} }

View file

@ -32,7 +32,7 @@ static name g_have_name("have");
static name g_show_name("show"); static name g_show_name("show");
static name g_by_name("by"); static name g_by_name("by");
static name g_sig_name("sig"); static name g_sig_name("sig");
static name g_tuple_name("tuple"); static name g_pair_name("pair");
static name g_proj1_name("proj1"); static name g_proj1_name("proj1");
static name g_proj2_name("proj2"); static name g_proj2_name("proj2");
static name g_cartesian_product_unicode("\u2A2F"); static name g_cartesian_product_unicode("\u2A2F");
@ -215,8 +215,8 @@ scanner::token scanner::read_a_symbol() {
return token::In; return token::In;
} else if (m_name_val == g_sig_name) { } else if (m_name_val == g_sig_name) {
return token::Sig; return token::Sig;
} else if (m_name_val == g_tuple_name) { } else if (m_name_val == g_pair_name) {
return token::Tuple; return token::Pair;
} else if (m_name_val == g_proj1_name) { } else if (m_name_val == g_proj1_name) {
return token::Proj1; return token::Proj1;
} else if (m_name_val == g_proj2_name) { } else if (m_name_val == g_proj2_name) {
@ -471,7 +471,7 @@ std::ostream & operator<<(std::ostream & out, scanner::token const & t) {
case scanner::token::Sig: out << "sig"; break; case scanner::token::Sig: out << "sig"; break;
case scanner::token::Proj1: out << "proj1"; break; case scanner::token::Proj1: out << "proj1"; break;
case scanner::token::Proj2: out << "proj2"; break; case scanner::token::Proj2: out << "proj2"; break;
case scanner::token::Tuple: out << "tuple"; break; case scanner::token::Pair: out << "pair"; break;
case scanner::token::Placeholder: out << "_"; break; case scanner::token::Placeholder: out << "_"; break;
case scanner::token::ScriptBlock: out << "Script"; break; case scanner::token::ScriptBlock: out << "Script"; break;
case scanner::token::CartesianProduct: out << "#"; break; case scanner::token::CartesianProduct: out << "#"; break;

View file

@ -20,7 +20,7 @@ class scanner {
public: public:
enum class token { enum class token {
LeftParen, RightParen, LeftCurlyBracket, RightCurlyBracket, Colon, Comma, Period, Lambda, Pi, Arrow, LeftParen, RightParen, LeftCurlyBracket, RightCurlyBracket, Colon, Comma, Period, Lambda, Pi, Arrow,
HEq, Sig, Tuple, Proj1, Proj2, Let, In, Exists, Id, CommandId, IntVal, DecimalVal, StringVal, Assign, Type, Placeholder, HEq, Sig, Pair, Proj1, Proj2, Let, In, Exists, Id, CommandId, IntVal, DecimalVal, StringVal, Assign, Type, Placeholder,
Have, Show, By, ScriptBlock, Ellipsis, CartesianProduct, Eof Have, Show, By, ScriptBlock, Ellipsis, CartesianProduct, Eof
}; };
protected: protected:

View file

@ -167,7 +167,6 @@ MK_CONSTANT(allext_fn, name("allext"));
MK_CONSTANT(proj1_congr_fn, name("proj1_congr")); MK_CONSTANT(proj1_congr_fn, name("proj1_congr"));
MK_CONSTANT(proj2_congr_fn, name("proj2_congr")); MK_CONSTANT(proj2_congr_fn, name("proj2_congr"));
MK_CONSTANT(hproj2_congr_fn, name("hproj2_congr")); MK_CONSTANT(hproj2_congr_fn, name("hproj2_congr"));
MK_CONSTANT(pair_fn, name("pair"));
MK_CONSTANT(funext_fn, name("funext")); MK_CONSTANT(funext_fn, name("funext"));
MK_CONSTANT(eta_fn, name("eta")); MK_CONSTANT(eta_fn, name("eta"));
MK_CONSTANT(eps_fn, name("eps")); MK_CONSTANT(eps_fn, name("eps"));

View file

@ -485,10 +485,6 @@ inline expr mk_proj2_congr_th(expr const & e1, expr const & e2, expr const & e3,
expr mk_hproj2_congr_fn(); expr mk_hproj2_congr_fn();
bool is_hproj2_congr_fn(expr const & e); bool is_hproj2_congr_fn(expr const & e);
inline expr mk_hproj2_congr_th(expr const & e1, expr const & e2, expr const & e3, expr const & e4, expr const & e5) { return mk_app({mk_hproj2_congr_fn(), e1, e2, e3, e4, e5}); } inline expr mk_hproj2_congr_th(expr const & e1, expr const & e2, expr const & e3, expr const & e4, expr const & e5) { return mk_app({mk_hproj2_congr_fn(), e1, e2, e3, e4, e5}); }
expr mk_pair_fn();
bool is_pair_fn(expr const & e);
inline bool is_pair(expr const & e) { return is_app(e) && is_pair_fn(arg(e, 0)) && num_args(e) == 5; }
inline expr mk_pair(expr const & e1, expr const & e2, expr const & e3, expr const & e4) { return mk_app({mk_pair_fn(), e1, e2, e3, e4}); }
expr mk_funext_fn(); expr mk_funext_fn();
bool is_funext_fn(expr const & e); bool is_funext_fn(expr const & e);
inline expr mk_funext_th(expr const & e1, expr const & e2, expr const & e3, expr const & e4, expr const & e5) { return mk_app({mk_funext_fn(), e1, e2, e3, e4, e5}); } inline expr mk_funext_th(expr const & e1, expr const & e2, expr const & e3, expr const & e4, expr const & e5) { return mk_app({mk_funext_fn(), e1, e2, e3, e4, e5}); }

View file

@ -1,14 +1,14 @@
check sig x : Nat, x > 0 check sig x : Nat, x > 0
check tuple 10, 20 check pair 10 20
check tuple 10, true check pair 10 true
check tuple true, 20 check pair true 20
check tuple Bool # Nat : true, 20 check pair true 20 : Bool # Nat
check tuple true, true check pair true true
check tuple Bool Bool : true, true check pair true true : Bool Bool
variable a : Nat variable a : Nat
axiom Ha : 1 ≤ a axiom Ha : 1 ≤ a
definition NZ : Type := sig x : Nat, 1 ≤ x definition NZ : Type := sig x : Nat, 1 ≤ x
check NZ check NZ
check tuple NZ : a, Ha check pair a Ha : NZ
check tuple Nat # Nat : true, 20 check pair true 20 : Nat # Nat
check tuple Bool # Bool : true, 20 check pair true 20 : Bool # Bool

View file

@ -1,25 +1,25 @@
Set: pp::colors Set: pp::colors
Set: pp::unicode Set: pp::unicode
sig x : , x > 0 : Type sig x : , x > 0 : Type
tuple 10, 20 : pair 10 20 :
tuple 10, : Bool pair 10 : Bool
tuple , 20 : Bool pair 20 : Bool
tuple , 20 : Bool pair 20 : Bool
tuple , : Bool Bool pair : Bool Bool
tuple , : Bool Bool pair : Bool Bool
Assumed: a Assumed: a
Assumed: Ha Assumed: Ha
Defined: NZ Defined: NZ
NZ : Type NZ : Type
tuple NZ : a, Ha : sig x : , 1 ≤ x pair a Ha : NZ : sig x : , 1 ≤ x
sig2.lean:13:6: error: type mismatch in the 1st argument of the pair sig2.lean:13:6: error: type mismatch in the 1st argument of the pair
tuple , 20 pair 20
Pair type: Pair type:
Argument type: Argument type:
Bool Bool
sig2.lean:14:6: error: type mismatch in the 2nd argument of the pair sig2.lean:14:6: error: type mismatch in the 2nd argument of the pair
tuple , 20 pair 20
Pair type: Pair type:
Bool Bool Bool Bool
Argument type: Argument type:

View file

@ -1,3 +1,3 @@
check tuple 10, 20 check pair 10 20
check tuple 10, 20, 30 check pair 10 (pair 20 30)
check tuple 10, true, (λ x : Nat, x > 10) check pair 10 (pair true (λ x : Nat, x > 10))

View file

@ -1,5 +1,5 @@
Set: pp::colors Set: pp::colors
Set: pp::unicode Set: pp::unicode
tuple 10, 20 : pair 10 20 :
tuple 10, 20, 30 : pair 10 (pair 20 30) :
tuple 10, , (λ x : , x > 10) : Bool ( → Bool) pair 10 (pair (λ x : , x > 10)) : Bool ( → Bool)

View file

@ -1,10 +1,10 @@
check proj1 (tuple 10, 20) check proj1 (pair 10 20)
eval proj1 (tuple 10, 20) eval proj1 (pair 10 20)
eval proj2 (tuple 10, 20) eval proj2 (pair 10 20)
eval proj2 (tuple 10, 20, 30) eval proj2 (pair 10 (pair 20 30))
eval proj1 1 (tuple 10, 20, 30, 40) eval proj1 (pair 10 (pair 20 30))
eval proj1 2 (tuple 10, 20, 30, 40) eval proj1 (proj2 (pair 10 (pair 20 30)))
eval proj2 2 (tuple 10, 20, 30, 40) eval proj2 (proj2 (proj2 (pair 10 (pair 20 (pair 30 40)))))
definition NZ : Type := sig x : Nat, 1 ≤ x definition NZ : Type := sig x : Nat, 1 ≤ x
variable t : NZ variable t : NZ
check proj1 t check proj1 t

View file

@ -1,11 +1,11 @@
Set: pp::colors Set: pp::colors
Set: pp::unicode Set: pp::unicode
proj1 (tuple 10, 20) : proj1 (pair 10 20) :
10 10
20 20
tuple 20, 30 pair 20 30
10
20 20
30
40 40
Defined: NZ Defined: NZ
Assumed: t Assumed: t

View file

@ -2,8 +2,8 @@ variable vec : Nat → Type
definition vec_with_len := sig len, vec len definition vec_with_len := sig len, vec len
variable n : Nat variable n : Nat
variable v : vec n variable v : vec n
check tuple n, v check pair n v
check (show vec_with_len, from tuple n, v) check (show vec_with_len, from pair n v)
check (let v2 : vec_with_len := tuple n, v check (let v2 : vec_with_len := pair n v
in v2) in v2)
check (tuple vec_with_len : n, v) check (pair n v : vec_with_len)

View file

@ -4,7 +4,7 @@
Defined: vec_with_len Defined: vec_with_len
Assumed: n Assumed: n
Assumed: v Assumed: v
tuple n, v : vec n pair n v : vec n
let H_show : vec_with_len := tuple (sig x : , vec x) : n, v in H_show : vec_with_len let H_show : vec_with_len := pair n v : (sig x : , vec x) in H_show : vec_with_len
let v2 : vec_with_len := tuple (sig x : , vec x) : n, v in v2 : vec_with_len let v2 : vec_with_len := pair n v : (sig x : , vec x) in v2 : vec_with_len
tuple vec_with_len : n, v : sig len : , vec len pair n v : vec_with_len : sig len : , vec len

View file

@ -1,8 +1,8 @@
variables A B : (Type U) variables A B : (Type U)
variables t1 t2 : A B variables t1 t2 : A B
axiom pair_Ax {A : (Type U)} {B : A → (Type U)} (p : sig x, B x) : (tuple (sig x, B x) : (proj1 p), (proj2 p)) = p axiom pair_Ax {A : (Type U)} {B : A → (Type U)} (p : sig x, B x) : (pair (proj1 p) (proj2 p) : sig x, B x) = p
theorem spairext {A B : (Type U)} {p1 p2 : A B} (H1 : proj1 p1 = proj1 p2) (H2 : proj2 p1 = proj2 p2) : p1 = p2 theorem spairext {A B : (Type U)} {p1 p2 : A B} (H1 : proj1 p1 = proj1 p2) (H2 : proj2 p1 = proj2 p2) : p1 = p2
:= calc p1 = tuple (proj1 p1), (proj2 p1) : symm (pair_Ax p1) := calc p1 = (pair (proj1 p1) (proj2 p1)) : symm (pair_Ax p1)
... = tuple (proj1 p2), (proj2 p1) : { H1 } ... = (pair (proj1 p2) (proj2 p1)) : { H1 }
... = tuple (proj1 p2), (proj2 p2) : { H2 } ... = (pair (proj1 p2) (proj2 p2)) : { H2 }
... = p2 : pair_Ax p2 ... = p2 : pair_Ax p2