Zulip Chat Archive

Stream: general

Topic: Creating own Prop universe


Brandon Brown (Jul 21 2022 at 02:02):

So Prop as Sort 0 is special because of some axioms applied especially in that universe, particularly the fact that if P : Prop and a : P and b : P then definitionally a = b. Could you pick a random non-Prop universe, say Sort 23, and define these same axioms to apply just to Sort 23 and have another Prop universe? I ask because if so, I wonder if this could allow modeling other logics in Lean by just selecting a different type universe to work in as Prop and using a different set of axioms.

Kevin Buzzard (Jul 21 2022 at 02:15):

I would imagine that this axiom would be inconsistent because I can make bool in Sort 23

Patrick Johnson (Jul 21 2022 at 03:09):

It would allow you to prove false

import tactic

axiom ax (P : Sort 23) (a b : P) : a = b

example : false :=
by cases ax (ulift nat) 0 1

Chris Bailey (Jul 21 2022 at 03:29):

You would have to modify the kernel to play around with proof irrelevance and impredicativity as well. You can try mm0 if you want a system that does the pluggable axioms thing.

Chris Bailey (Jul 21 2022 at 03:30):

The inductive module also has some sort 0 behavior hard-coded for the large vs small elimination stuff.

Junyan Xu (Jul 21 2022 at 03:31):

I read that to do HoTT in Lean3/4 people need to disable large elimination from Prop (they don't modify the kernel, they just check separately that large elimination isn't used). I wonder what if we just define the identity type to lie in Type instead of Prop? Maybe that isn't enough, but what about just don't use Prop at all and make Type effectively the lowest universe?

Brandon Brown (Jul 21 2022 at 03:41):

@Patrick Johnson what if I re-defined equality to not be Prop-valued but Sort 23 valued?

Eric Wieser (Jul 21 2022 at 06:36):

Then I could still define old_eq as the current definition and prove false

Floris van Doorn (Jul 21 2022 at 10:20):

@Junyan Xu: that is what happens in practice (at least in the Lean 3 HoTT library). The fact that you disable large elimination just means you cannot do anything useful with Prop, and so it is not used.

Junyan Xu (Jul 21 2022 at 18:28):

@Floris van Doorn Yes it looks like that you somehow override the built-in = notation and your equality types lie in Type instead of Prop. However I can't find the definition of your custom equality type in the repo. Reading the repo is quite confusing, as Type* and Prop have different meaning than in contemporary Lean 3. I hope Type still means the same thing!

However, once you define a custom equality type that lies in Type and state the univalence axiom in terms of it, it seems that you can't derive a contradiction even if large elimination is allowed. At least this proof of false won't work because it depends on ua bswap = ua (iso.refl bool) which you get from proof irrelevance because they're both proofs of bool = bool : Prop; however if bool = bool : Type then bool = bool isn't necessarily a subsingleton so you can't seem to prove ua bswap = ua (iso.refl bool). So why is there a need to disable large elimination? Is it possible to derive a contradiction from the following?

universe u

inductive Id {α : Sort u} (a : α) : α  Type
| refl [] : Id a

infix `  `:50 := Id

structure is_iso {α β} (f : α  β) :=
(inv_fun : β  α)
(left_inv : Π a, inv_fun (f a)  a)
(right_inv : Π b, f (inv_fun b)  b)

structure iso (α β : Sort*) :=
(to_fun : α  β)
(is_iso : is_iso to_fun)

infix `  `:25 := iso

def iso.refl (α) : α  α := id, id, Id.refl, Id.refl
def transport {X Y} (h : X  Y) : X  Y := Id.rec (iso.refl X) h
constant ua {X Y} : is_iso (@transport X Y)

Junyan Xu (Jul 21 2022 at 18:28):

By the way, I have trouble getting the hott3 repo to work; when I do lean --make src/hott it seems to correctly download Lean 3.7.0 as specified in the leanpkg.toml, as confirmed by running lean --version. However errors like the following immediately appear:

/Users/xuj18/Desktop/hott3/src/hott/types/pi.lean:1:0: error: file 'hott/arity' not found in the LEAN_PATH
/Users/xuj18/Desktop/hott3/src/hott/types/pi.lean:1:0: error: file 'hott/cubical/square' not found in the LEAN_PATH

If I open the repo in VSCode I immediately get "Server has stopped with error code 1", and I guess that's due to incompatibiliy with latest VSCode Lean extension.

Gabriel Ebner (Jul 21 2022 at 18:29):

You need to run leanpkg configure first.

Junyan Xu (Jul 21 2022 at 18:32):

Thanks that works (for compilation)! But the VSCode problem isn't related to that right? I saw that leanpkg configure was run the first time I open a file in VSCode.

Gabriel Ebner (Jul 21 2022 at 18:33):

It works for me. What platform are you on?

Floris van Doorn (Jul 21 2022 at 18:36):

The definition of equality is here: https://github.com/gebner/hott3/blob/7ead7a8a2503049eacd45cbff6587802bae2add2/src/hott/init/path0.lean#L18

Floris van Doorn (Jul 21 2022 at 18:38):

Yes, that version of ua is inconsistent with large elimination. With large elimination you are able to prove that Id a b \equiv (a = b) (and Id a b \iso (a = b)) (just apply path induction / eq.rec for both functions and both proofs), so Id a b is a subsingleton.

Junyan Xu (Jul 21 2022 at 18:43):

@Gabriel Ebner I'm on Mac, the following is the output:

cannot parse: Miscellaneous:
cannot parse:   --help -h          display this message
cannot parse:   --version -v       display version number
cannot parse:   --githash          display the git commit hash number used to build this binary
cannot parse:   --run              executes the 'main' definition
cannot parse:   --doc=file -r      generate module documentation based on module doc strings
cannot parse:   --make             create olean files
cannot parse:   --recursive        recursively find *.lean files in directory arguments
cannot parse:   --trust=num -t     trust level (default: max) 0 means do not trust any macro,
cannot parse:                      and type check all imported modules
cannot parse:   --quiet -q         do not print verbose messages
cannot parse:   --memory=num -M    maximum amount of memory that should be used by Lean
cannot parse:                      (in megabytes)
cannot parse:   --timeout=num -T   maximum number of memory allocations per task
cannot parse:                      this is a deterministic way of interrupting long running tasks
cannot parse:   --threads=num -j   number of threads used to process lean files
cannot parse:   --tstack=num -s    thread stack size in Kb
cannot parse:   --deps             just print dependencies of a Lean input
cannot parse:   --path             display the path used for finding Lean libraries and extensions
cannot parse:   --json             print JSON-formatted structured error messages
cannot parse:   --server           start lean in server mode
cannot parse:   --server=file      start lean in server mode, redirecting standard input from the specified file (for debugging)
cannot parse:   --profile          display elaboration/type checking time for each definition/theorem
cannot parse:   -D name=value      set a configuration option (see set_option command)
cannot parse: Exporting data:
cannot parse:   --export=file -E   export final environment as textual low-level file
cannot parse:   --only-export=decl_name   only export the specified declaration (+ dependencies)
cannot parse:   --test-suite       capture output and status code from each input file $f in $f.produced and $f.status, respectively
lean: unrecognized option `--old'
Unknown command line option
Lean (version 3.7.0, commit 401f4b723054, Release)

Junyan Xu (Jul 21 2022 at 18:44):

maybe I need to remove the --old from command line options ...

Junyan Xu (Jul 21 2022 at 18:45):

Indeed it works now. Thanks!

Junyan Xu (Jul 22 2022 at 02:16):

Floris van Doorn said:

Yes, that version of ua is inconsistent with large elimination. With large elimination you are able to prove that Id a b \equiv (a = b) (and Id a b \iso (a = b)) (just apply path induction / eq.rec for both functions and both proofs), so Id a b is a subsingleton.

Thanks for the hint! I confirm that I can derive a contradiction from my ua, and now I agree that large elimination needs to be disabled. It suffices to show that Id_of_eq is a left inverse of eq_of_Id, and it's also easy to show that they form an equiv/iso:

def Id_of_eq {α} {a b : α} (h : a = b) : a  b := eq.rec (Id.refl a) h
def eq_of_Id {α} {a b : α} (h : a  b) : a = b := Id.rec rfl h

lemma inv_Id_of_eq {α} {a b : α} :
  function.left_inverse (@Id_of_eq α a b) (@eq_of_Id α a b) :=
λ h, by { apply Id.rec_on h, refl }

lemma subsingleton_of_injective {α β} {f : α  β} (hf : function.injective f) [subsingleton β] :
  subsingleton α := λ a a', hf $ subsingleton.elim _ _

def bnot_bnot' (b : bool) : bnot (bnot b)  b := Id_of_eq (bnot_bnot b)
def bswap : bool  bool := bnot, bnot, bnot_bnot', bnot_bnot'
example : false :=
begin
  have h1 : transport (ua.inv_fun bswap) tt = ff :=
    congr_arg (λ e : bool  bool, e tt) (eq_of_Id $ ua.right_inv bswap),
  haveI : subsingleton (bool  bool) := subsingleton_of_injective inv_Id_of_eq.injective,
  have h2 : ua.inv_fun bswap = ua.inv_fun (iso.refl _) := subsingleton.elim _ _,
  rw [h2, eq_of_Id (ua.right_inv _)] at h1, cases h1,
end

def Id_iso_eq {α} {a b : α} : (a  b)  (a = b) :=
eq_of_Id, Id_of_eq, λ h, by { apply Id.rec_on h, apply Id.refl }, Id.refl⟩⟩

Last updated: Dec 20 2023 at 11:08 UTC