A362583

Part of: The digit sequence has infinitely many ones and infinitely many zeros; and a rational constant would have eventually periodic digits.

Theorembits_infinite_ones

The set \{k \mid b_k = 1\} is infinite.

Lean code for Theorem bits_infinite_ones
  • theorem bits_infinite_ones : {k | bitA362583.bit (k : ℕ) : ℕ`k`-th bit of the constant: `1` iff the `k`-th odd prime is `≡ 3 (mod 4)`.
    The `b_{k+1}` of the 1-based bit sequence; first values `1 0 1 1 0 0 1 1`
    (primes `3, 5, 7, 11, 13, 17, 19, 23`).  k = 1}.InfiniteSet.Infinite.{u} {α : Type u} (s : Set α) : PropA set is infinite if it is not finite.
    
    This is protected so that it does not conflict with global `Infinite`.  
    theorem bits_infinite_ones : {k | bitA362583.bit (k : ℕ) : ℕ`k`-th bit of the constant: `1` iff the `k`-th odd prime is `≡ 3 (mod 4)`.
    The `b_{k+1}` of the 1-based bit sequence; first values `1 0 1 1 0 0 1 1`
    (primes `3, 5, 7, 11, 13, 17, 19, 23`).  k = 1}.InfiniteSet.Infinite.{u} {α : Type u} (s : Set α) : PropA set is infinite if it is not finite.
    
    This is protected so that it does not conflict with global `Infinite`.  

By Dirichlet's theorem at modulus 4 — in Mathlib's form, the primes \equiv 3 \pmod 4 form an infinite set — infinitely many primes lie in the class 3 \bmod 4. These transfer to bit indices along the injection sending a prime p to the number of primes below p, minus one; its inverse is the odd-prime enumeration k \mapsto p_k, and 2 is excluded since 2 \not\equiv 3 \pmod 4. So infinitely many indices k have p_k \equiv 3 \pmod 4, i.e. b_k = 1. \blacksquare

by`by tac` constructs a term of the expected type by running the tactic(s) `tac`. 
  haveThe `have` tactic is for adding opaque definitions and hypotheses to the local context of the main goal.
The definitions forget their associated value and cannot be unfolded, unlike definitions added by the `let` tactic.

* `have h : t := e` adds the hypothesis `h : t` if `e` is a term of type `t`.
* `have h := e` uses the type of `e` for `t`.
* `have : t := e` and `have := e` use `this` for the name of the hypothesis.
* `have pat := e` for a pattern `pat` is equivalent to `match e with | pat => _`,
  where `_` stands for the tactics that follow this one.
  It is convenient for types that have only one applicable constructor.
  For example, given `h : p ∧ q ∧ r`, `have ⟨h₁, h₂, h₃⟩ := h` produces the
  hypotheses `h₁ : p`, `h₂ : q`, and `h₃ : r`.
* The syntax `have (eq := h) pat := e` is equivalent to `match h : e with | pat => _`,
  which adds the equation `h : e = pat` to the local context.

The tactic supports all the same syntax variants and options as the `have` term.

## Properties and relations

* It is not possible to unfold a variable introduced using `have`, since the definition's value is forgotten.
  The `let` tactic introduces definitions that can be unfolded.
* The `have h : t := e` is like doing `let h : t := e; clear_value h`.
* The `have` tactic is preferred for propositions, and `let` is preferred for non-propositions.
* Sometimes `have` is used for non-propositions to ensure that the variable is never unfolded,
  which may be important for performance reasons.
    Consider using the equivalent `let +nondep` to indicate the intent.

 hidx := infinite_oddPrime_index infinite_primes_three_mod_four
    (fun p hp  hp.1) (fun h  absurd h.2 (by`by tac` constructs a term of the expected type by running the tactic(s) `tac`.  decide`decide` attempts to prove the main goal (with target type `p`) by synthesizing an instance of `Decidable p`
and then reducing that instance to evaluate the truth value of `p`.
If it reduces to `isTrue h`, then `h` is a proof of `p` that closes the goal.

The target is not allowed to contain local variables or metavariables.
If there are local variables, you can first try using the `revert` tactic with these local variables to move them into the target,
or you can use the `+revert` option, described below.

Options:
- `decide +revert` begins by reverting local variables that the target depends on,
  after cleaning up the local context of irrelevant variables.
  A variable is *relevant* if it appears in the target, if it appears in a relevant variable,
  or if it is a proposition that refers to a relevant variable.
- `decide +kernel` uses kernel for reduction instead of the elaborator.
  It has two key properties: (1) since it uses the kernel, it ignores transparency and can unfold everything,
  and (2) it reduces the `Decidable` instance only once instead of twice.
- `decide +native` uses the native code compiler (`#eval`) to evaluate the `Decidable` instance,
  admitting the result via an axiom. This can be significantly more efficient than using reduction, but it is at the cost of increasing the size
  This can be significantly more efficient than using reduction, but it is at the cost of increasing the size
  of the trusted code base.
  Namely, it depends on the correctness of the Lean compiler and all definitions with an `@[implemented_by]` attribute.
  Like with `+kernel`, the `Decidable` instance is evaluated only once.

Limitation: In the default mode or `+kernel` mode, since `decide` uses reduction to evaluate the term,
`Decidable` instances defined by well-founded recursion might not work because evaluating them requires reducing proofs.
Reduction can also get stuck on `Decidable` instances with `Eq.rec` terms.
These can appear in instances defined using tactics (such as `rw` and `simp`).
To avoid this, create such instances using definitions such as `decidable_of_iff` instead.

## Examples

Proving inequalities:
```lean
example : 2 + 2 ≠ 5 := by decide
```

Trying to prove a false proposition:
```lean
example : 1 ≠ 1 := by decide
/-
tactic 'decide' proved that the proposition
  1 ≠ 1
is false
-/
```

Trying to prove a proposition whose `Decidable` instance fails to reduce
```lean
opaque unknownProp : Prop

open scoped Classical in
example : unknownProp := by decide
/-
tactic 'decide' failed for proposition
  unknownProp
since its 'Decidable' instance reduced to
  Classical.choice ⋯
rather than to the 'isTrue' constructor.
-/
```

## Properties and relations

For equality goals for types with decidable equality, usually `rfl` can be used in place of `decide`.
```lean
example : 1 + 1 = 2 := by decide
example : 1 + 1 = 2 := by rfl
```
))
  refine`refine e` behaves like `exact e`, except that named (`?x`) or unnamed (`?_`)
holes in `e` that are not solved by unification with the main goal's target type
are converted into new goals, using the hole's name, if any, as the goal case name.
 hidx.mono fun k hk  ?_
  exact`exact e` closes the main goal if its target type matches that of `e`.
 bit_eq_one_iff.mpr hk.2

Local dependency graph