import math.alexandroff_space math.notation
open set topological_space classical
set_option pp.generalized_field_notation true
local attribute [instance] prop_decidable
noncomputable theory
universe u

/-!
# A topological formal ontology and foundation of philosophy

  The purpose of this work is to implement in the Lean Theorem Prover an
  upper level ontology that minimizes the number of primitive concepts and axioms,
  while maximizing explanatory power with regards to the interpretability of
  philosophical concepts in the theory. We seek to give to the whole of philosophy the same sort
  of rigorous foundation that set/type theory gave to mathematics, without having to rely
  on the introduction of a primitive concept for almost every new concept of philosophy.
  The most basic version of our theory admits of only two primitives: possible worlds and existential events,
  everything else being defined in terms of those, in much the same way that everything in mathematics can be
  defined in terms of the primitive notions of set and set-membership.
  We name our theory simply as the **Topological Ontology**.

  Among other things, we seek to precisely define in our theory the concepts of: substance, simple substance,
  composite substance, physical substance, metaphysical substance, accident, property, positive property,
  essence and existence, causality, parthood, God, theism,
  atheism, physicalism, monism, pantheism, eleaticism, platonism, modal realism, etc...
  We also seek to formalize theories of: causality, counterfactuals, mereology,
  epistemology, ethics, philosophy of nature, metaphysics and natural theology.

  And in a higher order extension of our theory, we also seek to define: concept/abstract object,
  the process of abstraction, universal, matter, form, the categories of being, the post-predicaments, etc...

  All of it based on the foundation of possible worlds and existential events. Pretty audacious, ain't it?

## Ontologies and Events

  The fundamental concept upon which all of our work is based, is the concept of an *ontology of possible worlds*.
  Which is to be comprised of a Type of possible worlds equipped with some fundamental topological structure,
  the philosophical significance of which shall be made clear shortly.

  The notion of possible world is of course a primitive one, and you may interpret it as you will.
  We take a possible world in our theory to be a point in the phase space of the whole of possible reality,
  a fully qualified description of a possible state of existence,
  an outcome of the most general random experiment one could possible think of, etc...

  For simplicity, we  will also consider that possible worlds are *atomic truth-indexers*. This is to say that
  they are truth-indexers, i.e. things with respect to which propositions are said to be true or false
  (*tertium non datur*) but which cannot be thought to be composed of further things which have this property.
  In particular, our possible worlds will not have any intrinsic temporal or spatial structure, so it will simply
  *not make sense* at first to say that some event like "Socrates is sitting" will occur in
  the future of a possible world `w`, it will not make sense to claim "Socrates will sit in the future" is true at `w`,
  at least initially. Later on, by equipping our topological space of possible worlds with additional temporal structure,
  we *will* be able to make sense of these claims by defining timelines in terms of continuous paths of possible worlds.
  In this manner we can think of possible worlds as being possible spatio-temporal locations in possible space-times
  rather than as being space-times themselves; since if they were space-times they could be thought to be composed
  of points which would themselves be truth-indexers, and so our possible worlds would not be atomic truth-indexers.
  This seems to be a much simpler foundation to build upon than assuming that, somehow,
  possible worlds should have some intrinsic temporal structure, which would be very hard
  to define right from the start.

  Perhaps more importantly, given this primitive notion we can readily define the notion of an ontological
  **Event** as simply a set of possible worlds; the notion should be familiar to those acquainted
  with probability theory (probability spaces). An (not necessarily "random") event is something that "happens" or "occurs",
  precisely in the possible worlds which are its elements, i.e. an event is the set of all possible worlds in which
  the event occurs. We would like to talk a little bit about events before delving into the mathematical definitions.

  Another way to see an event is as the semantic content of a proposition.
  Not all events are necessarily propositions because,
  perhaps, we could have uncountably many events, but countably many propositions.
  However every proposition is to be associated with an event:
  the set of all possible worlds in which the proposition is true.
  For instance the proposition "Socrates exists" corresponds to the event {w : world | Socrates exists in w}.

  Now, it is quite clear that some propositions "talk about" or postulate one or more things existing, while others do not.
  "Socrates exists" clearly postulates the existence of Socrates, just as "Humans exist" postulates the existence of
  Human beings, and "Socrates and Plato exist" postulates the existence of both Plato and Socrates, etc...
  On the other hand, "Unicorns do not exist", does not seem to postulate or "talk about"
  the existence of anything, but merely about the *absence* of an existence.
  So there is quite clearly a primitive notion of which propositions
  talk about existence and which do not. I would not want to reduce this notion
  to merely "using an existential quantifier in formal language X" because I do
  not want to assume anything about the syntactical makeup of propositions in the first
  place.

  For the sake of generality, simplicity, and removing from our formal system the unnecessary concept of what a
  "proposition" is supposed to be, we can take this notion to apply to all events regardless
  of whether they are propositions or not, and stop talking about propositions altogether.
  So an event will be **existential** or **open**
  precisely when its occurrence postulates that one or more entities from a set of entities must exist,
  which is to say that the event can only occur in a possible world if those entities it postulates
  do exist in that possible world.

  Now, as we have already exemplified, we should expect that arbitrary set unions of existential
  events be existential events, since the event "(Some)Humans exist" is the union of all events of the form
  "X exists" for any possible human X. The same should apply for intersections, since "All possible humans exist"
  is the intersection of "X exists" for any possible human X. And generally speaking, regardless of the
  particular notion of "existential event" that we adopt, we should expect the set of all existential events to be
  closed by arbitrary unions and intersections.

  However, although plausible,
  this amounts to assuming more than what we actually need to develop our theory.
  For the purposes of our theory, we will only really be committed to the claim that
  *finite* intersections of existential events are existential events, rather than
  claiming that this works for *arbitrarily large* intersections.
  This latter assumption we will denominate, for very sound mathematical reasons, the **Alexandroff Postulate**,
  and we will neither affirm nor deny it, though we might occasionally derive some conclusions from its assumption.

  Furthermore, we should also assume that both the set of all possible worlds, i.e. the **necessary event**
  and the empty set of worlds, i.e. the **impossible event**, are both
  existential events. There are many ways to argue this point, the simplest one seems to consist in the
  consideration that the proposition "Something (whatsoever) exists" should be associated to the necessary event,
  and that the proposition "A squared-circle exists" should be associated to the impossible event. In that case,
  it is clear that these events postulate the existence of some things.

  It is however clear that we need not assume that the set complements of existential events are existential for, as we
  have previously exemplified, "Unicorns do not exist" is not existential, even though it is the complement, or negation, of
  "Unicorns exist", which is clearly existential.

  We are also going to assume, as the only real axiom in our theory, that there is an extensionality
  principle for possible worlds: possible worlds worlds in which exactly the same existential events occur
  are equal. This will allow us to think of possible worlds as the sets of possible entities which exist
  in that particular world, so that if two worlds are to be distinct, at least one entity would have to exist in one
  which does not exist in the other. This can be seen as the "identity of indiscernibles" principle
  applied to possible worlds. It might turn out however that for many applications we won't even need this axiom,
  so we might consider turning it into a postulate if the need arises, but as of now it looks like such a simple
  assumption that it makes sense to include it as an axiom.

  Now, we shall not explain here the mathematics involved, but
  a competent mathematician should already be able to conclude that what
  we are assuming is that existential events constitute a T₀-topology of
  possible worlds.

  This leads us to the very first formal definitions of our theory:

-/

/-- An `ontology` is a nonempty T₀ topological space
of possible worlds. -/
structure ontology :=
    (world : Type u)
    [wne : nonempty world]
    [t : topological_space world]
    -- identity of indiscernibles for possible worlds
    [axiom₀ : @t0_space world t]

/-- identity of indiscernibles for possible worlds. -/
add_decl_doc ontology.axiom₀

instance ontology_top  (ω : ontology)  : topological_space ω.world := ω.t
instance ontology_ne  (ω : ontology)  : nonempty ω.world := ω.wne
instance ontology_t0  (ω : ontology)  : t0_space ω.world := ω.axiom₀

/-- **Events** in an ontology are simply sets of possible worlds.
 Events are said to **occur** at their element worlds. -/
@[reducible]
def ontology.event (ω : ontology) := set ω.world

/-- **Existential** `events` in an ontology are open sets of possible worlds. -/
@[reducible, simp]
def ontology.event.existential {ω : ontology} (e : ω.event) := is_open e

-- We will start developing the most basic conclusions of the theory:
namespace ontology

variable {ω : ontology}

-- We develop further the notion of events.
section events

  variable (e : ω.event)

  @[reducible, simp]
  def event.occurs (w : ω.world) := w ∈ e

  -- We define the related topological notions for events:

  @[reducible, simp]
  def event.closure : ω.event := closure e
  @[reducible, simp]
  def event.dense : Prop := closure e = univ
  @[reducible, simp]
  def event.exterior : ω.event := interior (-e)
  @[reducible, simp]
  def event.regular : Prop := e = e.exterior.exterior
  /-- also called `boundary` -/
  @[reducible, simp]
  def event.frontier : ω.event := frontier e
  /-- also called `frontier` -/
  @[reducible, simp, alias]
  def event.boundary : ω.event := e.frontier
  @[reducible, simp]
  def event.connected : Prop := is_connected e
  @[reducible, simp]
  def event.irreducible : Prop := is_irreducible e
  @[reducible, simp]
  def event.clopen : Prop := is_clopen e
  @[reducible, simp]
  def event.closed : Prop := is_closed e
  @[reducible, simp]
  def event.nnegative : Prop := ¬ is_closed e
  /-- **Not Purely Negative** events -/
  @[reducible, simp]
  def event.npnegative : Prop := ¬ is_closed e ∨ is_clopen e
  @[reducible, simp]
  def event.compact : Prop := compact e

  -- necessity, possibility, impossibility, contingency
  @[reducible, simp]
  def event.necessary := e = univ
  @[reducible, simp]
  def event.possible := e.nonempty
  @[reducible, simp]
  def event.impossible := ¬e.possible
  @[reducible, simp]
  def event.contingent := e.possible ∧ ¬e.necessary

  /-- The **ground**, or *ontological counterpart* of an `event e` is its interior,
      i.e. the largest existential event below `e`.
      This will be the event of some entity existing whose
      existence necessitates the ocurrence of `e`. -/
  @[reducible, simp]
  def event.ground : ω.event := interior e

  /-- An `event` is **groundable** if its ground is `possible`. -/
  @[reducible, simp]
  def event.groundable := e.ground.possible

  /-- An `event` is **ungroundable** if it is not groundable. -/
  @[reducible, simp]
  def event.ungroundable := ¬e.groundable

  -- Setting up notation:

  /-- Use `□e` for "`e` is necessary" -/
  @[reducible, simp]
  instance has_box_event : has_box ω.event := ⟨event.necessary⟩

  /-- Use `◾e` for "the ground of `e`" -/
  @[reducible, simp]
  instance has_black_box_event : has_black_box ω.event := ⟨event.ground⟩

  /-- Use `⋄e` for "`e` is possible" -/
  @[reducible, simp]
  instance has_diamond_event : has_diamond ω.event := ⟨event.possible⟩

  /-- Use `✦e` for "the event of nothing precluding `e` from happening", or `-◾-e` -/
  @[reducible, simp]
  instance has_black_diamond_event : has_black_diamond ω.event := ⟨event.closure⟩

  /-- Use `~e` for "the exterior of `e`" -/
  @[reducible, simp]
  instance has_tilde_event : has_tilde ω.event := ⟨event.exterior⟩

  /-- Use `e₁ ⇒ e₂` instead of `e₁ ⊆ e₂`, replace with `⇒'` for `⊂`.
      Use `e₁ ⇏ e₂` instead of `¬ e₁ ⇒ e₂`.
      Use `e₁ ≡ e₂` instead of `e₁ ⇒ e₂ ∨ e₂ ⇒ e₁`.
      Use `e₁ ≢ e₂` instead of `¬ e₁ ≡ e₂`.
  -/
  @[reducible, simp]
  instance has_entailment_event : has_entailment ω.event := ⟨set.subset⟩

  /-- Use `e₁ ⟶ e₂`  instead of `-e₁ ∪ e₂`.
      Use `e₁ !⟶ e₂` instead of `-(e₁ ⟶ e₂)`.
      Use `e₁ ⟷ e₂`  instead of `(e₁ ⟶ e₂) ∩ (e₂ ⟶ e₁)`.
      Use `e₁ !⟷ e₂` instead of `-(e₁ ⟷ e₂)`.
  -/
  @[reducible, simp]
  instance has_local_entailment_event : has_local_entailment ω.event := ⟨λ e₁ e₂, -e₁ ∪ e₂⟩

  --tests:
  -- variables (e₁ e₂ : ω.event)
  -- #check □e
  -- #check ◾e
  -- #check ⋄e
  -- #check ✦e
  -- #check ~e
  -- #check e₁ ⇒ e₂
  -- #check e₁ ⇒' e₂
  -- #check e₁ ⇏ e₂
  -- #check e₁ ≡ e₂
  -- #check e₁ ≢ e₂
  -- #check e₁ ⟶ e₂
  -- #check e₁ ⟷ e₂
  -- #check e₁ !⟶ e₂
  -- #check e₁ !⟷ e₂
  -- example : e.groundable ↔ ⋄◾e := by simp

end events

-- And we prove some simple useful lemmas about them
section event_lemmas

  variable {e : ω.event}
  lemma event_union_exterior_open : e.existential → (e ∪ ~e).existential :=
    by intro h; apply is_open_union h; simp

  -- For some reason in the standard library there is a lemma
  -- like this for finsets but not one for sets.
  lemma event_possible_of_ne_empty : e ≠ ∅ → ⋄e :=
    begin
        intro h,
        simp [set.nonempty],
        by_contradiction h₂,
        push_neg at h₂,
        replace h₂ := eq_empty_iff_forall_not_mem.2 h₂,
        contradiction,
    end

  lemma event_union_exterior_possible : ⋄(e ∪ ~e) :=
    begin
        apply event_possible_of_ne_empty,
        intro h,
        simp at h,
        obtain ⟨h₁, h₂⟩ := h,
        rw h₁ at h₂,
        simp at h₂,
        have c := ω.wne,
        contradiction,
    end

  @[simp]
  lemma existential_iff_ground_eq : e.existential ↔ e = e.ground :=
    begin
      simp,
      symmetry,
      constructor; intros h,
        symmetry' at h,
        exact interior_eq_iff_open.mp h,
      symmetry,
      exact interior_eq_iff_open.2 h,
    end

end event_lemmas

-- We define (extensional) possible entities to be particular kinds of events, so
-- that existence is a special case of occurrence.
-- We defer full philosophical explanation to the "Intensionality and Extensionality" section.
section entities

  /-- The (possible, extensional) `entities` in the ontology are nonempty open sets of possible worlds.
      An entity is said to **exist** precisely at the worlds which are its elements. -/
  structure entity (ω : ontology) :=
    -- the event of the entity existing ("exists" is a reserved word)
    («exists» : ω.event)
    (existential : exists.existential)
    (possible : ⋄«exists»)

  /-- the event of the `entity` existing -/
  add_decl_doc entity.exists

  /-- Any groundable event `e` can be cast to an entity,
      the existence of which is the ground of `e`. -/
  def event.entity (e : ω.event) (h : ⋄◾e) : ω.entity := ⟨◾e, is_open_interior, h⟩
  /-- An event is entitative if it is both existential and possible. -/
  def event.entitative (e : ω.event) : Prop := e.existential ∧ ⋄e

  @[simp]
  lemma entity.entitative (e : ω.entity) : e.exists.entitative := ⟨e.existential, e.possible⟩
  @[reducible]
  lemma event.entitative.entity {e : ω.event} (h : e.entitative) : ω.entity := ⟨e, h.1, h.2⟩

  /-- main extensionality lemma for entities. -/
  @[ext]
  lemma entity_ext {e₁ e₂ : ω.entity} (h : e₁.exists = e₂.exists) : e₁ = e₂ :=
    by casesm* ω.entity; simp at h; simpa

  @[simp]
  lemma entity_ext_iff (e₁ e₂ : ω.entity) : e₁ = e₂ ↔ e₁.exists = e₂.exists :=
    ⟨(λ h, by rw h), entity_ext⟩

  variables (e e₁ e₂ : ω.entity)

  lemma entity_exists_inj : function.injective (@entity.exists ω) :=
    λ e₁ e₂, @entity_ext ω e₁ e₂

  /-- Two entities are said to be `contrary` if there is no possible world
      in which both exist together.
      they are otherwise said to be `compatible`. -/
  @[reducible, simp]
  def entity.contrary := e₁.exists ∩ e₂.exists = ∅
  /-- Negation of `entity.contrary`. -/
  @[reducible, simp]
  def entity.compatible := ⋄(e₁.exists ∩ e₂.exists)

  -- Some very important entities have no contraries
  @[reducible, simp]
  def entity.nocontrary := ¬ ∃ y, e.contrary y

  /-- Entity e₁ is said to existentially entail entity e₂,
      or to existentially depend on e₂,
      if in every possible world in which e₁ exists, e₂ exists.
      For this relation we use the ` ⇒ ` notation.
      This is defined via coercion to events and
      the `cross_entailment` typeclass instances. -/
  @[reducible, simp]
  instance has_coe_entity : has_coe ω.entity ω.event := ⟨entity.exists⟩

  -- tests:
  -- #reduce λ (e₁ : ω.entity) (e₂ : ω.entity), e₁ ⇒ e₂
  -- #reduce λ (e₁ : ω.entity) (e₂ : ω.event), e₁ ⇒ e₂
  -- #reduce λ (e₁ : ω.entity) (e₂ : ω.event), e₂ ⇒ e₁

  /-- An entity is said to be a **truthmaker** for any event its existence entails. -/
  def entity.truthmaker (e : ω.entity) (ev : ω.event) : Prop := e ⇒ ev

  /-- The event of an entity being "removed" from a possible world. -/
  def entity.removed (w : ω.world) : ω.event :=
    {w' | e.exists w ∧ w' < w ∧ ¬ e.exists w'}
  /-- The event of an entity being "added" to a possible world. -/
  def entity.added (w : ω.world) : ω.event :=
    {w' | ¬e.exists w ∧ w < w' ∧ e.exists w'}
  /-- The set of all possible worlds from which an entity can be "removed". -/
  def entity.removable : ω.event :=
    {w | ⋄e.removed w}
  /-- The set of all possible worlds to which an entity can be "added". -/
  def entity.addable : ω.event :=
    {w | ⋄e.added w}

  /-- The necessary being (entity) is the entity which exists in
      every possible world. -/
  def nbe (ω : ontology) : ω.entity := ⟨univ, is_open_univ, by simp [empty_ne_univ]⟩
  instance entity_inhabited : inhabited ω.entity := ⟨ω.nbe⟩

  /-- An entity is `contingent` if it is not the necessary being. -/
  @[reducible, simp]
  def entity.contingent := e ≠ ω.nbe
  /-- An entity is `necessary` if it is the necessary being. -/
  @[reducible, simp]
  def entity.necessary := e = ω.nbe

  @[reducible, simp]
  def entity.compact := e.exists.compact

  /-- Use `□e` for "`e` is necessary" -/
  @[reducible, simp]
  instance has_box_entity : has_box ω.entity := ⟨entity.necessary⟩

  lemma nbe_unique : ∃! e : ω.entity, □e := by use ω.nbe; simp

  /-- A contingent entity is said to be **complemented** if
      its existence is a clopen set.
      Complemented entities `e` are such that the event
      of their non-existence `-e.exists` is itself
      just as much of an entity as `e`.
      It can be proven that the possibility
      of the existence of complemented
      entities is logically equivalent to atheism. -/
  def entity.complemented : Prop := e.contingent ∧ e.exists.clopen

  -- Here are some definitions which look more like lemmas:

  -- Arbitrary nonempty unions of entities are entities.
  def entity_Sup (s : set ω.entity) (h : s.nonempty) : ω.entity :=
    begin
      fsplit,
          exact ⋃ i ∈ s, entity.exists i,
      apply is_open_bUnion,
      intros i H,
      exact i.existential,
          simp [set.nonempty],

      let i := h.some,
      let w := i.possible.some,
      existsi w,
      existsi i,
      constructor,
        exact h.some_mem,
        exact i.possible.some_mem,
    end

  -- so are pairwise unions, obviously
  def entity_sup (e₁ e₂ : ω.entity) : ω.entity :=
    begin
      fconstructor,
        exact e₁.exists ∪ e₂.exists,
      apply is_open_union,
        exact e₁.existential,
        exact e₂.existential,
      simp, left,
      exact e₁.possible,
    end

  -- @[reducible, simp]
  instance has_Sup_entity : has_Sup ω.entity :=
  ⟨λ s, if h : s.nonempty then entity_Sup s h else ω.nbe⟩

  -- @[reducible, simp]
  instance has_sup_entity : has_sup ω.entity := ⟨entity_sup⟩

  @[simp]
  lemma Sup_sup (e₁ e₂ : ω.entity) : Sup {e₁, e₂} = e₁ ⊔ e₂ :=
    begin
      have c : ({e₁, e₂} : set ω.entity).nonempty,
        use e₁, simp,
      simp [Sup, has_Sup.Sup, entity_Sup, entity_sup, c],
      exact sup_comm,
    end

  /-- Intersections of compatible entities are entities.
      If `h` is a proof of the compatibility of the entities
      `e₁` and `e₂`, then `h.inter` is the intersection of
      `e₁` and `e₂`. -/
  def entity.compatible.inter {e₁ e₂ : ω.entity} (h : e₁.compatible e₂) : ω.entity :=
      ⟨  e₁.exists ∩ e₂.exists
      , is_open_inter e₁.existential e₂.existential
      , h
      ⟩

  /-- possibly_not_exists_of_contingent -/
  lemma pnexists_of_contingent {e : ω.entity} : e.contingent → ⋄-e.exists :=
    begin
      intro h,
      simp [nbe, entity_ext_iff] at h,
      by_contradiction c,
      simp [has_neg.neg, compl, set.nonempty] at c,
      replace c := eq_univ_of_forall c,
      contradiction,
    end

  def entity.complement (h : e.complemented) : ω.entity :=
    ⟨ -e.exists
    , h.2.2
    , pnexists_of_contingent h.1
    ⟩

end entities

-- We discuss some properties of possible worlds
section worlds

  variables (w w₁ w₂ : ω.world)

  -- We can also talk about an entity existing in a world
  -- as belonging to it, so we can use the notation e ∈ w.
  @[reducible, simp]
  instance world.has_mem : has_mem ω.entity ω.world := ⟨λe w, w ∈ e.exists⟩
  @[reducible, simp]
  def world.entities := {e : ω.entity | e ∈ w}

  -- extensionality principle for possible worlds
  @[ext]
  lemma world.ext {w₁ w₂ : ω.world} (h : w₁.entities = w₂.entities) : w₁ = w₂ :=
    begin
      by_contradiction contra,
      have c₀ := ω.axiom₀.t0,
      obtain ⟨U, U_open, ⟨hU₁, hU₂⟩|⟨hU₁, hU₂⟩⟩ := c₀ w₁ w₂ contra;
      clear c₀;
      have ne := nonempty_of_mem hU₁;
      let e : ω.entity := ⟨U, U_open, ne⟩,
      replace h : w₁.entities ⊆ w₂.entities, finish,
      swap,
      replace h : w₂.entities ⊆ w₁.entities, finish,
      all_goals {
        simp [world.entities, entity.exists] at h,
        specialize h e,
        simp [e, hU₁, hU₂] at h,
        contradiction,
      },
    end

  @[reducible, simp]
  def world.ideal : ω.event := {w' | w' ≤ w}
  def world.filter : ω.event := {w' | w ≤ w'}
  def world.nonactuality : ω.event := {w' | w' ≠ w}

  variable (ω)

  def nonparmenidean : ω.event := {w | ∃ e : ω.entity, e.contingent ∧ e.exists w}
  def parmenidean : ω.event := {w | ∀ e : ω.entity, e ∈ w → □ e}

  @[reducible, simp]
  def weakly_parmenidean : Prop := ⋄ω.parmenidean
  @[reducible, simp]
  def strongly_parmenidean : Prop := □ω.parmenidean
  /-- A modal collapsing ontology is an ontology with a single possible world -/
  def mcollapse : Prop := ∀ w₁ w₂ : ω.world, w₁ = w₂

  def Parmenides : ontology := { world := unit }
  def Sierpinski : ontology := { world := Prop }

  lemma mcollapse_iff_str_parme : ω.mcollapse ↔ ω.strongly_parmenidean :=
    begin
      constructor; intro h;
        simp [strongly_parmenidean, nbe, ext_iff, parmenidean] at *,
        intros w₁ e he w₂,
        specialize h w₁ w₂,
        rwa h at he,
      intros w₁ w₂,
      ext e, constructor; intro h₀,
        exact h w₁ e h₀ w₂,
      exact h w₂ e h₀ w₁,
    end

  -- #reduce Sierpinski.t.is_open {false}
  -- lemma weakly_parme_weaker : ∃ ω₀ : ontology.{0}, ω₀.weakly_parmenidean ∧ ¬ ω₀.mcollapse :=
  --   begin
  --     use Sierpinski, constructor,
  --       use false, simp [parmenidean],
  --       intros e h,
  --       by_cases hyp : e.exists = {false, true};
  --         simp [nbe, hyp, ext_iff],
  --         exact em,
  --       have c := e.existential,
  --       change (generate_open (λ (b : Prop → Prop), (b = λ (b : Prop), b = true ∨ false) ∨ false) e.exists) at c,
  --       simp at c,
  --       intro w,
  --       apply generate_open.cases_on c,
  --       -- simp at d,
  --       -- induction c; try {simp},
  --       --   change (c_s = λ (b : Prop), b) at c_H,
  --       --   rw c_H at h,
  --       --   change (false) at h,
  --       --   contradiction,

        -- simp [set_of, set.mem] at c_H,
        --; simp [nbe],
        -- simp [sierpinski_space.is_open] at c,
  -- end

end worlds

-- Here we discuss basic general properties of ontologies themselves.
section ontology

  variable (ω)

  /-- The least we should assume for an ontology to be worthy of consideration as being
      the true ontology is that we can add or remove entities from its worlds.
      A `viable` ontology is one satisfying this postulate. -/
  class viable : Prop :=
      (postulate₁ : ∀ w : ω.world, ∃ w', w < w' ∨ w' < w)

  -- common (sensical) ontologies
  class common extends viable ω : Prop :=
      (postulate₂ : uncountable ω.world)

  def alexandroff_discrete := alexandroff_space ω.world

  class alexandroff extends common ω : Prop :=
    (postulate₃ : ω.alexandroff_discrete)

  /-- A complemented ontology supports complemented entities. -/
  def complemented := ∃ e : ω.entity, e.complemented

  /-- The **Principle of Non-Negative Nonactual Existence** claims
      that the nonactual (a.k.a. merely possible) existence of any entity is a non-negative event. -/
  def pnnnae : Prop := ∀ (w : ω.world) (e : ω.entity), (↑e ∩ w.nonactuality).nnegative

end ontology

/- We introduce a custom notion of subbasis in an ontology. -/
section subbasis

  def {v} is_subbasis {ω : ontology.{v}} (B : set ω.event) : Prop :=
    (∀ ev : ω.event, ev ∈ B → ev.entitative) ∧
    ∀ e : ω.entity, ∃ (I : Type v) (ne : nonempty I) (S : I → set ω.event),
    (∀ i, (S i).finite ∧ (S i).nonempty ∧ (S i) ⊆ B) ∧
    (⋃ i, ⋂₀ S i) = e

  def is_subbasis' (B : set ω.entity) : Prop := is_subbasis $ entity.exists '' B

  variable {B : set ω.event}

  lemma is_subbasis.ne : is_subbasis B → B.nonempty :=
    begin
      intro h,
      by_contradiction contra,
      replace contra := not_nonempty_iff_eq_empty.mp contra,
      simp [is_subbasis, contra] at h,
      specialize h ω.nbe,
      obtain ⟨I, ne, S, h⟩ := h,
      replace h := (h.1 ne).2,
      obtain ⟨h₁, h₂⟩ := h,
      replace h₁ := h₁.not_subset_empty,
      contradiction,
    end

  lemma is_subbasis.ne_of_mem : is_subbasis B → ∀ {b : ω.event}, b ∈ B → ⋄b :=
    λ h b hb, (h.1 b hb).2

  lemma is_subbasis.existential_of_mem : is_subbasis B → ∀ {b : ω.event}, b ∈ B → b.existential :=
    λ h b hb, (h.1 b hb).1

  lemma is_subbasis.sUnion_necessary :  is_subbasis B → □ ⋃₀ B :=
    begin
      intro h,
      replace h := h.2 ω.nbe,
      obtain ⟨I, ne, S, ⟨h₁, h₂⟩⟩ := h,
      unfold_coes at h₂,
      simp [nbe, Union, ext_iff] at h₂,
      simp [sUnion, ext_iff],
      intro w, specialize h₂ w,
      obtain ⟨i, hi⟩ := h₂,
      specialize h₁ i,
      obtain ⟨h₁, ⟨e,he⟩, h₃⟩ := h₁,
      specialize hi e he,
      specialize h₃ he,
      exact ⟨e, h₃, hi⟩,
    end

  lemma {v} default_subbasis (ω : ontology.{v}) : @is_subbasis ω event.entitative :=
    begin
      refine ⟨λ_,id, _⟩,
      intro e,
      refine ⟨(punit.{v+1} : Type v), ⟨punit.star⟩,(λ_,{e.exists}), _⟩,
      unfold_coes, simp,
      refine ⟨⟨e.existential, e.possible⟩,_⟩,
      simp [Union],
    end

end subbasis

/-! ## Intensionality and Extensionality

  A fundamental question in any ontological theory is that of
  whether the basic entities that the theory postulates have a clearly
  defined identity criteria or whether their identity should be assumed
  to be a primitive relation. This amounts to asking whether the entities
  in the theory admit an *extensionality* principle, such as the
  one admitted for sets, or whether no such extensionality principle is admitted.
  We can readily call the basic entities in an extensional ontological theory
  *extensional* entities, and likewise name the entities in an intensional theory
  *intensional* entities.

  As can be seen from the previous section, it is easy to turn our ontology into an extensional theory
  by identifying non-empty existential events to be possible extensional entities. Their
  extensionality principle is then naturally deduced from the extensionality
  principle for sets. We will indeed be primarily focusing on these entities for much of our work,
  but to demonstrate the generality of our theory we must
  also discuss shortly the introduction of primitive intensional entities via
  an intensional extension to our theory.

  It might indeed look somewhat controversial, to some,
  that we so readily move from existential events to "entities".
  It may look like we are saying that entities, or at least our particular kind of
  "extensional" entities, are *nothing but* sets of possible worlds, or that nothing but
  sets of possible worlds are supposed to "exist" in our theory. This of course seems implausible
  among other reasons because sets are abstract mathematical objects, not concretely existing "things".
  This objection can however be resolved by understanding that, this being a mathematical theory,
  we are not really claiming that possible entities *are* nothing other than sets of possible worlds,
  but only that these entities can be *represented* as the sets of possible worlds in which they exist.
  We are also not really committed to claiming that existence really just *is* a particular special case
  of the occurrence of events, but only that for all mathematical intents and purposes it can be so *represented*.
  We will look shortly into a way to make this representation formal by showing that any intensional ontological theory
  of possible entities naturally gives rise to our extensional topological theory in a mathematically well understood way.

-/

/-- An **Intensional ontology** is an ontology generated by a mapping of intensional entities to existential events -/
structure iontology (ω : ontology.{u}) :=
  (ientity : Type u)
  [iene : nonempty ientity]
  («exists» : ientity → ω.event)
  (axiom₁ : is_subbasis $ range «exists»)

namespace iontology

  section ientity

    variables {Ω : ω.iontology} (ie : Ω.ientity)

    /-- the `event` of an intensional entity existing -/
    def ientity.exists := Ω.exists ie

    /-! **...**

      As can be seen, we can define an intensional ontology as a particular kind of ontology whose
      topological structure was generated as the least topology containing the image of a map from some
      type of intensional entities to events. These events will provably be extensional entities, as we
      show bellow:

    -/

    lemma ientity.possible : ie.exists.possible :=
      Ω.axiom₁.ne_of_mem
      (by simp [ientity.exists]; use ie)

    lemma ientity.existential : ie.exists.existential :=
      Ω.axiom₁.existential_of_mem
      (by simp [ientity.exists]; use ie)

    -- "up" is used for informal inheritance here
    /-- cast from `ientity` to `entity` -/
    def ientity.up : ω.entity := ⟨ie.exists, ie.existential, ie.possible⟩

    instance ientity_coe : has_coe Ω.ientity ω.entity := ⟨ientity.up⟩

    -- #check ie ⇒ ie

  end ientity

end iontology

-- We discuss whether extensional entities, and other Lean types, are real or mere abstracta.
section realism

  variables (e : ω.entity) (Ω : ω.iontology)

  /-! ## Real and Virtual Entities

    Some philosophers might furthermore be skeptical with the prospect that, for example,
    the existential event "human beings exist"
    corresponds to some particular, unique, "extensional entity"
    which may possibly exist concretely in the world;
    i.e. the (not necessarily Platonic) universal of "Man", or Humanity.
    We make a concession to this sort of skepticism in order to make our
    system more general, and we will admit that some such extensional entities might be,
    in some sense, abstracta, figures of speech, concoctions of language, etc...
    and these we will call **virtual** entities; all other entities we shall call **real** entities.
    Formally what will make a non-empty existential event a real entity is its belonging
    to the image of the representation function which maps intensional possible entities to
    their extensional representations.

  -/

  /-- An `entity` `e` is real with respect to an iontology `Ω` if there is an `Ω.ientity`
      which exists in the same possible worlds as `e`. -/
  def entity.real : Prop := ∃ ie : Ω.ientity, ie.up = e
  /-- An `entity` is virtual with respect to an iontology `Ω` if its is not real with respect to `Ω`. -/
  @[reducible]
  def entity.virtual : Prop := ¬ e.real Ω

  /-! **Example**

    To give an example, the extensional entity "Socrates"
    defined as the existential event "(the set of all possible worlds in which) Socrates exists"
    is real because there is some possible intensional entity Socrates such that the event of
    this Socrates existing is precisely the same event which defines the extensional "Socrates".
    However one could consistently hold that the event "Humans exist" does not represent some
    distinct intensional entity over and above the individual intensional human beings from whose
    representations it is constructed. In this case, the associated extensional entity, "Humanity",
    would be a virtual entity. This is compatible with doctrines of mereological nihilism and such.

    We assume that talk of "virtual entities" is just a figure of speech for talk about
    existential events which talk about the existence of more than a single intensional entity,
    and as such we can conclude that the jump from existential events to extensional entities
    does not indeed commits us to any novel metaphysical thesis, nor to anything which could possibly
    be controversial.

  -/

  /-! In what follows, we speak of "realizations" instead of "instances" whenever we, informally, take the
      type in question to be a kind of proof-relevant "proposition". -/

  -- Specific Forms of realism:

  /-- An intensional ontology is realist about a class `C` of entities, if every entity in `C` is real. -/
  def iontology.realist (C : set ω.entity) := ∀ e : ω.entity, e ∈ C → e.real Ω

  /-- A *realization* of a position of **realism about instances of type `α`**,
      relative to a mapping `«exists»` of the `α`s to their extensional representations,
      consists in an injective map associating every `x : α` to some intensional entity, `map x`,
      such that `(map x).exists = «exists» x`. The default view is that all instances of `α`
      are necessary, such that (e.g.) `Ω.realism ℕ` correspond to the default view of realism about natural numbers
      which take them to be necessary entities. -/
  structure iontology.realism (Ω : ω.iontology) (α : Type u) («exists» : α → ω.entity := λ_, ω.nbe) :=
    (map : α → Ω.ientity)
    (h₀ : function.injective map)
    (h₁ : ∀ x, Ω.exists (map x) = «exists» x)

  /-- A *realization* of a position of **simplified realism about instances of type `α`**,
      consists in an injective map associating every `x : α` to some intensional entity, `map x`. -/
  structure iontology.srealism (Ω : ω.iontology) (α : Type u) :=
    (map : α → Ω.ientity)
    (h₀ : function.injective map)

  -- simplified realism can be cast to regular realism:
  def iontology.srealism.to_realism {Ω : ω.iontology} {α} (h : Ω.srealism α) :  Ω.realism α (iontology.ientity.up ∘ h.map) :=
    by refine ⟨h.map, h.h₀, _⟩; unfold_coes; simp [iontology.ientity.up, iontology.ientity.exists]

  /-- A *realization* of the position of **extensional realism** is a realization of `Ω.realism ω.entity id`.
      In other words, it consists of an injective map taking extensional entities to intensional entities
      which exist in the same possible worlds. It can be seem as associating to every equivalence class of intensional
      entities a canonical representative which reifies the class itself and/or
      the extensional entity corresponding to the class. The existence of a realization implies algebraic realism. -/
  def iontology.erealism := Ω.realism ω.entity id

  /-- A *realization* of the position of **restricted extensional realism** for some class of entities `C`,
      is a realization of `Ω.realism (subtype C) subtype.val`.
      In other words, it consists of an injective map, defined in `C`,
      taking extensional entities to intensional entities
      which exist in the same possible worlds. It can be seem as associating to every equivalence class of intensional
      entities represented by entities in `C`, a canonical representative which reifies
      the class itself and/or the extensional entity corresponding to the class.
      The existence of a realization implies realism about the `C`s. -/
  def iontology.rerealism (C : set ω.entity):= Ω.realism (subtype C) subtype.val

  /-! Now, if a map of this sort is not injective, we can take the position in question to be a realization
      of a position of **grounding** rather than a position of realism. Since however a position of grounding
      is just a (possibly partial) function, we do not define a new structure for it. -/

  /-! **Absolutely Real Entities**

      One important notion that will arise out of intensionality will be the property
      of an entity being absolutely real, i.e. real regardless of the underlying intensional ontology used
      to generate the ontological structure. This will allow us to think about intensional ontologies much
      in the same way that geometers think about a choice of "basis", or "chart", so that we --like them--
      shall be most interested in proving only the results which do not depend on an arbitrary choice of
      intensional ontology.

  -/

  /-- An `entity` is absolutely real if it is real regardless of the choice of iontology -/
  def entity.absolutely_real : Prop := ∀ Ω : ω.iontology, e.real Ω

end realism

section algebraic_realism

  variables (Ω : ω.iontology)

  /-! **Algebraic Realism**

    We shall name the theory which claims that all extensional entities are real **algebraic realism**,
    and we can also prove that both this theory and its denial are logically consistent.
    The theory is to be so called because it is realistic about the set theoretic constructions
    of extensional entities (unions and intersections), which are algebraic constructions
    in a complete Heyting algebra, or topological frame.
    Because we are not committed to algebraic realism from the outset,
    we intend our identification of existential events with extensional entities to be metaphysically neutral.

  -/

  /-- **Algebraic realism** for intensional ontologies claims that all
  extensional entities are real.
  It is realist about the algebraic operations of topological frames. -/
  class iontology.arealist : Prop :=
    (postulate₀ : ∀ e : ω.entity, e.real Ω)

  /-! We prove below that every ontology admits a canonical algebraic realist iontology.
      In order to do so, we first show that it is possible to construct an iontology out of
      any subbasis, then we prove that for the default subbasis the generated iontology is
      indeed `arealist`.
  -/

  /-- The `iontology` generated by events in a subbasis. -/
  def is_subbasis.intensionalize {B : set ω.event} : is_subbasis B → ω.iontology :=
    λ h, { ientity := subtype B
         , iene := let ⟨b, hb⟩ := h.ne in ⟨⟨b, hb⟩⟩
         , «exists» := subtype.val
         , axiom₁ := by simpa [range, subtype.val]
         }

  lemma natural_arealism : ω.default_subbasis.intensionalize.arealist :=
    begin
      constructor, intro e,
      use e; unfold_coes; simp [iontology.ientity.up],
      change (e.exists = e.exists), refl,
    end

end algebraic_realism

/-! **Final remarks about Intensionality**

  Even though we are not assuming algebraic realism, our general intention is indeed to avoid talking about
  intensional entities as most as possible. If we completely abstract away talk of intensional entities from
  our system, we will be left simply with a topological space of possible worlds from which the distinction
  between real and virtual entities cannot be defined. In order to define it we would at the very least have
  to equip the space with an additional sub-basis to stand in for the events which are used to represent the
  intensional entities we intend to abstract, and then claim that an entity is real only if it belong to the sub-basis.
  As such, in order to make the distinction we would need to introduce this sub-basis as a new unwanted and
  unneeded primitive concept to which our system would have to be committed.
  In order to eschew this primitive, we must say that the distinction between real and virtual entities is,
  for the most part, not really useful in our system, and we have introduced it,
  along with the discussion of intensional entities, only in order to anticipate some
  objections which might be leveled against our theory
  (e.g. that it is committed to algebraic realism, or to an universal extensionality principle for the most
  basic sort of possible entities). Because of this, in what follows we will simply be talking about
  extensional entities and will pay no attention to whether they are real or virtual unless
  it becomes important (and in general it won't be).

-/

-- additional auxiliary lemmas involving compact events and entities
section compact
  -- It is annoying that mathlib doesn't export this
  -- sort of lemma using sets of sets instead of set families.
  lemma event.compact.elim {e : ω.event} : e.compact → (∀ (S : set ω.event),
                                                         (∀ i ∈ S, is_open i) →
                                                         e ⇒ ⋃₀ S →
                                                         ∃ s : set ω.event, s ⊆ S ∧ finite s ∧ e ⇒ ⋃₀ s)
                                                         :=
    begin
      intros h S hS he,
      have c :=  @compact.elim_finite_subcover_image _ _ _ e S id h hS,
      specialize c _, swap,
        intros w hw,
        simp,
        specialize he hw,
        simp at he,
        exact he,
      simp at c,
      obtain ⟨s, h₁, h₂, h₃⟩ := c,
      refine ⟨s, h₁, h₂, _⟩,
      intros w hw,
      specialize h₃ hw,
      simp at h₃,
      simp,
      exact h₃,
    end

  lemma entity.compact.elim {e : ω.entity} : e.compact → (∀ {S : set ω.entity}, S.nonempty →
                                                         e ⇒ Sup S →
                                                         ∃ s : set ω.entity, s.nonempty ∧ s ⊆ S ∧ finite s ∧ e ⇒ Sup s)
                                                         :=
    begin
      intros h S hS he,
      simp [Sup, has_Sup.Sup, hS, entity_Sup, has_entailment.entails] at he,
      have c := h.elim (entity.exists '' S),
      specialize c _, swap,
        intros i hi,
        simp at hi,
        obtain ⟨x, _, hx⟩ := hi,
        rw ←hx, exact x.existential,
      specialize c _, swap,
        simp [has_entailment.entails],
        exact he,
      obtain ⟨s, hs₁, hs₂, hs₃⟩ := c,
      have sne : s.nonempty,
        simp [sUnion, set.subset] at hs₃,
        obtain ⟨w, hw⟩ := e.possible,
        obtain ⟨ev, hev,_⟩ := hs₃ hw,
        exact ⟨ev, hev⟩,
      replace sne : {e : ω.entity | e.exists ∈ s}.nonempty,
        obtain ⟨ev, hev⟩ := sne,
        have c := hs₁ hev, simp [image] at c,
        obtain ⟨e',_, he'⟩ := c,
        rw ←he' at hev,
        exact ⟨e', hev⟩,
      refine ⟨{e | e.exists ∈ s}, sne, _⟩,
      constructor,
        intros e' he', simp at he',
        have c := hs₁ he', simp [image] at c,
        obtain ⟨e'', goal, eq⟩ := c,
        replace eq := (entity_ext_iff e'' e').2 eq,
        rwa ←eq,
      constructor,
        set S' := {e : ω.entity | e.exists ∈ s},
        have c : entity.exists '' S' = s,
          simp [image],
          ext, constructor; intro hyp,
            simp at hyp,
            obtain ⟨_, _, hyp⟩ := hyp,
            rwa ←hyp,
          simp,
          have c := hs₁ hyp, simp [image] at c,
          obtain ⟨e', _, eq⟩ := c,
          rw ←eq at hyp,
          exact ⟨e', hyp, eq⟩,
        have c₁ := entity_exists_inj.inj_on S',
        apply finite_of_finite_image c₁,
        rwa c,
      simp [Sup, has_Sup.Sup, sne, entity_Sup, has_entailment.entails, set.subset],
      simp [has_entailment.entails, sUnion, set.subset] at hs₃,
      intros w hw,
      obtain ⟨ev, hev₁,hev₂⟩ := hs₃ hw,
      specialize hs₁ hev₁, simp [image] at hs₁,
      obtain ⟨e', aux, he'⟩ := hs₁, clear aux,
      rw ←he' at hev₁,
      rw ←he' at hev₂,
      exact ⟨e', hev₁, hev₂⟩,
    end

end compact

end ontology


import for_mathlib.short_exact_sequence

noncomputable theory

open category_theory
open category_theory.limits

universes v u

namespace category_theory
variables (𝒞 : Type u) [category.{v} 𝒞]
variables {C : Type u} [category.{v} C] {D : Type*} [category D]
variables [has_images C] [has_zero_morphisms C] [has_kernels C]
variables [has_images D] [has_zero_morphisms D] [has_kernels D]

/-- Cohomological covariant delta functor. -/
class delta_functor (F : ℕ → C ⥤ D) :=
(δ : Π (n : ℕ), short_exact_sequence.Trd C ⋙ (F n) ⟶ short_exact_sequence.Fst C ⋙ (F (n+1)))
(mono : ∀ (A : short_exact_sequence C), mono ((F 0).map A.f))
(exact' : ∀ (n : ℕ) (A : short_exact_sequence C), exact ((F n).map A.f) ((F n).map A.g))
(exact_δ : ∀ (n : ℕ) (A : short_exact_sequence C), exact ((F n).map A.g) ((δ n).app A))
(δ_exact : ∀ (n : ℕ) (A : short_exact_sequence C), exact ((δ n).app A) ((F (n+1)).map A.f))

namespace delta_functor

variables {𝒜 : Type*} [category 𝒜] [abelian 𝒜]
variables (F : ℕ → C ⥤ 𝒜) [delta_functor F]

example (A : short_exact_sequence C)
  (hA₂ : ∀ i, 0 < i → is_zero ((F i).obj A.2)) (hA₃ : ∀ i, 0 < i → is_zero ((F i).obj A.3))
  (i : ℕ) (hi : 1 < i) :
  is_zero ((F i).obj A.1) :=
begin
  obtain ⟨i, rfl⟩ : ∃ k, i = k + 2, { simpa only [add_comm] using nat.exists_eq_add_of_le hi },
  refine is_zero_of_exact_zero_zero' _ _ (delta_functor.δ_exact (i+1) A) _ _,
  { exact (hA₃ (i+1) i.succ_pos).eq_of_src _ _ },
  { refine (hA₂ (i+2) _).eq_of_tgt _ _, exact pos_of_gt hi }
end

end delta_functor

end category_theory


import doubleround
import littleendian

import category_theory.category.basic
import category_theory.core

open doubleround
open littleendian
open operations
open params
open utils

open category_theory

namespace core

variable [category (bitvec word_len)]

/-!
  # Core

  - The `doubleround10` function and its inverse.
  - The `hash` and `core` functions, the non existing inverse.
-/

/-- Apply double round 10 times to a reduced input. -/
@[simp] def doubleround_10 (X : matrixType): matrixType :=
  doubleround_salsa20 $
  doubleround_salsa20 $
  doubleround_salsa20 $
  doubleround_salsa20 $
  doubleround_salsa20 $
  doubleround_salsa20 $
  doubleround_salsa20 $
  doubleround_salsa20 $
  doubleround_salsa20 $
  doubleround_salsa20 $
  X

/-- Inverse of `doubleround_10`. -/
@[simp] def doubleround_10_inv (X : matrixType): matrixType :=
  doubleround_salsa20_inv $
  doubleround_salsa20_inv $
  doubleround_salsa20_inv $
  doubleround_salsa20_inv $
  doubleround_salsa20_inv $
  doubleround_salsa20_inv $
  doubleround_salsa20_inv $
  doubleround_salsa20_inv $
  doubleround_salsa20_inv $
  doubleround_salsa20_inv $
  X

/- Just some notation for inverses. -/
local notation `doubleround_10⁻¹` := doubleround_10_inv

/-- The `doubleround` function is invertible. -/
lemma doubleround_is_inv (I : doubleround_10 ≅ doubleround_10⁻¹) : I.hom ≫ I.inv = 𝟙 doubleround_10 :=
  by rw [iso.hom_inv_id]

/-!
## Core and hash definitions

  - There is no isomorphism (≅) between `core` and any `core⁻¹`.
  - There is no isomorphism (≅) between `hash` and any `hash⁻¹` because the use of `core` and `core⁻¹`.
-/

/-- Do addition modulo 2^32 of the reduced input and the doubleround of the reduced input. -/
@[simp] def core (X : matrixType) : matrixType := mod_matrix (doubleround_10 X) X

/-- Do the hash. -/
def hash (X : matrix64Type) : matrix64Type := aument (core (reduce X))

end core


import data.real.irrational
import topology.basic
import algebra.order.floor

--OUTPUT 1
theorem irrational_orbit_dense {α : ℝ} (hα_irrat : irrational α) : closure ((λ m : ℤ, int.fract (α * ↑m)) '' (@set.univ ℤ)) = set.Icc 0 1 :=
begin
  have h1 : (∀ (i j : ℤ), i ≠ j → int.fract (α * ↑i) ≠ int.fract (α * ↑j)), from sorry,
  have h2 : (∀ (i : ℤ), int.fract (α * ↑i) ∈ (set.Icc 0 1)), from sorry,
  have h3 : (∀ (i : ℤ), int.fract (α * ↑i) ≠ 0), from sorry,
  have h4 : (∀ (i : ℤ), int.fract (α * ↑i) ≠ 1), from sorry,
  have h5 : (∀ (i : ℤ), int.fract (α * ↑i) ∉ ({0} ∪ {1})), from sorry,
  have h6 : (∀ (i : ℤ), int.fract (α * ↑i) ∈ (set.Icc 0 1) \ ({0} ∪ {1})), from sorry,
  have h7 : (∀ (i : ℤ), int.fract (α * ↑i) ∈ (-∞, -1) ∪ (1, ∞)), from sorry,
  have h8 : (∀ (i : ℤ), int.fract (α * ↑i) ≠ -1), from sorry,
  have h9 : (∀ (i : ℤ), int.fract (α * ↑i) ≠ 2), from sorry,
  have h10 : (∀ (i : ℤ), int.fract (α * ↑i) ∉ ({-1} ∪ {2})), from sorry,
  have h11 : (∀ (i : ℤ), int.fract (α * ↑i) ∈ (set.Icc 0 1) \ ({-1} ∪ {2})), from sorry,
  have h12 : (∀ (i : ℤ), int.fract (α * ↑i) ∈ (-∞, -2) ∪ (2, ∞)), from sorry,
  have h13 : (∀ (i : ℤ), int.fract (α * ↑i) ≠ -2), from sorry,
  have h14 : (∀ (i : ℤ), int.fract (α * ↑i) ≠ 3), from sorry,
  have h15 : (∀ (i : ℤ), int.fract (α * ↑i) ∉ ({-2} ∪ {3})), from sorry,
  have h16 : (∀ (i : ℤ), int.fract (α * ↑i) ∈ (set.Icc 0 1) \ ({-2} ∪ {3})), from sorry,
  have h17 : (∀ (i : ℤ), int.fract (α * ↑i) ∈ (-∞, -3) ∪ (3, ∞)), from sorry,
  have h18 : (∀ (i : ℤ), int.fract (α * ↑i) ≠ -3), from sorry,
  have h19 : (∀ (i : ℤ), int.fract (α * ↑i) ≠ 4), from sorry,
  have h20 : (∀ (i : ℤ), int.fract (α * ↑i) ∉ ({-3} ∪ {4})), from sorry,
  have h21 : (∀ (i : ℤ), int.fract (α * ↑i) ∈ (set.Icc 0 1) \ ({-3} ∪ {4})), from sorry,
  have h22 : (∀ (i : ℤ), int.fract (α * ↑i) ∈ (-∞, -4) ∪ (4, ∞)), from sorry,
  have h23 : (∀ (i : ℤ), int.fract (α * ↑i) ≠ -4), from sorry,
  have h24 : (∀ (i : ℤ), int.fract (α * ↑i) ≠ 5), from sorry,
  have h25 : (∀ (i : ℤ), int.fract (α * ↑i) ∉ ({-4} ∪ {5})), from sorry,
  have h26 : (∀ (i : ℤ), int.fract (α * ↑i) ∈ (set.Icc 0 1) \ ({-4} ∪ {5})), from sorry,
  have h27 : (∀ (i : ℤ), int.fract (α * ↑i) ∈ (-∞, -5) ∪ (5, ∞)), from sorry,
  have h28 : (∀ (i : ℤ), int.fract (α * ↑i) ≠ -5), from sorry,
  have h29 : (∀ (i : ℤ), int.fract (α * ↑i) ∉ {-5}), from sorry,
  have h30 : (∀ (i : ℤ), int.fract (α * ↑i) ∈ (set.Icc 0 1) \ {-5}), from sorry,
  have h31 : (∀ (i : ℤ), int.fract (α * ↑i) ∈ (-∞, -5) ∪ (5, ∞)), from sorry,
  have h32 : (∀ (i : ℤ), int.fract (α * ↑i) ≠ -6), from sorry,
  have h33 : (∀ (i : ℤ), int.fract (α * ↑i) ∉ {-6}), from sorry,
  have h34 : (∀ (i : ℤ), int.fract (α * ↑i) ∈ (set.Icc 0 1) \ {-6}), from sorry,
  have h35 : (∀ (i : ℤ), int.fract (α * ↑i) ∈ (-∞, -6) ∪ (6, ∞)), from sorry,
  have h36 : (∀ (i : ℤ), int.fract (α * ↑i) ≠ -7), from sorry,
  have h37 : (∀ (i : ℤ), int.fract (α * ↑i) ∉ {-7}), from sorry,
  have h38 : (∀ (i : ℤ), int.fract (α * ↑i) ∈ (set.Icc 0 1) \ {-7}), from sorry,
  have h39 : (∀ (i : ℤ), int.fract (α * ↑i) ∈ (-∞, -7) ∪ (7, ∞)), from sorry,
  have h40 : (∀ (i : ℤ), int.fract (α * ↑i) ≠ -8), from sorry,
  have h41 : (∀ (i : ℤ), int.fract (α * ↑i) ∉ {-8}), from sorry,
  have h42 : (∀ (i : ℤ), int.fract (α * ↑i) ∈ (set.Icc 0 1) \ {-8}), from sorry,
  have h43 : (∀ (i : ℤ), int.fract (α * ↑i) ∈ (-∞, -8) ∪ (8, ∞)), from sorry,
  have h44 : (∀ (i : ℤ), int.fract (α * ↑i) ≠ -9), from sorry,
  have h45 : (∀ (i : ℤ), int.fract (α * ↑i) ∉ {-9}), from sorry,
  have h46 : (∀ (i : ℤ), int.fract (α * ↑i) ∈ (set.Icc 0 1) \ {-9}), from sorry,
  have h47 : (∀ (i : ℤ), int.fract (α * ↑i) ∈ (-∞, -9) ∪ (9, ∞)), from sorry,
  have h48 : (∀ (i : ℤ), int.fract (α * ↑i) ≠ -10), from sorry,
  have h49 : (∀ (i : ℤ), int.fract (α * ↑i) ∉ {-10}), from sorry,
  have h50 : (∀ (i : ℤ), int.fract
end --Needs more than 2000 tokens!

--OUTPUT 2
theorem irrational_orbit_dense {α : ℝ} (hα_irrat : irrational α) : closure ((λ m : ℤ, int.fract (α * ↑m)) '' (@set.univ ℤ)) = set.Icc 0 1 :=
begin
  sorry
end

--OUTPUT 3
theorem irrational_orbit_dense {α : ℝ} (hα_irrat : irrational α) : closure ((λ m : ℤ, int.fract (α * ↑m)) '' (@set.univ ℤ)) = set.Icc 0 1 :=
begin
  have h1 : ∀ (i j : ℤ), i ≠ j → int.fract (α * ↑i) ≠ int.fract (α * ↑j),
  from sorry,

  have S := {x : ℝ | ∃ (i : ℤ), x = int.fract (α * ↑i)},
  have h2 : S ⊆ set.Icc 0 1,
  from sorry,
  have h3 : ∀ (x : ℝ), x ∈ S → x ∈ closure S, from sorry,
  have h4 : S ⊆ closure S, from sorry,

  have h5 : closure S ⊆ set.Icc 0 1, from sorry,

  have h6 : set.Icc 0 1 ⊆ closure S, from
    assume x,
    assume h6 : x ∈ set.Icc 0 1,
    assume ε : ℝ,
    assume h7 : ε > 0,
    cases set.mem_Icc.mp h6 with h6 h6,
    let x := (λ (m : ℤ), int.fract (α * ↑m)),

    cases set.mem_Icc.mp h6 with h6 h6,

end

--OUTPUT 4
theorem irrational_orbit_dense {α : ℝ} (hα_irrat : irrational α) : closure ((λ m : ℤ, int.fract (α * ↑m)) '' (@set.univ ℤ)) = set.Icc 0 1 :=
begin
  have h1 : (∀ (i j : ℤ), i ≠ j → int.fract (α * ↑i) ≠ int.fract (α * ↑j)),
  from begin
    assume (i j : ℤ),
    assume h1 : (i ≠ j),
    assume h2 : int.fract (α * ↑i) = int.fract (α * ↑j),
    calc α = (↑(int.fract (α * ↑i)) + ↑(int.floor (α * ↑i))) * 1 : by sorry
    ... = (int.fract (α * ↑i) + int.floor (α * ↑i)) * (1 : ℝ) : by sorry
    ... =  int.fract (α * ↑i) + int.floor (α * ↑i) : by rw mul_one
    ... =  int.fract (α * ↑i) + int.floor (α * ↑j) : by rw h2
    ... =  int.fract (α * ↑i) + int.fract (α * ↑j) + int.floor (α * ↑j) - int.fract (α * ↑j) : by rw nat.add_sub_cancel -- this is not a valid line
    ... =  int.fract (α * ↑i) + int.fract (α * ↑j) + (α * ↑j) - int.fract (α * ↑j) : by rw int.floor_eq
    ... =  int.fract (α * ↑i) + int.fract (α * ↑j) + (α * ↑j) - int.fract (α * ↑i) : by rw h2
    ... =  int.fract (α * ↑i) + (1 : ℝ) * (α * ↑j) - int.fract (α * ↑i) : by rw int.fract_eq
    ... =  int.fract (α * ↑i) + α * ↑j - int.fract (α * ↑i) : by rw mul_one
    ... =  α * ↑j + int.fract (α * ↑i) - int.fract (α * ↑i) : by rw add_comm
    ... =  α * ↑j : by rw nat.add_sub_cancel
    ... =  ↑j * α : by rw mul_comm
    ... =  ↑j * (α : ℝ) : by rw mul_comm
    ... =  ↑j * ↑i : by rw int.fract_eq
    ... =  ↑i * ↑j : by rw mul_comm
    ... =  ↑i * α : by rw h2
    ... =  (α : ℝ) * ↑i : by rw mul_comm
    ... =  α : by rw int.fract_eq
    ... ∈ ℚ : by sorry,
    show false, from sorry,
  end,

  have set_S : (set.univ : set ℤ) = set.Iio 0,
  from sorry, --this is no a valid line

  have h2 : (λ m : ℤ, (int.fract (α * m))) '' (set.Iio 0) = (λ m : ℤ, int.fract (α * ↑m)) '' (set.univ : set ℤ),
  from sorry, --this is no a valid line

  have h3 : (λ m : ℤ, int.fract (α * ↑m)) '' (set.univ : set ℤ) = (λ m : ℤ, int.fract (α * ↑m)) '' set.univ,
  from sorry, --this is no a valid line

  have h4 : ∀ (i : ℕ), ∃ (x : ℝ), x ∈ (λ m : ℤ, int.fract (α * ↑m)) '' (set.univ : set ℤ),
  from sorry, --this is no a valid line

  have h5 : ∀ (i : ℕ), ∃ (x : ℝ), x ∈ (λ m : ℤ, int.fract (α * ↑m)) '' set.univ,
  from sorry, --this is no a valid line

  have h6 : ∀ (i : ℕ), ∃ m, m ∈ set.univ ∧ (int.fract (α * ↑m) = i),
  from sorry, --this is no a valid line

  have h7 : ∀ i : ℕ, ∃ m, m ∈ set.Iio 0 ∧ (int.fract (α * ↑m) = i),
  from sorry, --this is no a valid line

  have h8 : ∀ i : ℕ, ∃ m, m ∈ set.Iio 0 ∧ (int.fract (α * ↑m) = i),
  from sorry, --this is no a valid line

  have h9 : ∀ i : ℕ, ∃ m, m ∈ set.Iio 0 ∧ (int.fract (α * ↑m) = i),
  from sorry, --this is no a valid line

  have h10 : ∀ i : ℕ, ∃ m, m ∈ set.Iio 0 ∧ (int.fract (α * ↑m) = i),
  from sorry, --this is no a valid line

  have h11 : ∀ i : ℕ, ∃ m, m ∈ set.Iio 0 ∧ (int.fract (α * ↑m) = i),
  from sorry, --this is no a valid line

  have h12 : ∀ i : ℕ, ∃ m, m ∈ set.Iio 0 ∧ (int.fract (α * ↑m) = i),
  from sorry, --this is no a valid line

  have h13 : ∀ i : ℕ, ∃ m, m ∈ set.Iio 0 ∧ (int.fract (α * ↑m) = i),
  from sorry, --this is no a valid line

  have h14 : ∀ i : ℕ, ∃ m, m ∈ set.Iio 0 ∧ (int.fract (α * ↑m) = i),
  from sorry, --this is no a valid line

  have h15 : ∀ i : ℕ, ∃ m, m ∈ set.Iio 0 ∧ (int.fract (α * ↑m) = i),
  from sorry, --this is no a valid line

  have h16 : ∀ i : ℕ, ∃ m, m ∈ set.Iio 0 ∧ (int.fract (α * ↑m) = i),
  from sorry, --this is no a valid line

  have h17 : ∀ i : ℕ, ∃ m, m ∈ set.Iio 0 ∧ (int.fract (α * ↑m) = i),
  from sorry, --this is no a valid line

  have h18 : ∀ i : ℕ, ∃ m, m ∈ set.Iio 0 ∧ (int.fract (α * ↑m) = i),
  from sorry, --this is no a valid line

  have h19 : ∀ i : ℕ, ∃ m, m ∈ set.Iio 0 ∧ (int.fract (α * ↑m) = i),
  from sorry, --this is no a valid line

  have h20 : ∀ i : ℕ, ∃ m, m ∈ set.Iio 0 ∧ (int.fract (α * ↑m) = i),
  from sorry, --this is no a valid line

  have h21 : ∀ i : ℕ, ∃ m, m ∈ set.Iio 0 ∧ (int.fract (α * ↑m) = i),
  from sorry, --this is no a valid line

  have h22 : ∀ i : ℕ, ∃ m, m ∈ set.Iio 0 ∧ (int.fract (α * ↑m) = i),
  from sorry, --this is no a valid line

  have h23 : ∀ i : ℕ, ∃ m, m ∈ set.Iio 0 ∧ (int.fract (α * ↑m) = i),
  from sorry, --this is no a valid line

  have h24 :
end --Needs more than 2000 tokens!

--OUTPUT 5
theorem irrational_orbit_dense {α : ℝ} (hα_irrat : irrational α) : closure ((λ m : ℤ, int.fract (α * ↑m)) '' (@set.univ ℤ)) = set.Icc 0 1 :=
begin
  have h1 : ∀ i j : ℤ, i ≠ j → (λ (m : ℤ), int.fract (α * ↑m)) i ≠ (λ (m : ℤ), int.fract (α * ↑m)) j,
  {
    intros i j h12,
    assume h13 : (λ (m : ℤ), int.fract (α * ↑m)) i = (λ (m : ℤ), int.fract (α * ↑m)) j,
    have h14 : (α * ↑i) - (int.floor (α * ↑i)) = int.fract (α * ↑i),
    from sorry,
    have h15 : (α * ↑j) - (int.floor (α * ↑j)) = int.fract (α * ↑i),
    from sorry,
    have h16 : (α * ↑i)  = α * ↑i - (int.floor (α * ↑i)) + (int.floor (α * ↑i)),
    from sorry,
    have h17 : (α * ↑j)  = α * ↑j - (int.floor (α * ↑j)) + (int.floor (α * ↑j)),
    from sorry,
    have h18 : α = (int.floor (α * ↑i) - (int.floor (α * ↑j)))/(i - j),
    begin
      calc α = (α * ↑i - (int.floor (α * ↑i)))/(i - j) : by sorry
      ... = ((α * ↑i) - (int.floor (α * ↑i)) + (int.floor (α * ↑i)))/(i - j) : by sorry
      ... = ((α * ↑i) + (int.floor (α * ↑i)) - (int.floor (α * ↑i)))/(i - j) : by sorry
      ... = ((α * ↑i) + (int.floor (α * ↑i)) - (int.floor (α * ↑j)) - (int.floor (α * ↑i)) + (int.floor (α * ↑j)))/(i - j) : by sorry
      ... = ((α * ↑i) + (int.floor (α * ↑j)) - (int.floor (α * ↑i)) + (int.floor (α * ↑j)) - (int.floor (α * ↑i)))/(i - j) : by sorry
      ... = ((α * ↑j) + (int.floor (α * ↑j)) - (int.floor (α * ↑i)))/(i - j) : sorry
      ... = ((α * ↑j) - (int.floor (α * ↑j)) + (int.floor (α * ↑j)))/(i - j) : by sorry
      ... = (α * ↑j - (int.floor (α * ↑j)))/(i - j) : by sorry
      ... = α : sorry,
    end,
    show false, from hα_irrat h18,
  },

  have h2 : ∀ i j : ℤ, ((λ (m : ℤ), int.fract (α * ↑m)) i = (λ (m : ℤ), int.fract (α * ↑m)) j) ↔ (i = j),
  from sorry,

  have h3 : ∀ i j : ℤ, i ≠ j → ((λ (m : ℤ), int.fract (α * ↑m)) i ≠ (λ (m : ℤ), int.fract (α * ↑m)) j) ↔ (i ≠ j),
  from sorry,

  have h4 : ∀ i j : ℤ, ((λ (m : ℤ), int.fract (α * ↑m)) i = (λ (m : ℤ), int.fract (α * ↑m)) j) ↔ (i = j) ↔ ((λ (m : ℤ), int.fract (α * ↑m)) i ≠ (λ (m : ℤ), int.fract (α * ↑m)) j) ↔ (i ≠ j),
  from sorry,

  have h5 : equiv.set ((λ (m : ℤ), int.fract (α * ↑m)) '' (@set.univ ℤ)) ((λ (m : ℤ), int.fract (α * ↑m)) '' (@set.univ ℤ)) := sorry,

  have h6 : inj ((λ (m : ℤ), int.fract (α * ↑m)) : ℤ → (λ (m : ℤ), int.fract (α * ↑m)) '' (@set.univ ℤ)) := sorry,

  have h7 : ∀ i j : ℤ, ((λ (m : ℤ), int.fract (α * ↑m)) i = (λ (m : ℤ), int.fract (α * ↑m)) j) ↔ (i = j),
  from sorry,

  have h8 : setoid ((λ (m : ℤ), int.fract (α * ↑m)) '' (@set.univ ℤ)) := sorry,

  have h9 : ∀ i j : ℤ, pfinset.finset.mem ((λ (m : ℤ), int.fract (α * ↑m)) '' (@set.univ ℤ)) (λ (m : ℤ), int.fract (α * ↑m)) i ↔ pfinset.finset.mem ((λ (m : ℤ), int.fract (α * ↑m)) '' (@set.univ ℤ)) (λ (m : ℤ), int.fract (α * ↑m)) j → i = j,
  from sorry,

  have h10 : ∀ i j : ℤ, pfinset.finset.mem ((λ (m : ℤ), int.fract (α * ↑m)) '' (@set.univ ℤ)) (λ (m : ℤ), int.fract (α * ↑m)) i ↔ pfinset.finset.mem ((λ (m : ℤ), int.fract (α * ↑m)) '' (@set.univ ℤ)) (λ (m : ℤ), int.fract (α * ↑m)) j ↔ i = j,
  from sorry,

  have h11 : decidable_eq ((λ (m : ℤ), int.fract (α * ↑m)) '' (@set.univ ℤ)) := sorry,

  have h12 : fintype ((λ (m : ℤ), int.fract (α * ↑m)) '' (@set.univ ℤ)) := sorry,

  have h13 : unique ((λ (m : ℤ), int.fract (α * ↑m)) '' (@set.univ ℤ)) := sorry,

  have h14 : ¬(∃ i : ℤ, (∀ (j : ℤ), pfinset.finset.mem ((λ (m : ℤ), int.fract (α * ↑m)) '' (@set.univ ℤ)) (λ (m : ℤ), int.fract (α * ↑m)) i ↔ pfinset.finset.mem ((λ (m : ℤ), int.fract (α * ↑m)) '' (@set.univ ℤ)) (λ (m : ℤ), int.fract (α * ↑m)) j)) :=
  begin
    assume h14,
    have h15 : ∀ j : ℤ, pfinset.finset.mem (@set.univ ℤ) j ↔ pfinset.finset.mem ((λ (m : ℤ), int.fract (α * ↑m)) '' (@set.univ ℤ)) (λ (m : ℤ), int.fract (α * ↑m)) j,
    from sorry,

    have h16 : ∀ j : ℤ, j ∈ (@set.univ ℤ) ↔  pfinset.finset.mem ((λ (m : ℤ), int.fract (α * ↑m)) '' (@set.univ ℤ)) (λ (m :
end --Needs more than 2000 tokens!

--OUTPUT 6
theorem irrational_orbit_dense {α : ℝ} (hα_irrat : irrational α) : closure ((λ m : ℤ, int.fract (α * ↑m)) '' (@set.univ ℤ)) = set.Icc 0 1 :=
begin
  have h1 : ∀ i j : ℤ, (i ≠ j) → (int.fract (α * i) ≠ int.fract (α * j)), from sorry,
  have h2 : ∀ i j : ℤ, (i ≠ j) → (α * i ≠ α * j), from sorry,

  have h3 : ∀ i j : ℤ, (i ≠ j) → (i * α ≠ j * α),
  from sorry,

  have h4 : ∀ i j : ℤ, (i ≠ j) → (i * α - (i * α).floor ≠ j * α - (j * α).floor),
  from sorry,

  have h5 : ∀ i j : ℤ, (i ≠ j) → (i * α - (i * α).floor ≠ j * α - (j * α).floor),
  from sorry,

  have h6 : ∀ i j : ℤ, (i ≠ j) → (i * α - (i * α).floor ≠ j * α - (j * α).floor),
  from sorry,

  have h7 : ∀ i : ℤ, (i * α - (i * α).floor) ≠ 0,
  from sorry,

  have h8 : ∀ i : ℤ, (i * α - (i * α).floor) > 0,
  from sorry,

  have h9 : ∀ i : ℤ, (i * α - (i * α).floor) < 1,
  from sorry,

  have h10 : ∀ i : ℤ, i * α ≠ 0,
  from sorry,

  have h11 : ∀ i : ℤ, i * α ≠ 1,
  from sorry,

  have h12 : ∀ i : ℤ, i * α - (i * α).floor ≠ 0,
  from sorry,

  have h13 : ∀ i : ℤ, i * α - (i * α).floor ≠ 1,
  from sorry,

  have h14 : ∀ i : ℤ, i * α ≠ 0,
  from sorry,

  have h15 : ∀ i : ℤ, i * α ≠ 1,
  from sorry,

  have h16 : ∀ i : ℤ, (i * α - (i * α).floor) ≠ 0,
  from sorry,

  have h17 : ∀ i : ℤ, (i * α - (i * α).floor) ≠ 1,
  from sorry,

  have h18 : ∀ i : ℤ, (i * α - (i * α).floor) ≠ 0,
  from sorry,

  have h19 : ∀ i : ℤ, (i * α - (i * α).floor) ≠ 1,
  from sorry,

  have h20 : ∀ x : ℤ, (∀ i : ℤ, i * α - (i * α).floor ≠ x) → (x < 0) ∨ (x > 1)
  := assume (x : ℤ) (h20 : ∀ i : ℤ, i * α - (i * α).floor ≠ x),
  begin
    have h21 : ∀ i : ℤ,  ((i * α - (i * α).floor ≠ x) ∧ (i * α - (i * α).floor ≠ 0))
    := assume (i : ℤ), ⟨h20 i, h18 i⟩,
    have h22 : ∀ i : ℤ,  ((i * α - (i * α).floor ≠ x) ∧ (i * α - (i * α).floor ≠ 1))
    := assume (i : ℤ), ⟨h20 i, h17 i⟩,

    have h23 : ∀ i : ℤ,  ((i * α - (i * α).floor ≠ x) ∧ (i * α - (i * α).floor ≠ 0) ∧ (i * α - (i * α).floor ≠ 1))
    := assume (i : ℤ), and.intro (h21 i) (h22 i),

    have h24 : ∀ i : ℤ, (x < i * α - (i * α).floor) ∨ (x > i * α - (i * α).floor)
    := assume (i : ℤ), lt_or_gt_of_ne (h20 i),

    have h25 : ∀ i : ℤ, ((x < i * α - (i * α).floor) ∨ (i * α - (i * α).floor < x))
    := assume (i : ℤ), sorry,

    have h26 : ∀ i : ℤ, ((x < 0) ∨ (0 < x))
    := assume (i : ℤ), sorry,

    have h27 : ∀ i : ℤ, ((x < i * α - (i * α).floor) ∨ (i * α - (i * α).floor < x))
    := assume (i : ℤ), sorry,

    have h28 : ∀ i : ℤ, ((x < 0) ∨ (0 < x))
    := assume (i : ℤ), sorry,

    have h29 : ∀ i : ℤ, ((x < i * α - (i * α).floor) ∨ (i * α - (i * α).floor < x))
    := assume (i : ℤ), sorry,

    have h30 : ∀ i : ℤ, ((x < 0) ∨ (0 < x))
    := assume (i : ℤ), sorry,

    have h31 : ((x < 0) ∨ (0 < x))
    := sorry,

    have h32 : ∀ i : ℤ, ((x < i * α - (i * α).floor) ∨ (i * α - (i * α).floor < x))
    := assume (i : ℤ), sorry,

    have h33 : ∀ i : ℤ, ((x < 0) ∨ (0 < x))
    := assume (i : ℤ), sorry,

    have h34 : ((x < 0) ∨ (0 < x))
    := sorry,

    have h35 : ∀ i : ℤ, ((x < i * α - (i * α).floor) ∨ (i * α - (i * α).floor < x))
    := assume (i : ℤ), sorry,

    have h36 : ∀ i : ℤ, ((x < 0) ∨ (0 < x))
    := assume (i : ℤ), sorry,

    have h37 : ((x < 0) ∨ (0 < x))
    := sorry,

    have h38 : ∀ i : ℤ, ((x < i * α - (i * α).floor) ∨ (i * α - (i * α).floor < x))
    := assume (i : ℤ), sorry,

    have h39 : ∀ i : ℤ, ((x < 0) ∨ (0 < x))
    := assume (i : ℤ), sorry,

    have h40 : ((x < 0) ∨ (0 < x))
    := sorry,

    have h41 : ∀ i : ℤ, ((x < i * α - (i * α).floor) ∨ (i * α - (i * α).floor < x))
    := assume (i : ℤ), sorry,

    have h42 : ∀ i : ℤ, ((x < 0) ∨ (0 < x))
    := assume (i : ℤ), sorry,

    have h43 : ((x < 0) ∨ (0 < x))
    := sorry,

    have h44 : ∀ i : ℤ, (x < i * α - (i * α).floor) ∨ (i * α - (i * α).floor < x)
    := assume (i : ℤ), sorry,

    have h45 : ∀ i : ℤ, (x < 0) ∨ (0 < x)
    := assume (i
end --Needs more than 2000 tokens!

--OUTPUT 7
theorem irrational_orbit_dense {α : ℝ} (hα_irrat : irrational α) : closure ((λ m : ℤ, int.fract (α * ↑m)) '' (@set.univ ℤ)) = set.Icc 0 1 := begin
  have h2 : ∀ i j : ℤ, i ≠ j → int.fract (α * ↑i) ≠ int.fract (α * ↑j), from
  begin
    assume (i j : ℤ) (h3 : i ≠ j),
    assume (h4 : int.fract (α * ↑i) = int.fract (α * ↑j)),
    have h5 : α = (int.fract (α * ↑i) - int.fract (α * ↑j))/(i - j), by simp [h4],
    exact hα_irrat h5,
  end,

  let S : set ℝ := {int.fract (α * ↑i) | i : ℤ},

  have h6 : irrational α, from hα_irrat,
  have h7 : S.finite = ff, from set.finite_iff.mpr sorry,

  have h8 : ∀ x : ℝ, (∃ (x' : S), x' ≤ x) ∨ (∃ (x' : S), x ≤ x') :=
  begin
    assume (x : ℝ),
    --split
    cases classical.em (∃ (x' : S), x' ≤ x) with hh hh,
      {left,
        exact hh
      },
    {right,
      exact show ∃ (x' : S), x ≤ x',
        from sorry,
    },
  end,

  have h9 : (∀ (x : S), ∀ (n : ℕ), 0 < n → int.fract (↑n * x) < 1)
  ∧ (∀ (x : S), ∀ (n : ℕ), n < 0 → 0 < int.fract (↑n * x))  := sorry,

  set_option trace.class_instances true,
  have h10 : S.finite = ff, from set.finite_iff.mpr (sorry),
  have h11 : ¬ (S.finite ∧ ¬ ∃ x : S, ∀ y : S, ¬ x ≤ y ∧ ¬ y ≤ x), from sorry,
  set_option trace.class_instances false,

  have h12 : ¬ ∃ x : S, ∀ y : S, ¬ x ≤ y ∧ ¬ y ≤ x, from sorry,
  have h13 : ∃ x : S, ∀ y : S, y < x ∨ x < y, from sorry,

  have h14 : ∃ y : S, ∀ x : S, y < x ∨ x < y, from sorry,

  let y := classical.some h14, let m := classical.some sorry,

  have h15 : (∀ x : S, x < y ∨ y < x) ∧ ∃ m, y = classical.some (sorry), from sorry,

  have h16 : ∀ (m n : ℕ), int.fract (m * ↑y) < int.fract (n * ↑y) ∨ int.fract (n * ↑y) < int.fract (m * ↑y),
  from sorry,

  have h17 : ∃ m, ∀ n, ∃ p, m ≤ p ∧ p ≤ n ∧ (int.fract (p * ↑y) ≤ 1/2) ∧ (Π y, int.fract (p * ↑y) ≤ 1/2 → n ≤ p),
  from sorry,

  have h18 : ∃ m, ∀ n, ∃ p, m ≤ p ∧ p ≤ n ∧ (int.fract (p * ↑y) ≤ 1/2)
  ∧ (Π y, int.fract (p * ↑y) ≤ 1/2 → p ≤ n), from sorry,

  have h19 : ∃ m, ∀ n, ∃ p, int.fract (p * ↑y) ≤ 1/2 ∧ int.fract (p * ↑y) ≤ 1/2 → m ≤ p ∧ p ≤ n,
  from sorry,

  have h20 : ∃ m, ∀ n, ∃ p, int.fract (p * ↑y) ≤ 1/2 ∧ int.fract (p * ↑y) ≤ 1/2 → p ≤ m ∧ m ≤ p,
  from sorry,

  have h21 : ∃ m, ∀ n, ∃ p, int.fract (p * ↑y) ≤ 1/2 ∧ int.fract (p * ↑y) ≤ 1/2 → m ≤ p ∧ p ≤ m,
  from sorry,

  have h22 : ∃ m, ∀ n, ∃ p, int.fract (p * ↑y) ≤ 1/2 ∧ int.fract (p * ↑y) ≤ 1/2 → m ≤ p ∧ p ≤ n ∧ m ≤ p,
  from sorry,

  have h23 : ∃ m, ∀ n, ∃ p, int.fract (p * ↑y) ≤ 1/2 ∧ int.fract (p * ↑y) ≤ 1/2 → m ≤ p ∧ m ≤ p ∧ p ≤ n,
  from sorry,

  have h24 : ∃ m, ∀ n, ∃ p, int.fract (p * ↑y) ≤ 1/2 ∧ int.fract (p * ↑y) ≤ 1/2 → m ≤ p ∧ m ≤ p ∧ m ≤ p ∧ p ≤ n,
  from sorry,

  have h25 : ∃ m, ∀ n, ∃ p, int.fract (p * ↑y) ≤ 1/2 ∧ int.fract (p * ↑y) ≤ 1/2 → m ≤ p ∧ m ≤ p ∧ m ≤ p ∧ m ≤ p ∧ p ≤ n,
  from sorry,

  have h26 : ∃ m, ∀ n, ∃ p, int.fract (p * ↑y) ≤ 1/2 ∧ int.fract (p * ↑y) ≤ 1/2 → m ≤ p ∧ m ≤ p ∧ m ≤ p ∧ m ≤ p ∧ m ≤ p ∧ p ≤ n,
  from sorry,

  have h27 : ∃ m, ∀ n, ∃ p, int.fract (p * ↑y) ≤ 1/2 ∧ int.fract (p * ↑y) ≤ 1/2 → m ≤ p ∧ m ≤ p ∧ m ≤ p ∧ m ≤ p ∧ m ≤ p ∧ m ≤ p ∧ p ≤ n,
  from sorry,

  have h28 : ∃ m, ∀ n, ∃ p, int.fract (p * ↑y) ≤ 1/2 ∧ int.fract (p * ↑y) ≤ 1/2 → m ≤ p ∧ m ≤ p ∧ m ≤ p ∧ m ≤ p ∧ m ≤ p ∧ m ≤ p ∧ m ≤ p ∧ p ≤ n,
  from sorry,

  have h29 : ∃ m, ∀ n, ∃ p, int.fract (p * ↑y) ≤ 1/2 ∧ int.fract (p * ↑y) ≤ 1/2 → m ≤ p ∧ m ≤ p ∧ m ≤ p ∧ m ≤ p ∧ m ≤ p ∧ m ≤ p ∧ m ≤ p ∧ m ≤ p ∧ p ≤ n,
  from sorry,

  have h30 : ∃ m, ∀ n, ∃ p, int.fract (p * ↑y) ≤ 1/2 ∧ int.fract (p * ↑y) ≤ 1/2 → m ≤ p ∧ m ≤ p ∧ m ≤ p ∧ m ≤ p ∧ m ≤ p ∧ m ≤ p ∧ m ≤ p ∧ m ≤ p ∧ m ≤ p ∧ p ≤ n,
  from sorry,

  have h31 : ∃ m, ∀ n, ∃ p, int.fract (p * ↑y) ≤ 1/2 ∧ int.fract (p * ↑y) ≤ 1/2 → m ≤ p ∧ m ≤ p ∧ m ≤ p ∧ m ≤ p ∧ m ≤ p ∧ m ≤ p ∧ m ≤ p ∧ m ≤ p ∧ m ≤ p ∧ m ≤ p ∧ p ≤ n,
  from h30,

  have h32 : ∃ m, ∀ n, ∃ p, int.fract (p * ↑y) ≤ 1/2 ∧ int
end --Needs more than 2000 tokens!

--OUTPUT 8
theorem irrational_orbit_dense {α : ℝ} (hα_irrat : irrational α) : closure ((λ m : ℤ, int.fract (α * ↑m)) '' (@set.univ ℤ)) = set.Icc 0 1 :=
begin
  have h1 : (∃ m : ℤ, 0 < m) → (∃ m : ℤ, m < 0), from sorry,
  have h2 : irrational α → ∀ m : ℤ, ∀ n : ℤ, m ≠ n → int.fract (α * ↑m) ≠ int.fract (α * ↑n), from sorry,
  have h3 : ((λ (m : ℤ), int.fract (α * ↑m)) '' (@set.univ ℤ)) ∈ closure (λ (m : ℤ), int.fract (α * ↑m) '' (@set.univ ℤ)), from sorry,
  have h4 : closure (λ (m : ℤ), int.fract (α * ↑m) '' (@set.univ ℤ)) ⊆ closure (set.Icc 0 1), from sorry,
  have h5 : closure (set.Icc 0 1) ⊆ closure (λ (m : ℤ), int.fract (α * ↑m) '' (@set.univ ℤ)), from sorry,
  show closure (λ (m : ℤ), int.fract (α * ↑m) '' (@set.univ ℤ)) = set.Icc 0 1, from sorry,
end

--OUTPUT 9
theorem irrational_orbit_dense {α : ℝ} (hα_irrat : irrational α) : closure ((λ m : ℤ, int.fract (α * ↑m)) '' (@set.univ ℤ)) = set.Icc 0 1 :=
begin
  have h1 : ∀ (i j : ℤ), i ≠ j →
    int.fract (α * ↑i) ≠ int.fract (α * ↑j),
  from sorry,

  have h2 : ∀ i, i ∈ @set.univ ℤ → int.fract (α * ↑i) ∈ set.Icc 0 1,
  from sorry,

  show closure ((λ m : ℤ, int.fract (α * ↑m)) '' (@set.univ ℤ)) = set.Icc 0 1,
  from sorry,
end

--OUTPUT 10
theorem irrational_orbit_dense {α : ℝ} (hα_irrat : irrational α) : closure ((λ m : ℤ, int.fract (α * ↑m)) '' (@set.univ ℤ)) = set.Icc 0 1 :=
begin
  have h0 : ∀ i j : ℤ, i ≠ j → (int.fract (α * ↑i)) ≠ (int.fract (α * ↑j)), {
    assume i j h1,
    have h2 : (α * ↑i - (α * ↑i).floor) = (α * ↑j - (α * ↑j).floor), {
      rw int.fract_eq_sub_floor,
    },
    have h3 : α = ((((α * ↑i).floor : ℝ) - ((α * ↑j).floor : ℝ)) / (i - j)), {
      rw h2,
      field_simp,
    },
    have h4 : irrational α, {
      exact hα_irrat,
    },
    have h5 : irrational (((((α * ↑i).floor) - ((α * ↑j).floor)) / (i - j)) : ℝ), {
      rw ← h3,
      exact h4,
    },
    have h6 : (((((α * ↑i).floor) - ((α * ↑j).floor)) / (i - j)) : ℝ) ∉ (@set.univ ℚ), {
      have h7 : ℚ ∉ {r : ℝ | irrational r}, {
        exact (irrational_of_rat_of_irrational_of_ne_bot ℚ),
      },
      assumption,
    },
    have h8 : (((((α * ↑i).floor) - ((α * ↑j).floor)) / (i - j)) : ℝ) ∉ set.univ, {
      rw ← (@set.mem_univ ℝ _),
      exact h6,
    },
    have h9 : (((((α * ↑i).floor) - ((α * ↑j).floor)) / (i - j)) : ℝ) ∉ set.range ((λ (m : ℤ), (α * ↑m) - (α * ↑m).floor) : ℤ → ℝ), {
      sorry,
    },
    have h10 : (((((α * ↑i).floor) - ((α * ↑j).floor)) / (i - j)) : ℝ) ∉ set.univ, {
      rw ← (@set.mem_univ ℝ _),
      exact h9,
    },
    exact h10,
  },
  have h1 : ∀ i j : ℤ, i ≠ j → (int.fract (α * ↑i)) ∉ (λ (m : ℤ), int.fract (α * ↑m)) '' (@set.univ ℤ), {
    assume i j h2,
    have h3 : {m : ℤ | (int.fract (α * ↑m)) = (int.fract (α * ↑i))} ⊆ {m : ℤ | m = i}, {
      assume x h4,
      have h5 : int.fract (α * ↑x) = int.fract (α * ↑i), {
        exact h4,
      },
      have h6 : (int.fract (α * ↑x - α * ↑i)) = 0, {
        rw ← h5,
        field_simp,
      },
      rw int.fract_eq_sub_floor at h6,
      have h7 : int.fract (α * ↑x) = int.fract (α * ↑x - α * ↑i), {
        exact h6,
      },
      rw h7 at h5,
      have h8 : (int.fract (↑x * α - ↑i * α)) = (int.fract (α * ↑x - α * ↑i)), {
        have h9 : int.fract (↑x * α) = int.fract (α * ↑x),
        begin
          field_simp,
        end,
        have h10 : int.fract (↑i * α) = int.fract (α * ↑i), {
          field_simp,
        },
        rw h9 at h5,
        rw h10 at h5,
        exact h5,
      },
      have h11 : (int.fract (↑x * α - ↑i * α)) = 0, {
        exact h8,
      },
      have h12 : (int.fract (↑x * α - ↑i * α)) ∈ {r : ℝ | r = 0}, {
        exact h11,
      },
      have h13 : int.fract (↑x * α - ↑i * α) = 0, {
        have h14 : int.fract (↑x * α - ↑i * α) ∈ {r : ℝ | r = 0}, {
          exact h11,
        },
        rw ← (@set.mem_univ ℝ _),
        assumption,
      },
      rw h13 at h4,
      have h15 : ↑x * α - ↑i * α = 0, {
        field_simp,
      },
      have h16 : ↑x = ↑i, {
        rw ← @set.mem_univ ℤ _ at h4,
        have h17 : ↑x * α - ↑i * α = (↑x - ↑i) * α, {
          ring,
        },
        rw h17 at h15,
        have h18 : (↑x - ↑i) * α = 0, {
          exact h15,
        },
        have h19 : ↑x - ↑i = 0, {
          have h20 : α ≠ 0, {
            have h21 : ¬ (α = 0), {
              have h22 : irrational α, {
                exact hα_irrat,
              },
              have h23 : ¬ (α = 0), {
                have h24 : α ∈ (@set.univ ℝ), {
                  exact set.mem_univ α,
                },
                have h25 : α ∉ ({r : ℝ | rational r}), {
                  rw set.mem_compl,
                  exact h22,
                },
                exact h25,
              },
              exact h23,
            },
            exact h21,
          },
          field_simp,
        },
        exact h19,
      },
      have h17 : x = i, {
        exact h16,
      },
      exact h17,
    },
    have h18 : {m : ℤ | (int.fract (α * ↑m)) = (int.fract (α * ↑i))} ⊆ {i}, {
      have h19 : {m : ℤ | (int.fract (α * ↑m)) = (int.fract (α * ↑i))} ⊆ {m : ℤ | m = i}, {
        exact h3,
      },
      exact h19,
    },
    have h20 : {m : ℤ | (int.fract (α * ↑m)) = (int.fract (α * ↑i))} ⊆ {i}, {
      have h21 : {m : ℤ | (int.fract (α * ↑m)) = (int.fract (α * ↑i))} ⊆ {i}, {
        exact h3,
      },
      exact h21,
    },
    have h22 : {m : ℤ | m = i} ⊆ (λ (m : ℤ), (int.fract (α * ↑m))), {
      assume x h23,
      have h24 : x = i, {
        exact h23,
      },
      have h25 : int.fract (α * ↑x) = int.fract (α * ↑i), {
        have h26 : α ≠ 0, {
          have h27 : α ∈ @set.univ ℝ, {
            exact set.mem_univ α,
          },
          have h28 : α ∉ ({r : ℝ | rational r} : set ℝ), {
            rw set.mem_compl,
            exact hα_irrat,
          },
          exact h28,
        },
        have h29 : int.fract (α * ↑x - α * ↑i) = 0
end --Needs more than 2000 tokens!

/- FEW SHOT PROMPTS TO CODEX(START)
/--`theorem`
Power Set is Closed under Intersection
Let $S$ be a set.

Let $\powerset S$ be the power set of $S$.

Then:
:$\forall A, B \in \powerset S: A \cap B \in \powerset S$
`proof`
Let $A, B \in \powerset S$.

Then by the definition of power set, $A \subseteq S$ and $B \subseteq S$.

From Intersection is Subset we have that $A \cap B \subseteq A$.

It follows from Subset Relation is Transitive that $A \cap B \subseteq S$.

Thus $A \cap B \in \powerset S$ and closure is proved.
{{qed}}
-/
theorem power_set_intersection_closed {α : Type*} (S : set α) : ∀ A B ∈ 𝒫 S, (A ∩ B) ∈ 𝒫 S :=
begin
  assume (A : set α) (hA : A ∈ 𝒫 S) (B : set α) (hB : B ∈ 𝒫 S),
  have h1 : (A ⊆ S) ∧ (B ⊆ S), from sorry,
  have h2 : (A ∩ B) ⊆ A, from sorry,
  have h3 : (A ∩ B) ⊆ S, from sorry,
  show (A ∩ B) ∈  𝒫 S, from sorry,
end

/--`theorem`
Square of Sum
 :$\forall x, y \in \R: \paren {x + y}^2 = x^2 + 2 x y + y^2$
`proof`
Follows from the distribution of multiplication over addition:

{{begin-eqn}}
{{eqn | l = \left({x + y}\right)^2
      | r = \left({x + y}\right) \cdot \left({x + y}\right)
}}
{{eqn | r = x \cdot \left({x + y}\right) + y \cdot \left({x + y}\right)
      | c = Real Multiplication Distributes over Addition
}}
{{eqn | r = x \cdot x + x \cdot y + y \cdot x + y \cdot y
      | c = Real Multiplication Distributes over Addition
}}
{{eqn | r = x^2 + 2xy + y^2
      | c =
}}
{{end-eqn}}
{{qed}}
-/
theorem square_of_sum (x y : ℝ) : (x + y)^2 = (x^2 + 2*x*y + y^2) :=
begin
  calc (x + y)^2 = (x+y)*(x+y) : by sorry
  ... = x*(x+y) + y*(x+y) : by sorry
  ... = x*x + x*y + y*x + y*y : by sorry
  ... = x^2 + 2*x*y + y^2 : by sorry,
end

/--`theorem`
Identity of Group is Unique
Let $\struct {G, \circ}$ be a group. Then there is a unique identity element $e \in G$.
`proof`
From Group has Latin Square Property, there exists a unique $x \in G$ such that:
:$a x = b$

and there exists a unique $y \in G$ such that:
:$y a = b$

Setting $b = a$, this becomes:

There exists a unique $x \in G$ such that:
:$a x = a$

and there exists a unique $y \in G$ such that:
:$y a = a$

These $x$ and $y$ are both $e$, by definition of identity element.
{{qed}}
-/
theorem group_identity_unique {G : Type*} [group G] : ∃! e : G, ∀ a : G, e * a = a ∧ a * e = a :=
begin
  have h1 : ∀ a b : G, ∃! x : G, a * x = b, from sorry,
  have h2 : ∀ a b : G, ∃! y : G, y * a = b, from sorry,

  have h3 : ∀ a : G, ∃! x : G, a * x = a, from sorry,
  have h4 : ∀ a : G, ∃! y : G, y * a = a, from sorry,

  have h5 : ∀ a : G, classical.some (h3 a) = (1 : G), from sorry,
  have h6 : ∀ a : G, classical.some (h4 a) = (1 : G), from sorry,

  show ∃! e : G, ∀ a : G, e * a = a ∧ a * e = a, from by {
    use (1 : G),
    have h7 : ∀ e : G, (∀ a : G, e * a = a ∧ a * e = a) → e = 1, from by {
      assume (e : G) (h7 : ∀ a : G, e * a = a ∧ a * e = a),
      have h8 : ∀ a : G, e = classical.some (h3 a), from sorry,
      have h9 : ∀ a : G, e = classical.some (h4 a), from sorry,
      show e = (1 : G), from sorry,
    },
    sorry,
  }
end

/--`theorem`
Squeeze Theorem for Real Numbers
Let $\sequence {x_n}$, $\sequence {y_n}$ and $\sequence {z_n}$ be sequences in $\R$.

Let $\sequence {y_n}$ and $\sequence {z_n}$ both be convergent to the following limit:
:$\ds \lim_{n \mathop \to \infty} y_n = l, \lim_{n \mathop \to \infty} z_n = l$

Suppose that:
:$\forall n \in \N: y_n \le x_n \le z_n$

Then:
:$x_n \to l$ as $n \to \infty$
that is:
:$\ds \lim_{n \mathop \to \infty} x_n = l$

`proof`
From Negative of Absolute Value:
:$\size {x - l} < \epsilon \iff l - \epsilon < x < l + \epsilon$

Let $\epsilon > 0$.

We need to prove that:
:$\exists N: \forall n > N: \size {x_n - l} < \epsilon$

As $\ds \lim_{n \mathop \to \infty} y_n = l$ we know that:
:$\exists N_1: \forall n > N_1: \size {y_n - l} < \epsilon$

As $\ds \lim_{n \mathop \to \infty} z_n = l$ we know that:
:$\exists N_2: \forall n > N_2: \size {z_n - l} < \epsilon$

Let $N = \max \set {N_1, N_2}$.

Then if $n > N$, it follows that $n > N_1$ and $n > N_2$.

So:
:$\forall n > N: l - \epsilon < y_n < l + \epsilon$
:$\forall n > N: l - \epsilon < z_n < l + \epsilon$

But:
:$\forall n \in \N: y_n \le x_n \le z_n$

So:
:$\forall n > N: l - \epsilon < y_n \le x_n \le z_n < l + \epsilon$

and so:
:$\forall n > N: l - \epsilon < x_n < l + \epsilon$

So:
:$\forall n > N: \size {x_n - l} < \epsilon$

Hence the result.
{{qed}}

-/
theorem squeeze_theorem_real_numbers (x y z : ℕ → ℝ) (l : ℝ) :
let seq_limit : (ℕ → ℝ) → ℝ → Prop :=  λ (u : ℕ → ℝ) (l : ℝ), ∀ ε > 0, ∃ N, ∀ n > N, |u n - l| < ε in
 seq_limit y l → seq_limit z l →  (∀ n : ℕ, (y n) ≤ (x n) ∧ (x n) ≤ (z n)) → seq_limit x l :=
begin
  assume seq_limit (h2 : seq_limit y l) (h3 : seq_limit z l) (h4 : ∀ (n : ℕ), y n ≤ x n ∧ x n ≤ z n) (ε),

  have h5 : ∀ x, |x - l| < ε ↔ (((l - ε) < x) ∧ (x < (l + ε))),
  from sorry,

  assume (h7 : ε > 0),
  cases h2 ε h7 with N1 h8,
  cases h3 ε h7 with N2 h9,
  let N := max N1 N2,
  use N,

  have h10 : ∀ n > N, n > N1 ∧ n > N2 := sorry,
  have h11 : ∀ n > N, (((l - ε) < (y n)) ∧ ((y n) ≤ (x n))) ∧ (((x n) ≤ (z n)) ∧ ((z n) < l+ε)),
  from sorry,

  have h15 : ∀ n > N, ((l - ε) < (x n)) ∧ ((x n) < (l+ε)),
  from sorry,

  show  ∀ (n : ℕ), n > N → |x n - l| < ε,
  from sorry,
end

/--`theorem`
Density of irrational orbit
The fractional parts of the integer multiples of an irrational number form a dense subset of the unit interval
`proof`
Let $\alpha$ be an irrational number. Then for distinct $i, j \in \mathbb{Z}$, we must have $\{i \alpha\} \neq\{j \alpha\}$. If this were not true, then
$$
i \alpha-\lfloor i \alpha\rfloor=\{i \alpha\}=\{j \alpha\}=j \alpha-\lfloor j \alpha\rfloor,
$$
which yields the false statement $\alpha=\frac{\lfloor i \alpha\rfloor-\lfloor j \alpha\rfloor}{i-j} \in \mathbb{Q}$. Hence,
$$
S:=\{\{i \alpha\} \mid i \in \mathbb{Z}\}
$$
is an infinite subset of $\left[0,1\right]$.

By the Bolzano-Weierstrass theorem, $S$ has a limit point in $[0, 1]$. One can thus find pairs of elements of $S$ that are arbitrarily close. Since (the absolute value of) the difference of any two elements of $S$ is also an element of $S$, it follows that $0$ is a limit point of $S$.

To show that $S$ is dense in $[0, 1]$, consider $y \in[0,1]$, and $\epsilon>0$. Then by selecting $x \in S$ such that $\{x\}<\epsilon$ (which exists as $0$ is a limit point), and $N$ such that $N \cdot\{x\} \leq y<(N+1) \cdot\{x\}$, we get: $|y-\{N x\}|<\epsilon$.

QED
-/
theorem  irrational_orbit_dense {α : ℝ} (hα_irrat : irrational α) : closure ((λ m : ℤ, int.fract (α * ↑m)) '' (@set.univ ℤ)) = set.Icc 0 1 :=
FEW SHOT PROMPTS TO CODEX(END)-/


def Nat.Up (ub a i : Nat) := i < a ∧ i < ub

theorem Nat.Up.next {ub i} (h : i < ub) : Up ub (i+1) i := ⟨Nat.lt_succ_self _, h⟩

/-- A terminal byte slice, a suffix of a byte array. -/
structure ByteSliceT := (arr : ByteArray) (off : Nat)

namespace ByteSliceT

/-- The number of elements in the byte slice. -/
@[inline] def size (self : ByteSliceT) : Nat := self.arr.size - self.off

/-- Index into a byte slice. The `getOp` function allows the use of the `buf[i]` notation. -/
@[inline] def getOp (self : ByteSliceT) (idx : Nat) : UInt8 := self.arr.get! (self.off + idx)

end ByteSliceT

/-- Convert a byte array into a terminal slice. -/
def ByteArray.toSliceT (arr : ByteArray) : ByteSliceT := ⟨arr, 0⟩

/-- A byte slice, given by a backing byte array, and an offset and length. -/
structure ByteSlice := (arr : ByteArray) (off len : Nat)

namespace ByteSlice

/-- Convert a byte slice into an array, by copying the data if necessary. -/
def toArray : ByteSlice → ByteArray
| ⟨arr, off, len⟩ => arr.extract off len

/-- Index into a byte slice. The `getOp` function allows the use of the `buf[i]` notation. -/
@[inline] def getOp (self : ByteSlice) (idx : Nat) : UInt8 := self.arr.get! (self.off + idx)

/-- The inner loop of the `forIn` implementation for byte slices. -/
def forIn.loop [Monad m] (f : UInt8 → β → m (ForInStep β))
  (arr : ByteArray) (off _end : Nat) (i : Nat) (b : β) : m β :=
  if h : i < _end then do
    match ← f (arr.get! i) b with
    | ForInStep.done b => pure b
    | ForInStep.yield b => have := Nat.Up.next h; loop f arr off _end (i+1) b
  else pure b
termination_by _ => _end - i

attribute [simp] ByteSlice.forIn.loop
#check @ByteSlice.forIn.loop._eq_1