Доказательство того, что конкатенация языков ассоциативна в Agda

Я новичок в языке Agda, и я работаю над формальными языками, используя Agda.

У меня возникают проблемы с доказательством ассоциативности конкатенации языков. Доказательство будет выделено желтым цветом, поскольку Agda не смогла найти слова для "++ Assoc" в следующем коде:

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

Где "++ Assoc" - это доказательство ассоциативности объединения списков.

Язык и конкатенация определяются следующим образом:

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)

Поэтому я хотел бы спросить, может ли кто-нибудь объяснить, что я делаю не так в этой ситуации, и дать мне несколько подсказок о том, как решить эту проблему.

Изменить 1: я пробовал другой способ, используя подстановку вне конкатенации, но я застрял в этой ситуации:

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)

Изменить 2: я только что попробовал использовать следующий код и получил сообщение об ошибке.

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

Изменить 3: просто была еще одна попытка, разбив слово w на три части, как было предложено.

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)

Сообщение об ошибке:

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)

где List (Fin Σ) - определение слова Σ.


person Orio    schedule 23.04.2017    source источник


Ответы (1)


Проблема в том, что ++ не является инъективным (и даже если бы это было так, Agda не узнала бы об этом), поэтому при попытке решить x ++ (y ++ z) ?= _1 ++ (_2 ++ _3) не существует наиболее общего решения, которое Agda могла бы выбрать.

Например, слова _1 = [], _2 = x, _3 = y ++ z подойдут.

Изменить: на самом деле не имеет смысла вводить w после сопоставления шаблона на LangConc l1 (LangConc l2 l3) w: w был разбит на 3 части (те, которые соответствуют l1, l2 и l3). Намного интереснее представить эти части:

LangAssoc (conc {w1} x (conc {w2} {w3} y z)) =
  subst (LangConc (LangConc _ _) _) (++Assoc w1 w2 w3) (conc (conc x y) z)
person gallais    schedule 23.04.2017
comment
Большое спасибо за ответ. Думаю, теперь я могу понять эту часть. Могу я спросить, есть ли какой-нибудь простой способ решить такую ​​проблему? - person Orio; 23.04.2017
comment
Вы должны явно передать аргументы. - person gallais; 23.04.2017
comment
Я только что попытался передать аргументы, сделав видимым слово w, и получил второе редактирование. Я что-то сделал не так? - person Orio; 23.04.2017
comment
Спасибо, что снова помогли мне в этом. Кроме того, похоже, что я не совсем понял синтаксис некоторых функций, таких как subst. Я также столкнулся с новой проблемой, показанной в Edit 3. Не могли бы вы объяснить, что здесь происходит, и как с этим бороться? - person Orio; 24.04.2017
comment
Я не могу воспроизвести это сообщение об ошибке. Какую версию Agda вы используете? - person gallais; 24.04.2017
comment
Я использую версию 2.4.2.2 - person Orio; 25.04.2017