3

I am new to the language Agda, and I am working on formal languages using Agda.

I've got some problems when proving the concatenation of languages is associative. The proof will be yellow highlighted as Agda could not find the words for "++Assoc" in the following code:

LangAssoc : ∀{Σ}{l1 l2 l3 : Language Σ}{w : Word Σ} → (LangConc l1 (LangConc l2 l3)) w → (LangConc (LangConc l1 l2) l3) w
LangAssoc {l1 = l1} (conc x (conc y z)) = conc (conc (subst l1 (++Assoc _ _ _) x) y) z

Where the "++Assoc" is the proof of the associativity of the concatenation of the lists.

The language and concatenation is defined as following:

Language : ℕ → Set₁
Language a = Word a → Set

data LangConc {Σ} (l1 l2 : Language Σ) : Language Σ where
  conc : ∀{w1 w2} → l1 w1 → l2 w2 → (LangConc l1 l2) (w1 ++ w2)

So I would like to ask if anyone can explain on what am I doing wrong in this situation and give me some hint on how to solve the problem.

Edit 1: I've tried another way by using subst outside the concatenation, but I got stuck in this situation:

LangAssoc : ∀{Σ} {l1 l2 l3 : Language Σ} {w : Word Σ} → (LangConc l1 (LangConc l2 l3)) w → (LangConc (LangConc l1 l2) l3) w
LangAssoc {Σ} {l1 = l1} {l2 = l2} {l3 = l3} (conc x (conc y z)) = subst {!!} (++Assoc {Σ} _ _ _) (conc {Σ} (conc {Σ} x y) z)

Edit 2: I've just tried with the following code and results in a error message.

LangAssoc : ∀{Σ} {l1 l2 l3 : Language Σ} {w : Word Σ} → (LangConc l1 (LangConc l2 l3)) w → (LangConc (LangConc l1 l2) l3) w
LangAssoc {l1 = l1} {w = w} (conc x (conc y z)) =  ?

w1 ++ w2 != w of type List (Fin Σ)
when checking that the pattern conc x (conc y z) has type
LangConc l1 (LangConc l2 l3) w

Edit 3: Just had another try by breaking the word w into three pieces as suggested.

LangAssoc : ∀{Σ : ℕ}{l1 l2 l3 : Language Σ}{w1 w2 w3 : Word Σ} 
             → (LangConc l1 (LangConc l2 l3)) (w1 ++ w2 ++ w3)
             → (LangConc (LangConc l1 l2) l3) ((w1 ++ w2) ++ w3)
LangAssoc (conc {w1} x (conc {w2} {w3} y z))
   = subst (LangConc (LangConc _ _) _) (++Assoc w1 w2 w3) (conc (conc x y) z)

Error message:

w4 != w1 of type List (Fin Σ)
when checking that the pattern conc {w1} x (conc {w2} {w3} y z) has
type LangConc l1 (LangConc l2 l3) (w1 ++ w2 ++ w3)

where List (Fin Σ) is the definition of Word Σ.

Orio
  • 33
  • 5

1 Answers1

2

The problem is that ++ is not injective (and even if it were, Agda wouldn't know about it) so when trying to solve x ++ (y ++ z) ?= _1 ++ (_2 ++ _3), there is no most general solution Agda could pick.

For instance saying _1 = [], _2 = x, _3 = y ++ z would work.

Edit: It does not really makes sense to introduce w after having pattern matched on LangConc l1 (LangConc l2 l3) w: w has been broken up in 3 parts (the ones correponding to l1, l2 and l3). It is much more interesting to introduce these parts:

LangAssoc (conc {w1} x (conc {w2} {w3} y z)) =
  subst (LangConc (LangConc _ _) _) (++Assoc w1 w2 w3) (conc (conc x y) z)
gallais
  • 11,823
  • 2
  • 30
  • 63
  • Thank you very much for the answer. I think I can understand this part now. May I ask is there any easy way to solve the problem like this? – Orio Apr 23 '17 at 17:21
  • You have to explicitly pass in the arguments. – gallais Apr 23 '17 at 17:30
  • I have just tried to pass in the arguments by making the word w visible, and resulted as the second edit. Is there anything I did wrong? – Orio Apr 23 '17 at 18:34
  • Thanks for helping me again on this. Also, it seems like I have not quite understood the syntax of certain functions like "subst". I also met a new problem as shown in the Edit 3. Could you please explain what is going on here, and how to deal with it? – Orio Apr 24 '17 at 18:19
  • I can't reproduce this error message. Which version of Agda are you using? – gallais Apr 24 '17 at 19:20
  • I am using version 2.4.2.2 – Orio Apr 25 '17 at 15:40