Conversation
| ``` | ||
| data CompatVar (@++ R : Relation) : Relation where | ||
| `F_ : | ||
| ∀ {X} (x : Fin X) |
There was a problem hiding this comment.
I find this notation confusing. I'm used to seeing X as representing any type (of type Set usually). Whereas, X : ℕ here, so it's actually just a number! x is also just a number, but wrapped by Fin.
Would the following notation be better?
| ∀ {X} (x : Fin X) | |
| ∀ {n} (nᶠ : Fin n) |
or
| ∀ {X} (x : Fin X) | |
| ∀ {n} (n↑ : Fin n) |
or whatever you think is better.
There was a problem hiding this comment.
Agreed that X is awkward. It is a left-over from when the metatheory used nested maybe's for representing scope size. Right now this is consistent with all other uses in the codebase like X ⊢. We should change this project-wide.
There was a problem hiding this comment.
I actually don't mind x personally, since it represents an (arbitrary) variable name in the ast, it just happens to be represented by a natural. But perhaps v is also good?
There was a problem hiding this comment.
Both x and v are ok, although tying it to the n in some way is more helpful to me since it indicates we're using Debruijn
There was a problem hiding this comment.
I've opened https://github.com/IntersectMBO/plutus-private/issues/2182, it's probably better to do that in a separate PR.
| pointwise? : ∀ {R : Relation} → | ||
| DecidableRel R → | ||
| ∀ {X} (Ms Ns : List (X ⊢)) → | ||
| Dec (Pointwise R Ms Ns) | ||
| pointwise? R? [] [] = yes [] | ||
| pointwise? R? (x ∷ xs) (y ∷ ys) | ||
| with R? x y ×-dec pointwise? R? xs ys | ||
| ... | yes (Rxy , Rxsys) = yes (Rxy ∷ Rxsys) | ||
| ... | no ¬R = no λ {(R ∷ Rs ) → ¬R (R , Rs)} | ||
| pointwise? R? (_ ∷ _) [] = no λ () | ||
| pointwise? R? [] (_ ∷ _) = no λ () |
There was a problem hiding this comment.
Why is this decision procedure defined here instead of where the Pointwise type is defined?
Actually, why are the decision procedures for all of the relations defined in this module? Would it be better to have a Untyped.Relation.Decidable module?
There was a problem hiding this comment.
I've moved pointwise? now to Untyped.Binary.Core. The decision procedures are here because they are tied to the Modular approach, I'd rather have them contained here. We could move them to Untyped.Relation.Binary.Modular.Decidable perhaps, but I don't think it's too bad to keep it all in a single module for now.
Co-authored-by: Ana Pantilie <45069775+ana-pantilie@users.noreply.github.com>
zliu41
left a comment
There was a problem hiding this comment.
If I understand correctly this is a quite complex way of saying: "If M reduces to M' via case-reduce, pass, else fail".
As we discussed, this has the disadvantage of tight coupling with the compiler: for example, if the compiler is changed such that it stops reducing case-constr in certain cases, then the certifier would break. I thought we've discussed an approach that doesn't have such tight coupling?
|
|
||
| ``` | ||
| _~_ : Relation | ||
| _~_ = Fix (Reduction + CompatTerm + Transitivity + Symmetry + Reflexivity) |
There was a problem hiding this comment.
What's the point of having this relation, and why does it need to be symmetric or reflexive?
There was a problem hiding this comment.
For the same reason why the force-delay paper has an equivalence: it is (more) obviously semantics preserving, and since the case-reduce pas in Agda is a re-implementation of the Haskell implementation, a mistake there could carry over to Agda. It also becomes easier to count the optimization sites using a relation vs a function.
There was a problem hiding this comment.
I'd agree with the value of _~_ if its definition is much simpler and much more obviously correct than CaseReduce, but their complexities seem similar.
Also, since CaseReduce performs the actual reduction that the compiler does, doesn't it already include compatibility closure, making the CompatTerm redundant?
|
|
||
| ``` | ||
| ## An Example: | ||
| reduceM : X ⊢ → Maybe (X ⊢) | ||
| reduceM = refine? (reduce {R = _~_}) |
There was a problem hiding this comment.
I find it confusing that the definition of CaseReduce mentions _~_. I thought they are supposed to be two completely separate relations, one is more of an actual reduction algorithm, and the other is a specification that is more obviously correct.
There was a problem hiding this comment.
Good point, that's not necessary here. R just needs to be instantiated to resolve ambiguity for the type checker, it's not actually used.
It also guarantees by construction that it is sound with respect to the inductive reduction rules.
Yes, I looked at two ways of doing that:
This is equally easy to decide, and less coupled because it allows case-reduction rules to be applied selectively: the compiler is allowed to not touch some case-constant/case-constructor. However, it also accepts the reverse application of reduction rules, which we deemed outside of the spec of the pass (this relation is sound/complete with the
This would also allow selective application of the reduction rules, but the decision procedure needs to do some reducing itself. Initially that made it hard to construct the proof of the relation, but with the sound-by-construction rules it may now not be that difficult anymore. Anyway, I'm happy to look into 2 more, but I wanted to get working certifiers for all passes first before generalizing more. |
This adds
CaseReduce.lagda.mdfor documentation on how it is structured.Untyped.Relation.Binary.{Core,Properties,Structures}. This mimics the module structure ofagda-stdlibUntyped.Relation.Binary.Modular), used by the equivalence relation of case-reduce, see the end of the module for an example how to build decidable relations.