Skip to content

feat: add language interface#323

Draft
ayhon wants to merge 19 commits intoleanprover-community:masterfrom
ayhon:fele/feat/add-language-interface
Draft

feat: add language interface#323
ayhon wants to merge 19 commits intoleanprover-community:masterfrom
ayhon:fele/feat/add-language-interface

Conversation

@ayhon
Copy link
Copy Markdown
Contributor

@ayhon ayhon commented Apr 21, 2026

Description

Port the file program_logic/language.v. I needed to make multiple changes to the file while porting, since the Rocq definition was using canonical structures, which is something that doesn't exist in Lean. This interface instead relies on various typeclasses, and assumptions about them (for instance, one Expr may only have one Val, State and Obs types associated, since they are marked as outParams).

Main differences:

  • Identifiers were changed to follow Mathlib's naming guidelines.
  • The language structure is now a Language typeclass, which embeds separate ToVal and PrimStep typeclasses.
  • Added a coercion for ofVal, with most relevant theorems defined in terms of it (SUBJECT TO CHANGE).
  • Added notations for the different kinds of steps.
  • The primStep notation now makes use of a product Expr x State instead of taking them as separate parameters.

Some other changes needed to implement this file

  • Added Relation.ReflTransGen from Mathlib.
  • Added a new Relation.Iterate construction.
  • Added some lemmas about Forall₂.

Checklist

  • My code follows the mathlib naming and code style conventions
  • I have updated PORTING.md as appropriate
  • I have added my name to the authors section of any appropriate files

ayhon added 18 commits April 21, 2026 15:36
In the end, it seems like around `40` is quite a good precedence level.

If we look at `Notation.lean`, we see the precedence levels of various
notations.

```
@[inherit_doc] infixr:90 " ∘ "  => Function.comp
@[inherit_doc] infixr:35 " × "  => Prod
@[inherit_doc] infixr:35 " ×' " => PProd
@[inherit_doc]  infix:50 " ∣ " => Dvd.dvd
@[inherit_doc] infixl:55 " ||| " => HOr.hOr
@[inherit_doc] infixl:58 " ^^^ " => HXor.hXor
@[inherit_doc] infixl:60 " &&& " => HAnd.hAnd
@[inherit_doc] infixl:65 " + "   => HAdd.hAdd
@[inherit_doc] infixl:65 " - "   => HSub.hSub
@[inherit_doc] infixl:70 " * "   => HMul.hMul
@[inherit_doc] infixl:70 " / "   => HDiv.hDiv
@[inherit_doc] infixl:70 " % "   => HMod.hMod
@[inherit_doc] infixl:75 " <<< " => HShiftLeft.hShiftLeft
@[inherit_doc] infixl:75 " >>> " => HShiftRight.hShiftRight
@[inherit_doc] infixr:80 " ^ "   => HPow.hPow
@[inherit_doc] infixl:65 " ++ "  => HAppend.hAppend
@[inherit_doc] prefix:75 "-"     => Neg.neg
@[inherit_doc] prefix:100 "~~~"  => Complement.complement
@[inherit_doc] postfix:max "⁻¹"  => Inv.inv
@[inherit_doc] infixr:73 " • " => HSMul.hSMul
```

If we take further into account that the precedence of the
arrow `→` is `25`, then my earlier choice of `40` makes it
weaker than all other usual operators, but still stronger than
implication, which is roughly where I wanted to place it.
One actually cannot make the definition of `NSteps` use `Iterate`
because `Step` is a tagged relation, and `Iterate` does not
support merging the observations between `Step`s.
Actually, we can see `List Obs` to be the free monoid of `Obs`, so
we don't actually gain any expressivity by changing the definition.
Maybe it would make for a nicer API, but it doesn't warrant making
the change at this stage.
@ayhon ayhon force-pushed the fele/feat/add-language-interface branch from e160189 to 6828180 Compare April 21, 2026 13:42
@lzy0505 lzy0505 linked an issue Apr 24, 2026 that may be closed by this pull request
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.

Port program_logic/language.v

1 participant