OrgPad logo

LEAN (very outdated)

Created by Martin Dvořák

#computer science

LEAN (very outdated)

Existential quantification

In situations where p x : Prop we cannot write
Σ x : α, p x
but we can write
∃ x : α, p x
which is both correct and idiomatic.

Tuples (prod) aren't enough to express existential quantification.

Differences

Both Π and are notations for the same kernel expressions. They are not inductive types. They are more "primitive" than other types. They use a built-in term constructor; it is not the same kind of constructor as structures have.

However, Σ is an inductive type.
core.html#sigma

In addition to that, is also an inductive type.
logic.html#exists 

As a consequence, Σ and  have different meanings.
In contrast, Π and mean exactly the same thing.

 

universes u v
def Pi' {α : Sort u} (x : α → Sort v) := Π i, x i
#check @Pi'.{u v}
#check @psigma.{u v}
#check @sigma.{u v}
#check @Exists.{u}

Universal quantification

In situations where p x : Prop we write
∀ x : α, p x
as a syntactic sugar for
Π x : α, p x
which would be less idiomatic to write.

Functions () aren't enough to express universal quantification.

Tuple type (cartesian product)

τ : Type
bar : τ

δ : Type
baz : δ

Consider the following declaration.

mtt = τ × δ

The symbol × refers to prod and not to Σ. However, a conceptually same thing could be expressed by a Σ-type.

mst = Σ x : τ, δ

Here δ doesn't depend on x.
We obtained a cartesian product of our types τ and δ. Don't get confused by the fact that a cartesian product is expressed by a dependent sum type (and not by a dependent product type).

The type prod further defines a notation with parentheses. Hence a term (bar, baz) stands  for prod.mk bar baz of the type mtt and nothing else.
In comparison bar, baz⟩ can stand for either prod.mk bar baz or sigma.mk bar baz and the exact type is inferred from the context.
If we write it explicitly, we can obtain (prod.mk bar baz) : mtt or (sigma.mk bar baz) : mst only.

The parentheses associate to the right (as well as chevrons do), hence (a,b,c) means the same as (a,(b,c)) and they both denote a term of the type T×U×V = T×(U×V) = prod T (prod U V) assuming that a:T, b:U, c:V.

In general, prod is preferred over sigma wherever possible. It has a better type inference and the code is more readable.

Sigma type

The dependent sum type (a.k.a. "dependent pair type"), or Σ-type for short ("sigma type"), is a generalization of tuple types.

α : Type

β : α → Type

mdst = Σ x : α, β x

Any z : mdst is of the form z = ⟨a,b⟩ where a : α and b : (β a).

def f : ℕ → Type
| 0 := ℕ
| 1 := ℤ
| _ := ℕ
def g : ℕ → Type
| _ := ℤ
def foo : sigma f := ⟨1, (2 : ℤ)⟩
def bar : sigma g := ⟨1, (2 : ℤ)⟩
lemma also_does_not_typecheck : foo = bar := sorry

Pi type

The dependent product type (a.k.a. "dependent function type"), or Π-type for short ("pie type"), is a generalization of function types.

α : Type

β : α → Type

mdpt = Π x : α, β x

Any f : mdpt is a function with the property that, for each a : α,  we have (f a) : (β a).

Function type

τ : Type

δ : Type

Consider the following declaration.

mft = τ → δ

It is just a convenient notation for a Π-type.

mft = Π x : τ , δ

Here δ doesn't depend on x.

cases_on

Working with inductive types

rec_on

Inductive types

Every type other than the universes and every type constructor other than Π belongs to a general family of type constructions known as inductive types.

Constructors with arguments

If the type foo has only one constructor,  it is automatically named foo.mk and it can automatically be envoked by writing ⟨bar, baz⟩ as a syntactic sugar for foo.mk bar baz in case of a constructor with two arguments (in this example). The chevrons associate to the right, hence ⟨a,b,c means the same as ⟨a,⟨b,c⟩ and so on.

Enumerated Types

inductive foo : Sort u
| constructor1 : ... → foo
| constructor2 : ... → foo
...
| constructorN : ... → foo

Quantifiers use dependent types

Structures

essentially single-constructor inductive types with some syntactic sugar

Types can depend also on "values"

That's why it is called "dependent type theory".

1. objects

2. types

3. universes

Lambda cube

image

https://en.wikipedia.org/wiki/Lambda_cube 

Many can be inferred automatically

TODO

Implicit arguments

TODO

Conceptual levels

image

Type*

any level

Sort*

Type* or Prop

Propositional logic is straightforward

Mandatory from outside

Vanilla lambda calculus

https://en.wikipedia.org/wiki/Lambda_calculus 

Functions defined by lambda expressions

Universes are non-cumulative

Agda also has non-cumulative universes. Coq has cumulative universes, i.e., whenever x : Type u we also have x : Type v for every v > u.

Optional from inside

Infinite (countable) hierarchy

7 : int : Type : Type 1 : Type 2 : Type 3 : (...)

Type = Type 0 = Sort 1

Prop = Sort 0

namespace <name>

begins the namespace

Dot notation

namespace.lemma

namespace.definition

namespace.namespace.tactic

...

Also denote the scope of "variables" and "local definitions"

Namespaces can contain namespaces

rfl

proves equality from definition

rfl is a short for eq.refl _

Universe levels

Displays the type of the term

#check -3 gives int

#check int gives Type

#check Type gives Type 1

Even stronger datatypes

end <name>

closes the namespace

Commands

Namespaces can contain sections

Theorem has a proof iff its type has an instance

A proof in Lean is a function of the given type, that is, a construction of a term of the type representing the theorem.

match

unpacks and renames a term from "before :" and then another := must follow

Arithmetics is complicated

untyped_lambda_arithmetic.pdf

Can be nested

Often suitable to mark private

lemma

formally the same as theorem ;  better for auxiliary theorems (lemmata)

Proofs as terms (term-style proofs)

forward proofs

Simply-typed lambda calculus

https://en.wikipedia.org/wiki/Simply_typed_lambda_calculus 

Command #check

Interaction with types

Displays the normal form

beta-equivalent expression ("reduct")

open <name>

"imports" the namespace (rather allows to omit the prefix <name>.)

Namespaces

But sections cannot contain namespaces

theorem

best to use for important theorems

example

no name; cannot be refferred to

assume

syntactic sugar for λ which is recommended for preconditions (better readability)

Command #reduce

Basic principle is myterm : mytype

Tutorial

https://agentultra.github.io/lean-4-hackers/

Howard–Curry correspondence

https://en.wikipedia.org/wiki/Curry%E2%80%93Howard_correspondence 

Keywords to introduce a statement

#print axioms

#print axioms mytheorem prints all axioms that were used in the proof of the theorem mytheorem

Calculus of Inductive Constructions

Lean is based on this type theory.

Command #eval

Displays some reduced form

less trustworthy than #reduce but far more efficient

Default currying

Every function is a unary function.

bool

Two "values" (actually types):

Lean 2

Lean 3

Lean 4

Every type is a term itself

}

inside a begin ... end block, a nested end can be abbreviated to }

NOT every term IS a type

BUT every term HAS a type

Prop

Similar to Haskell

https://www.haskell.org/ 

Command def

defines new terms and names them

Metaprogramming

TODO

Boolean stuff

No double negation cancellation

Versions

The project began in 2013.

{

inside a begin ... end block, a nested begin can be abbreviated to {

Intuitionistic logic

LEAN

end

closes the interactive mode

by

in position of a term; the next token is a tactic (only one) that provides witness to the current term (only one)

by exact (useless)

outside of the interactive mode, writing by exact foo is equivalent to just writing foo

rintros

intros together with rcases applied to each part

Extras

In comparison to the Calculus of Inductive Constructions, the following two features are added.

Propositional extensionality

axiom propext {a b : Prop} : 
(a ↔ b) → (a = b)

:

Head:tail in Haskell

Type in Lean

::

Type in Haskell

Head::tail in Lean

Typeclasses

Pure functional programming

Programming language

Interactive theorem prover

Writing proofs

begin

opens the interactive mode

Double negation cancellation (explicit)

axiom dnc :
∀ (a : Prop), (¬(¬a)) a

Similar to interfaces in OOP

Examples

Instances

Execution is slow

Community

exact

answers current goal by a proof term

Functions normally need a proof of termination

Verify mathematics

Bring formal methods to the masses

rintro

intro together with rcases

intros

applies intro repeatedly; can be used with argument names or without (then it eats as much as it can and assigns default names to the eaten terms)

No law of excluded middle

Choice

The axiom classical.choice is a type-theoretic statement that implies the set-theoretic axiom of choice.

Xenaproject

The mathlib

Goals

obtain

like have together with rcases

:=

Declaration in Lean

Only a few syntactic differences

Quotient types

??

often used to avoid setoids

Strict notion of equality

By default, two terms are equal, if they beta-reduce to the same term, that is, they are "somewhere deep inside" both made by the same tree of constructors.

TODO

TODO

TODO

Microsoft Research

Zulip chat for Lean

Projects based on mathlib

Group A

interface between proof terms and tactics

Naming conventions

https://leanprover-community.github.io/contribute/naming.html

Verify software

Support formal methods in education

library_search

searches the library for a single exact ... that closes the goal; otherwise (theorem for the current goal is not found), it fails

Verify hardware

have

introduces an auxiliary proposition (inside a proof)

POT can usually be inferred automatically

Probably isn't Turing complete

suggest

like library_search but shows more stuff, including lemmata for which preconditions haven't been provided

sorry

not proved yet; generates a warning during compilation and is listed by #print axioms

Law of excluded middle (explicit)

axiom lem :
∀ (a : Prop), a ∨ ¬a

=

Declaration in Haskell

Relation operator (id) in Lean

==

Relation operator (id) in Haskell

No axiom of choice

Independence of the continuum hypothesis

https://github.com/flypitch/flypitch 

Type classes

TODO

Focus on classical mathematics

intro

eats the first part of the curent goal and saves it into a variable

use

fills in existentially-quantified variable in the current goal (which must begin by )

TODO

Leonardo de Moura

http://leodemoura.github.io/ 

Mario Carneiro

https://www.cmu.edu/dietrich/philosophy/people/phd/mario-carneiro.html 

Kevin Buzzard

https://www.imperial.ac.uk/people/k.buzzard 

Perfectoid spaces

https://github.com/leanprover-community/lean-perfectoid-spaces 

rcases

recursive cases but requires separating parts by commas

hint

lists possible tactics which will make progress (that is, not fail) towards the current goal

Group S

what you can write when don't know how to (or don't want to) solve a goal

by_cases

splits the goal into two goals by a condition (proposition); one when holds, one when doesn't

cases

decomposes a terms according to its constructor(s); similar to destruct in Coq

with

assigns names to the outputs of the command on the left (e.g. cases)

Can be added as an axiom of your theory

Axiom of choice (explicit)

axiom choice {α : Sort*} :
(nonempty α) α

VIPs

contrapose

proof by contradiction (needs classical logic)

Group B

quantifiers, logical connectives, ...

Function extensionality

theorem funext : ∀ {α : Type u₁} {β : α → Type u₂}

{f₁ f₂ : Π (x : α), β x},

(∀ (x : α), f₁ x = f₂ x) →
(f₁ = f₂))

This should follow from quotients but I don't understand what it means.

Set extensionality

theorem setext {a b : set α}
(h : ∀ x, x ∈ a ↔ x ∈ b) :
(a = b) :=

funext (λ x, propext (h x))

simp * at *

tries to simplify both the goal and all hypotheses, using all hypotheses and all simp lemmas (defaults)

itauto

uses only intuitionistic logic

contrapose!

contrapose followed by push_neg

Group N

stuff around negations

Interactive mode (tactic-style proofs)

backward proofs (unless something modifies their structure)

unfold*

TODO

Folders

@[simp]

writing @[simp] theorem mytheorem declares a new theorem and automatically invokes attribute [simp] mytheorem

dunfold*

TODO

ext

breaks the goal identity into several identities to be proved (use e.g. for tuples)

simp at *

works on all hypothesis and the goal

exfalso

replaces the current goal (no matter what it is) by false

simp ... ⊢

simp [h1] at h2 ⊢ tries to simplify both h2 and the goal using h1 and all simp lemmas (defaults)

apply

applies a transformation to the current goal (proving stuff "backwards"), then it attemps refl

simp *

uses all hypotheses present in the local context (and all defaults) when simplifying the goal

tauto

sound and fast but incomplete SAT+ solver

finish

tries to finish the proof automatically (slow and incomplete, of course)

unfold

expands a term using its definition

Ordinals

well-ordered types modulo order-isomorphism

src/computability

dec_trivial

tries to definitionally reduce expressions to true or false

dunfold

TODO

induction

mathematical induction; transforms the current goal into a base step and an induction step

Cardinals

types modulo equivalence

src/data

local attribute

local attribute [simp] myrule adds myrule into the list of simplification rules  for the current file or section (local scope)

attribute

attribute [simp] myrule adds myrule into the (global) list of simplification rules

simp at

works on a given hypothesis instead

Group T

tactics

Group R

stuff around binary relations

delta

replaces a term by its definition (without any simplification)

left

short for apply or.inl

right

short for apply or.inr

Quotient group

"faktorgrupa"

other collections

attribute [mysimps] myrule adds myrule into the (custom) list of simplification rules called mysimps

simp

attempts to simplify the current goal; probably the most powerful tactic out there

linarith

attempts to reach a contradiction using elementary properties of inequalities (transitivity, sums, ...)

Examples

src/category_theory

simp with

simp with mysimps adds all the rules that have been marked with the attribute [mysimps] to the default set of rules marked with the attribute [simp] before applying simp

simpa

attempts to simplify and solve the current goal; if it is unable to close the goal, it fails

src/algebra

image

ring

attempts to solve the current goal (if it is an algebraic identity) using properties of commutative (semi)rings (commutativity, associativity, distributivity (left and right), zero and one)

subst

rewrites all occurences in the goal and clears

calc

solves the current goal from an explicitly given series of identities and/or inequalities; applies transitivity to them (many possible forms)

reflexivity

closes a goal of type x = x or some xRx for any reflexive relation R

is more general than rfl

works on any relation that has been tagged by the attribute refl

wlog

reduces more goals into a single goal using permutations of variables

split

breaks conjunction (or equivalence) into two goals

case

specifies which goal will be worked on now

Tensor product of modules

Cauchy completion

src/linear_algebra

TODO

https://github.com/leanprover-community/mathlib/tree/master/src/linear_algebra 

src/topology

run_cmd

before using the (custom) list of simplification rules called mysimps we must create it using run_cmd mk_simp_attr `mysimps

simpa using

attempts to simplify the right side and close the current goal with that result; if it is unable to close the goal, it fails

simp without

???

probably removes a whole collection of rules

any_goals

any_goals { bar, baz } applies { bar, baz } to all open goals; only if all branches fail, any_goals fails

specialize

substitutes a variable by a given term

Colimit of rings

Stone-Čech compactification

simp [–rule]

uses the defaults (simp lemmas) excluding the given rule(s)

simp [rule]

uses the given rules(s) for simplification and also defaults (so-called simp lemmas)

simp only [rule]

uses only the given rule(s) for simplication; excludes defaults

transitivity

if the current goal is rXy for a transitive relation R, it will get replaced by two goals xRt and tRy for a new variable t (or by putting a term from an argument in place of t)

symmetry

swaps the left side and the right side of the current goal (which must be a symmetric relation)

refl

short for reflexivity

`

the backtick indicates a new name

ring_nf

???

probably something about normal form

rewrite

performs a substitution (using a given identity or equivalence — from left to right) to the current goal

all_goals

all_goals { bar, baz } applies { bar, baz } to all open goals; if any branch fails, all_goals fails

generalize

substitutes a term by a new variable

simp_rw

like rw it applies identities/equivalences in the given order, but it also rewrites terms under binders ( or  or λ)

rw

short for rewrite

rewrite at

to a given variable instead of to the current goal

rewrite ←

given identity or equivalence is used from right to left instead

Group C

working with "structure" of the proof script

revert

reverts the effect of intro or generalize

repeat

repeat { foo } applies foo repeatedly until it fails;
it also goes to subgoals (and the recursion stops in a subgoal when the tactic has failed to make progress)

rwa

rw followed by assumption

useful to write rwa equ at foo instead of rw equ at foo, exact foo

iterate

iterate 3 { foo } applies foo three times

assumption

tries to satisfy the current goal by something from current context (fails otherwise)

try

try { foo } invokes foo but doesn't fail if foo fails; instead, the goal simply stays unchanged

show

selects which open goal the script will solve now