Coq - disj_conj_intro_patterns для индуктивных предложений

Учитывая произвольное определение индуктивного предложения в Coq, существует ли общая формула для вывода разумного disj_conj_intro_pattern для использования при вызове тактики индукции для индуктивного предложения?

В общем, полный intro_pattern для любого из конструкторов индуктивного определения может потребовать (имена для) более одной гипотезы и более одной индуктивной гипотезы, и в этом случае порядок имен, представленный в шаблоне, может включать все параметры, за которыми следует одной гипотезой и соответствующей индуктивной гипотезой, за которыми следуют одна или несколько дополнительных пар, состоящих из гипотезы и индуктивной гипотезы. Например, Software Foundations включает в себя следующее:

Inductive exp_match {T} : list T -> reg_exp T -> Prop :=
| MEmpty : exp_match [] EmptyStr
| MChar : forall x, exp_match [x] (Char x)
| MApp : forall s1 re1 s2 re2,
           exp_match s1 re1 ->
           exp_match s2 re2 ->
           exp_match (s1 ++ s2) (App re1 re2)
| MUnionL : forall s1 re1 re2,
              exp_match s1 re1 ->
              exp_match s1 (Union re1 re2)
| MUnionR : forall re1 s2 re2,
              exp_match s2 re2 ->
              exp_match s2 (Union re1 re2)
| MStar0 : forall re, exp_match [] (Star re)
| MStarApp : forall s1 s2 re,
               exp_match s1 re ->
               exp_match s2 (Star re) ->
               exp_match (s1 ++ s2) (Star re).

Notation "s =~ re" := (exp_match s re) (at level 80).

Theorem in_re_match : forall T (s : list T) (re : reg_exp T) (x : T),
  s =~ re ->
  In x s ->
  In x (re_chars re).
Proof.
  intros T s re x Hmatch Hin.
  induction Hmatch
    as [
        |x'
        |s1 re1 s2 re2 Hmatch1 IH1 Hmatch2 IH2
        |s1 re1 re2 Hmatch IH|re1 s2 re2 Hmatch IH
        |re|s1 s2 re Hmatch1 IH1 Hmatch2 IH2].

В этом примере каждая из intro_patterns для MApp и MStarApp имеет две пары гипотезы и индуктивной гипотезы - предположительно потому, что каждый из этих двух конструкторов содержит выражение формы

x -> y -> z

Об этом в текущем Справочном руководстве говорится только

термин индукции как disj_conj_intro_pattern

Это ведет себя как термин индукции, но использует имена в disj_conj_intro_pattern для именования переменных, представленных в контексте. Disj_conj_intro_pattern обычно должен иметь форму [p11… p1n1 | … | pm1… pmnm], где m - количество конструкторов типа терма. Каждая переменная, введенная индукцией в контексте i-й цели, получает свое имя из списка pi1… pini по порядку. Если имен недостаточно, индукция изобретает имена для оставшихся переменных, которые нужно ввести. В более общем смысле pij может быть любым дизъюнктивным / конъюнктивным паттерном введения (см. Раздел 8.3.2). Например, для индуктивного типа с одним конструктором вместо [p1… pn] можно использовать обозначение шаблона (p1,…, pn).

Кажется, это не указывает, как определить правильную форму для полного disj_conj_intro_pattern для данного индуктивного определения.

Мое вышеупомянутое эмпирическое наблюдение, что 1) сначала идут формальные параметры каждого конструктора, а затем гипотезы конструктора в паре с соответствующими индуктивными гипотезами; и 2) количество пар гипотезы и индуктивной гипотезы следует из количества гипотез в конструкторе, суммы материи? Или это еще не все?

Есть ли другая соответствующая документация по этому поводу, помимо главы «Тактика» Справочного руководства и самого общего обсуждения шаблонов в грамматике Gallina в главе 1?


person Christopher Brinkley    schedule 31.08.2016    source источник
comment
Я также сделал эмпирическое наблюдение, что шаблоны, необходимые для induction, такие же, как шаблоны, необходимые для destruct, за исключением того, что гипотеза индукции должна быть добавлена ​​после каждого аргумента конструктора, тип которого совпадает с индуктивным типом, которому он принадлежит (мы можно сказать, что это рекурсивный вызов). В вашем примере все гипотезы конструкторов exp_match относятся к типу exp_match, но у вас могут быть другие гипотезы, которые не будут генерировать гипотезы индукции.   -  person eponier    schedule 01.09.2016


Ответы (1)


Если я правильно понимаю ваш вопрос, то ответ - «да». Вы можете вывести образец вступления для индукции.

Coq автоматически генерирует принцип индукции для любого индуктивного определения и называет его, добавляя _ind в качестве суффикса, поэтому принцип индукции для exp_match становится exp_match_ind. Если вы исследуете тип exp_match_ind с помощью команды Check, вы сможете создать требуемый шаблон вступления.

Check exp_match_ind.

(* output:
exp_match_ind
     : forall (T : Type) (P : list T -> reg_exp T -> Prop),
       P [] EmptyStr ->
       (forall x : T, P [x] (Char x)) ->
       (forall (s1 : list T) (re1 : reg_exp T) 
          (s2 : list T) (re2 : reg_exp T),
        s1 =~ re1 ->
        P s1 re1 ->
        s2 =~ re2 -> P s2 re2 -> P (s1 ++ s2) (App re1 re2)) ->
       (forall (s1 : list T) (re1 re2 : reg_exp T),
        s1 =~ re1 -> P s1 re1 -> P s1 (Union re1 re2)) ->
       (forall (re1 : reg_exp T) (s2 : list T) (re2 : reg_exp T),
        s2 =~ re2 -> P s2 re2 -> P s2 (Union re1 re2)) ->
       (forall re : reg_exp T, P [] (Star re)) ->
       (forall (s1 s2 : list T) (re : reg_exp T),
        s1 =~ re ->
        P s1 re ->
        s2 =~ Star re -> P s2 (Star re) -> P (s1 ++ s2) (Star re)) ->
       forall (l : list T) (r : reg_exp T), l =~ r ->
       P l r
*)

Этот тип говорит, что (если вы пропустите начальный forall "заголовок"), что вам нужно доказать набор подцелей, чтобы доказать цель P l r. Каждые -> на верхнем уровне разделяют подцели:

1) MEmpty корпус:

P [] EmptyStr

Нет никаких гипотез, поэтому мы начинаем с induction Hmatch as [ | - обратите внимание, что слева от | ничего нет.

2) MChar дело:

(forall x : T, P [x] (Char x))

Шаблон вступления в этом случае прост: для некоторых x' нам нужно P [x'] (Char x') доказывать. На этом этапе наш шаблон выглядит следующим образом: _18 _...

3) MApp дело:

(forall (s1 : list T) (re1 : reg_exp T) 
        (s2 : list T) (re2 : reg_exp T),  (* s1 re1 s2 re2 *)
        s1 =~ re1 ->                      (* Hmatch1 *)
        P s1 re1 ->                       (* IH1 *)
        s2 =~ re2 ->                      (* Hmatch2 *)
        P s2 re2 ->                       (* IH2 *)
        P (s1 ++ s2) (App re1 re2))       (* the current subgoal *)

В комментариях выше я пометил переменные и гипотезы в соответствии с теми, которые используются в теореме in_re_match. На этом этапе наш шаблон выглядит следующим образом: _22 _...

Остальные подцели могут быть выполнены аналогично, в результате получится шаблон, использованный в теореме.

person Anton Trunov    schedule 31.08.2016