|
| 1 | +/- |
| 2 | +Copyright (c) 2018 Mario Carneiro. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Author: Mario Carneiro |
| 5 | +
|
| 6 | +A type for VM-erased data. |
| 7 | +-/ |
| 8 | + |
| 9 | +import data.set.basic data.equiv |
| 10 | + |
| 11 | +/-- `erased α` is the same as `α`, except that the elements |
| 12 | + of `erased α` are erased in the VM in the same way as types |
| 13 | + and proofs. This can be used to track data without storing it |
| 14 | + literally. -/ |
| 15 | +def erased (α : Sort*) : Sort* := |
| 16 | +Σ' s : α → Prop, ∃ a, (λ b, a = b) = s |
| 17 | + |
| 18 | +namespace erased |
| 19 | + |
| 20 | +@[inline] def mk {α} (a : α) : erased α := ⟨λ b, a = b, a, rfl⟩ |
| 21 | + |
| 22 | +noncomputable def out {α} : erased α → α |
| 23 | +| ⟨s, h⟩ := classical.some h |
| 24 | + |
| 25 | +@[reducible] def out_type (a : erased Sort*) : Sort* := out a |
| 26 | + |
| 27 | +theorem out_proof {p : Prop} (a : erased p) : p := out a |
| 28 | + |
| 29 | +@[simp] theorem out_mk {α} (a : α) : (mk a).out = a := |
| 30 | +begin |
| 31 | + let h, show classical.some h = a, |
| 32 | + have := classical.some_spec h, |
| 33 | + exact cast (congr_fun this a).symm rfl |
| 34 | +end |
| 35 | + |
| 36 | +@[simp] theorem mk_out {α} : ∀ (a : erased α), mk (out a) = a |
| 37 | +| ⟨s, h⟩ := by simp [mk]; congr; exact classical.some_spec h |
| 38 | + |
| 39 | +noncomputable def equiv (α) : erased α ≃ α := |
| 40 | +⟨out, mk, mk_out, out_mk⟩ |
| 41 | + |
| 42 | +instance (α : Type*) : has_repr (erased α) := ⟨λ _, "erased"⟩ |
| 43 | + |
| 44 | +def choice {α} (h : nonempty α) : erased α := mk (classical.choice h) |
| 45 | + |
| 46 | +theorem nonempty_iff {α} : nonempty (erased α) ↔ nonempty α := |
| 47 | +⟨λ ⟨a⟩, ⟨a.out⟩, λ ⟨a⟩, ⟨mk a⟩⟩ |
| 48 | + |
| 49 | +instance {α} [h : nonempty α] : nonempty (erased α) := |
| 50 | +erased.nonempty_iff.2 h |
| 51 | + |
| 52 | +instance {α} [h : inhabited α] : inhabited (erased α) := |
| 53 | +⟨mk (default _)⟩ |
| 54 | + |
| 55 | +def bind {α β} (a : erased α) (f : α → erased β) : erased β := |
| 56 | +⟨λ b, (f a.out).1 b, (f a.out).2⟩ |
| 57 | + |
| 58 | +@[simp] theorem bind_eq_out {α β} (a f) : @bind α β a f = f a.out := |
| 59 | +by delta bind bind._proof_1; cases f a.out; refl |
| 60 | + |
| 61 | +def join {α} (a : erased (erased α)) : erased α := bind a id |
| 62 | + |
| 63 | +@[simp] theorem join_eq_out {α} (a) : @join α a = a.out := bind_eq_out _ _ |
| 64 | + |
| 65 | +instance : monad erased := { pure := @mk, bind := @bind } |
| 66 | + |
| 67 | +instance : is_lawful_monad erased := by refine {..}; intros; simp |
| 68 | + |
| 69 | +end erased |
0 commit comments