简体   繁体   中英

Decidable equality in Agda with less than n^2 cases?

I've got a datatype for the AST of a programming langauge that I'd like to reason about, but there are about 10 different constructors for the AST.

data Term : Set where
  UnitTerm : Term
  VarTerm : Var -> Term
  ...
  SeqTerm : Term -> Term -> Term

I'm trying to write a function that has decidable equality for syntax trees of this language. In theory this is straightforward: there's nothing too complicated, it's just simple data being stored in the AST.

The problem is that writing such a function seems to require about 100 cases: for each constructor, there's 10 cases.

  eqDecide : (x : Term) -> (y : Term) -> Dec (x ≡ y)
  eqDecide UnitTerm UnitTerm = yes refl
  eqDecide UnitTerm (VarTerm x) = Generic.no (λ ())
  ...
  eqDecide UnitTerm (SeqTerm t1 t2) = Generic.no (λ ())
  EqDecide (VarTerm x) UnitTerm = Generic.no (λ ())
  ...

The problem is, there are a bunch of redundant cases. After the first pattern match where the constructors match, ideally I could match with underscore, since no possible other constructor could unify, but it doesn't appear that I can do that.

I've tried and failed to use this library to derive the equality: I'm running into problems with strict positivity, as well as getting some general errors that I'm are pretty hard to debug. The Agda Prelude also has some facility for this, but looks pretty immature, and is lacking some things that I need from the standard library.

How do people do decidable equality in practice? Do they suck it up and just write all 100 cases, or is there a trick I'm missing? Is this just a place where the newness of the language is showing through?

If you want to avoid using reflection and still prove decidable equality in a linear number of cases, you could try the following approach:

  1. Define a function embed : Term → Nat (or to some other type for which decidable equality is easier to prove such as labelled trees).
  2. Prove that your function is indeed injective.
  3. Make use of the fact that your function is injective together with decidable equality on the result type to conclude decidable equality on Term s (see for example via-injection in the module Relation.Nullary.Decidable in the standard library).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM