Skip to content

Exploit proof-irrelevance when lowering - #124

Closed
mvr wants to merge 19 commits into
coln-compiler/more-ir-testsfrom
coln-compiler/lower-prop
Closed

Exploit proof-irrelevance when lowering#124
mvr wants to merge 19 commits into
coln-compiler/more-ir-testsfrom
coln-compiler/lower-prop

Conversation

@mvr

@mvr mvr commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator

WIP for exploiting proof-irrelevance when lowering. This isn't hooked into the TypeScript FFI at all currently.

The basic-ir tests have a lot of instances where the result changes (for the better). In the monoid example, the tables for the equations disappear and become rules that assert those equalities directly.

Before:

flatrealm
  entities
    table ℜ.car := []
    table ℜ.unit := [.a : ℜ.car] primarykey []
    table ℜ.mul := [.a : ℜ.car, .b : ℜ.car, .c : ℜ.car] primarykey [.a, .b]
    table ℜ.mul/unitl := [.x : ℜ.car] primarykey [.x]
    table ℜ.mul/unitr := [.x : ℜ.car] primarykey [.x]
    table ℜ.mul/assoc := [.x : ℜ.car, .y : ℜ.car, .z : ℜ.car] primarykey [
      .x,
      .y,
      .z
    ]
  end
  rules
    enforced ℜ.car.foreignKey := ℜ.car [] ⊢ ⊤
    enforced ℜ.unit.foreignKey a := ℜ.unit [.a ↦ a] ⊢ a ∈ ℜ.car []
    monitored ℜ.unit.total := ⊤ ⊢ ℜ.unit []
    enforced ℜ.mul.foreignKey a b c := ℜ.mul [
      .a ↦ a,
      .b ↦ b,
      .c ↦ c
    ] ⊢ a ∈ ℜ.car [] ∧ b ∈ ℜ.car [] ∧ c ∈ ℜ.car []
    monitored ℜ.mul.total a b := a ∈ ℜ.car [] ∧ b ∈ ℜ.car [] ⊢ ℜ.mul [
      .a ↦ a,
      .b ↦ b
    ]
    enforced ℜ.mul/unitl.foreignKey x a.lhs a.lhs.a := ℜ.mul/unitl [
      .x ↦ x
    ] ∧ ℜ.unit [.a ↦ a.lhs.a] ∧ ℜ.mul [
      .a ↦ a.lhs.a,
      .b ↦ x,
      .c ↦ a.lhs
    ] ⊢ x ∈ ℜ.car [] ∧ a.lhs = x
    monitored ℜ.mul/unitl.total x := x ∈ ℜ.car [] ⊢ ℜ.mul/unitl [.x ↦ x]
    enforced ℜ.mul/unitr.foreignKey x a.lhs a.lhs.b := ℜ.mul/unitr [
      .x ↦ x
    ] ∧ ℜ.unit [.a ↦ a.lhs.b] ∧ ℜ.mul [
      .a ↦ x,
      .b ↦ a.lhs.b,
      .c ↦ a.lhs
    ] ⊢ x ∈ ℜ.car [] ∧ a.lhs = x
    monitored ℜ.mul/unitr.total x := x ∈ ℜ.car [] ⊢ ℜ.mul/unitr [.x ↦ x]
    enforced ℜ.mul/assoc.foreignKey x y z a.lhs a.lhs.a a.rhs a.rhs.b := ℜ.mul/assoc [
      .x ↦ x,
      .y ↦ y,
      .z ↦ z
    ] ∧ ℜ.mul [.a ↦ x, .b ↦ y, .c ↦ a.lhs.a] ∧ ℜ.mul [
      .a ↦ a.lhs.a,
      .b ↦ z,
      .c ↦ a.lhs
    ] ∧ ℜ.mul [.a ↦ y, .b ↦ z, .c ↦ a.rhs.b] ∧ ℜ.mul [
      .a ↦ x,
      .b ↦ a.rhs.b,
      .c ↦ a.rhs
    ] ⊢ x ∈ ℜ.car [] ∧ y ∈ ℜ.car [] ∧ z ∈ ℜ.car [] ∧ a.lhs = a.rhs
    monitored ℜ.mul/assoc.total x y z := x ∈ ℜ.car [] ∧ y ∈ ℜ.car [] ∧ z ∈ ℜ.car [] ⊢ ℜ.mul/assoc [
      .x ↦ x,
      .y ↦ y,
      .z ↦ z
    ]
  end
end

After:

flatrealm
  entities
    table ℜ.car := []
    table ℜ.unit := [.a : ℜ.car] primarykey []
    table ℜ.mul := [.a : ℜ.car, .b : ℜ.car, .c : ℜ.car] primarykey [.a, .b]
  end
  rules
    enforced ℜ.car.foreignKey := ℜ.car [] ⊢ ⊤
    enforced ℜ.unit.foreignKey a := ℜ.unit [.a ↦ a] ⊢ a ∈ ℜ.car []
    monitored ℜ.unit.total := ⊤ ⊢ ℜ.unit []
    enforced ℜ.mul.foreignKey a b c := ℜ.mul [
      .a ↦ a,
      .b ↦ b,
      .c ↦ c
    ] ⊢ a ∈ ℜ.car [] ∧ b ∈ ℜ.car [] ∧ c ∈ ℜ.car []
    monitored ℜ.mul.total a b := a ∈ ℜ.car [] ∧ b ∈ ℜ.car [] ⊢ ℜ.mul [
      .a ↦ a,
      .b ↦ b
    ]
    monitored ℜ.mul/unitl x a.lhs a.lhs.a := x ∈ ℜ.car [] ∧ ℜ.unit [
      .a ↦ a.lhs.a
    ] ∧ ℜ.mul [.a ↦ a.lhs.a, .b ↦ x, .c ↦ a.lhs] ⊢ a.lhs = x
    monitored ℜ.mul/unitr x a.lhs a.lhs.b := x ∈ ℜ.car [] ∧ ℜ.unit [
      .a ↦ a.lhs.b
    ] ∧ ℜ.mul [.a ↦ x, .b ↦ a.lhs.b, .c ↦ a.lhs] ⊢ a.lhs = x
    monitored ℜ.mul/assoc x y z a.lhs a.lhs.a a.rhs a.rhs.b := x ∈ ℜ.car [] ∧ y ∈ ℜ.car [] ∧ z ∈ ℜ.car [] ∧ ℜ.mul [
      .a ↦ x,
      .b ↦ y,
      .c ↦ a.lhs.a
    ] ∧ ℜ.mul [.a ↦ a.lhs.a, .b ↦ z, .c ↦ a.lhs] ∧ ℜ.mul [
      .a ↦ y,
      .b ↦ z,
      .c ↦ a.rhs.b
    ] ∧ ℜ.mul [.a ↦ x, .b ↦ a.rhs.b, .c ↦ a.rhs] ⊢ a.lhs = a.rhs
  end

Closes #13

mvr added 11 commits August 7, 2026 15:19
It feels excessive, but many of the combinations will end up being
lowered differently.

* `dependent-function-*` tests `(a : A) -> B a`
* `dependent-function-argument-*` tests `(a : A) -> (b : B a) -> C a b`
* `family-argument-*` tests `(a : A) -> B a -> Set/Prop`
* `lookup-{argument,field}-projection-*` tests families indexed by the output of a function
* `lookup-composition-*` tests the same for two a composite of functions
* `lookup-proof-result-argument` is a special case (could be expanded to 8 cases)
* `param-record-*` tests records parameterised by various things
* `param-record-type-family-* tests records parameterised by a type family specifically
* `proof-record-* tests records that contain a proof field
* `prop-record-* tests records that themselves live in `Prop`
* `equality-record-* tests equality of records
* `param-alias-*` tests parameterised records and aliases
* `empty-prop-record-function` tests functions into a trivial proposition
* `record-nested` is a minimal nested record case
Remove subsumed `lookup-proof-result-argument` special case
@mvr
mvr force-pushed the coln-compiler/lower-prop branch from f8aad5b to 4196ed3 Compare August 11, 2026 14:12
@mvr
mvr force-pushed the coln-compiler/more-ir-tests branch from 55ba392 to d8c4565 Compare September 1, 2026 15:55
@mvr
mvr deleted the branch coln-compiler/more-ir-tests September 3, 2026 10:40
@mvr mvr closed this Sep 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants