/- Copyright (c) 2014 Microsoft Corporation. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Leonardo de Moura, Floris van Doorn -/ prelude import init.datatypes notation `assume` binders `,` r:(scoped f, f) := r notation `take` binders `,` r:(scoped f, f) := r structure has_zero [class] (A : Type) := (zero : A) structure has_one [class] (A : Type) := (one : A) structure has_add [class] (A : Type) := (add : A → A → A) definition zero [reducible] {A : Type} [s : has_zero A] : A := has_zero.zero A definition one [reducible] {A : Type} [s : has_one A] : A := has_one.one A definition add [reducible] {A : Type} [s : has_add A] : A → A → A := has_add.add definition bit0 [reducible] {A : Type} [s : has_add A] (a : A) : A := add a a definition bit1 [reducible] {A : Type} [s₁ : has_one A] [s₂ : has_add A] (a : A) : A := add (bit0 a) one definition num_has_zero [reducible] [instance] : has_zero num := has_zero.mk num.zero definition num_has_one [reducible] [instance] : has_one num := has_one.mk (num.pos pos_num.one) definition pos_num_has_one [reducible] [instance] : has_one pos_num := has_one.mk (pos_num.one) namespace pos_num open bool definition is_one (a : pos_num) : bool := pos_num.rec_on a tt (λn r, ff) (λn r, ff) definition pred (a : pos_num) : pos_num := pos_num.rec_on a one (λn r, bit0 n) (λn r, bool.rec_on (is_one n) (bit1 r) one) definition size (a : pos_num) : pos_num := pos_num.rec_on a one (λn r, succ r) (λn r, succ r) definition add (a b : pos_num) : pos_num := pos_num.rec_on a succ (λn f b, pos_num.rec_on b (succ (bit1 n)) (λm r, succ (bit1 (f m))) (λm r, bit1 (f m))) (λn f b, pos_num.rec_on b (bit1 n) (λm r, bit1 (f m)) (λm r, bit0 (f m))) b end pos_num definition pos_num_has_add [reducible] [instance] : has_add pos_num := has_add.mk pos_num.add namespace num open pos_num definition add (a b : num) : num := num.rec_on a b (λpa, num.rec_on b (pos pa) (λpb, pos (pos_num.add pa pb))) end num definition num_has_add [reducible] [instance] : has_add num := has_add.mk num.add definition std.priority.default : num := 1000 definition std.priority.max : num := 4294967295 /- Global declarations of right binding strength If a module reassigns these, it will be incompatible with other modules that adhere to these conventions. When hovering over a symbol, use "C-c C-k" to see how to input it. -/ definition std.prec.max : num := 1024 -- the strength of application, identifiers, (, [, etc. definition std.prec.arrow : num := 25 /- The next definition is "max + 10". It can be used e.g. for postfix operations that should be stronger than application. -/ definition std.prec.max_plus := num.succ (num.succ (num.succ (num.succ (num.succ (num.succ (num.succ (num.succ (num.succ (num.succ std.prec.max))))))))) /- Logical operations and relations -/ reserve prefix `¬`:40 reserve prefix `~`:40 reserve infixr ` ∧ `:35 reserve infixr ` /\ `:35 reserve infixr ` \/ `:30 reserve infixr ` ∨ `:30 reserve infix ` <-> `:20 reserve infix ` ↔ `:20 reserve infix ` = `:50 reserve infix ` ≠ `:50 reserve infix ` ≈ `:50 reserve infix ` ~ `:50 reserve infix ` ≡ `:50 reserve infixr ` ∘ `:60 -- input with \comp reserve postfix `⁻¹`:std.prec.max_plus -- input with \sy or \-1 or \inv reserve infixl ` ⬝ `:75 reserve infixr ` ▸ `:75 /- types and type constructors -/ reserve infixr ` ⊎ `:25 reserve infixr ` × `:30 /- arithmetic operations -/ reserve infixl ` + `:65 reserve infixl ` - `:65 reserve infixl ` * `:70 reserve infixl ` div `:70 reserve infixl ` mod `:70 reserve infixl ` / `:70 reserve prefix ` - `:100 reserve infix ` ^ `:80 reserve infix ` <= `:50 reserve infix ` ≤ `:50 reserve infix ` < `:50 reserve infix ` >= `:50 reserve infix ` ≥ `:50 reserve infix ` > `:50 /- boolean operations -/ reserve infixl ` && `:70 reserve infixl ` || `:65 /- set operations -/ reserve infix ` ∈ `:50 reserve infix ` ∉ `:50 reserve infixl ` ∩ `:70 reserve infixl ` ∪ `:65 reserve infix ` ⊆ `:50 reserve infix ` ⊇ `:50 /- other symbols -/ reserve infix ` ∣ `:50 reserve infixl ` ++ `:65 reserve infixr ` :: `:67