I'm trying to define a simple predicate to determine if a formula is a subformula of a given formal over a simple inductively defined syntax. I'm running into a few, presumably simple, problems.
(i) I'd rather use a parameterized module with a given type A. How can one import the information that A is a set, in the sense that A has decideable equality? If this can't be done, what are some workarounds? This is why I have Nat instead.
(ii) Is the t1 ≡ (t2 // t3) (and similairly defined) predicates isSubFormula the proper way to deal with equal subformulas? If not, how else does one easily do this? I've also considered writing a predicate for equalFmla and then making a global subformula predicate with isSubFormula ⊎ equalFmla but am not sure if this is so clean.
(iii) Why do the last three lines highlight blue when I pattern match internal to the first one? How can I fix this
(iv) Why won't the {!Data.Nat._≟_ n1 n2 !} refine below?
module categorial1 (A : Set) where
open import Data.Nat using (ℕ)
open import Data.Empty
open import Data.Sum
open import Relation.Binary.PropositionalEquality
-- type symbols
data tSymb : Set where
-- base : A → tSymb
base : ℕ → tSymb
~ : tSymb → tSymb
_\\_ : tSymb → tSymb → tSymb
_//_ : tSymb → tSymb → tSymb
-- A needs a decideable notion of equality
isSubFormula : tSymb → tSymb → Set
-- isSubFormula y (base x) = {!!}
isSubFormula (base n1) (base n2) = {!Data.Nat._≟_ n1 n2 !}
isSubFormula (~ t1) (base x) = ⊥
isSubFormula (t1 \\ t2) (base x) = ⊥
isSubFormula (t1 // t2) (base x) = ⊥
isSubFormula t1 (~ t2) = t1 ≡ (~ t2) ⊎ isSubFormula t1 t2
isSubFormula t1 (t2 \\ t3) = t1 ≡ (t2 \\ t3) ⊎ isSubFormula t1 t2 ⊎ isSubFormula t1 t3
isSubFormula t1 (t2 // t3) = t1 ≡ (t2 // t3) ⊎ isSubFormula t1 t2 ⊎ isSubFormula t1 t3
That's quite a lot of different questions; Stack Overflow works better if you post each question separately.
Nevertheless, here are some answers:
You can parametrize your module by the decision procedure, i.e. something like this:
Note that we import
Relation.Binary(forDecidable) andR.B.PropositionalEquality(for_≡_) before the module header, since the parameter types of our module depend on these definitions.This is Agda warning you that those clauses won't hold definitionally, because they depend on the previous clauses not matching on
t1.Because
isSubFormulareturns aSet, butn1 ≟ n2returns aDec _≡_.I think there is confusion in your code about whether
isSubFormulais supposed to be a proposition or a decision procedure. If it returns aSet, it means it is a proposition. You can write that without decidable equality since there is nothing to decide --isSubFormula-ness of twobasevalues means they are equal:If you want a decision procedure, you could do it "boolean-blindly" by instead writing
isSubFormula : tSymb → tSymb → Bool, or by keepingisSubFormulaas a proposition and writingdecSubFormula : Decidable isSubFormula.Note also that you only need decidable equality on
Aif you are trying to decideisSubFormula, so you can do