As a learning experience, I'm trying to implement a verified regular-expression matcher using continuation-passing style in Agda, based on the one proposed in this paper.
I've got a type for regular expressions defined like this:
data RE : Set where
ε : RE
∅ : RE
Lit : Char -> RE
_+_ : RE -> RE -> RE
_·_ : RE -> RE -> RE
_* : RE -> RE
And a type for a proof that a string matches an RE like this:
data REMatch : List Char -> RE -> Set where
EmptyMatch : REMatch [] ε
LitMatch : (c : Char) -> REMatch (c ∷ []) (Lit c)
...
ConcatMatch :
(s1 : List Char) (s2 : List Char ) (r1 : RE) (r2 : RE)
-> REMatch s1 r1
-> REMatch s2 r2
-> REMatch (s1 ++ s2) (r1 · r2)
I'm trying to write a correctness proof for my matcher, but I'm getting type errors on my pattern matches, before I even try to have a proof:
accCorrect :
(r : RE) (s : List Char) (s1 : List Char) (s2 : List Char) (k : (List Char -> Bool))
-> ( (s1 ++ s2) ≡ s)
-> (REMatch s1 r)
-> (k s2 ≡ true)
-> (acc r s k ≡ true )
accCorrect ε [] [] [] k _ EmptyMatch kproof = kproof
accCorrect (r1 · r2) s s1 s2 k splitProof (ConcatMatch s1' s1'' r1' r2' subMatch1 subMatch2 ) kproof = ?
However, this gives the following error:
r2' != r2 of type RE
when checking that the pattern
ConcatMatch s1' s1'' r1' r2' subMatch1 subMatch2 has type
REMatch s1 (r1 · r2)
However, if I replace the underscores r2'
with r2
, I get a "repeated variables" error.
There is no way to construct a match for (r1 · r2)
except the ConcatMatch
constructor.
My question:
How do I convince the type-checker that r2
and r2'
are equal, from within a pattern match? Any argument of type REMatch s1 (r1 · r2)
must be constructed with the ConcatMatch
constructor using arguments r1
and r2
, but I don't know how to prove that this is the case from within a pattern match.