Çok biçimlilik ve tümevarımsal veri türleri


10

Merak ediyorum. OCaml'de bu veri türü üzerinde çalışıyorum :

type 'a exptree =
  | Epsilon
  | Delta of 'a exptree * 'a exptree
  | Omicron of 'a
  | Iota of 'a exptree exptree

Hangi açıkça yazılmış özyinelemeli işlevler (oldukça yakın zamanda eklenen bir özellik) kullanılarak manipüle edilebilir. Misal:

let rec map : 'a 'b. ('a -> 'b) -> 'a exptree -> 'b exptree =
  fun f ->
    begin function
    | Epsilon -> Epsilon
    | Delta (t1, t2) -> Delta (map f t1, map f t2)
    | Omicron t -> Omicron (f t)
    | Iota tt -> Iota (map (map f) tt)
    end

Ama bunu Coq ile tanımlayamadım :

Inductive exptree a :=
  | epsilon : exptree a
  | delta : exptree a -> exptree a -> exptree a
  | omicron : a -> exptree a
  | iota : exptree (exptree a) -> exptree a
.

Coq sızlanıyor. Son kurucudan hoşlanmıyor ve tamamen anlamadığım veya katılmadığım bir şey söylüyor:

Error: Non strictly positive occurrence of "exptree" in "exptree (exptree a) -> exptree a".

Anlayabildiğim şey, tanımları içinde bir olumsuzlama kullanan endüktif türlerin type 'a term = Constructor ('a term -> …)reddedilmiş olmasıdır, çünkü onlar (türsüz) λ terimleri gibi çirkin iyi kurulmuş olmayan hayvanlara yol açacaktır. Bununla birlikte, bu belirli exptreeveri türü yeterince zararsız görünmektedir: OCaml tanımına bakıldığında, argümanı 'aasla olumsuz pozisyonlarda kullanılmaz.

Coq burada çok dikkatli görünüyor . Peki bu özel endüktif veri tipinde gerçekten bir sorun var mı? Yoksa Coq burada biraz daha izinli olabilir mi?

Ayrıca, diğer kanıt asistanları, böyle bir endüktif tanımla (doğal bir şekilde) başa çıkabilirler mi?

Yanıtlar:


9

Bu, Coq posta listesinde birkaç kez ortaya çıktı, ancak hiçbir zaman kesin bir cevap görmedim. Coq olabildiğince genel değil; (Coquand, 1990) ve (Giménez, 1998) (ve doktora tezi) 'ndeki kurallar daha geneldir ve katı bir pozitiflik gerektirmez. Ancak dışarıya çıktığınızda yeterli pozitiflik yeterli değildir Set; bu örnek birkaç tartışmada ortaya çıktı :

Inductive Big : Type := B : ((B -> Prop) -> Prop) -> Big.

Sizinki gibi sade veri yapılarında, endüktif tip, uygulamayı daha karmaşık hale getirmekten başka sorunlara neden olmaz.

Bir polinomun sabit noktası olarak tanımlanan bunun gibi türleri tanımlamanın genel bir yolu vardır:

F=ϵ+δ(F×F)+οid+FF

işlevini tanımlamak yerine , türlerinin ailesini tanımlayın . Bu, kendi kendine kompozisyon sayısını kodlayan türe bir tamsayı parametresi eklemek anlamına gelir ( , , , vb) ve açmak için bir ek enjeksiyon yapıcı içine .exptree:aexptree(a)exptree,exptreeexptree,exptreeexptreeexptree,exptree0(a)=aexptree1(a)=exptree(a)a e x p t r e e 0 ( a ) = aexptree2(a)=exptree(exptree(a))aexptree0(a)=a

Inductive et : nat -> Type -> Type :=
  | alpha : forall a, a -> et 0 a                      (*injection*)
  | omicron : forall n a, et n a -> et (S n) a         (**)
  | epsilon : forall (S n) a, et (S n) a
  | delta : forall n a, et (S n) a -> et (S n) a -> et (S n) a
  | iota : forall n a, et (S (S n)) a -> et (S n) a
.

Değerleri tanımlamaya ve bunlar üzerinde çalışmaya devam edebilirsiniz. Coq genellikle üssü çıkartabilecektir. Set Implicit Argumentsbu tanımları daha güzel yapar.

Definition exptree := et 1.
Definition et1 : exptree nat :=
  delta _ _ (omicron _ _ (alpha _ 42)) (epsilon _ _).
Definition et2 : exptree nat := iota _ _ (omicron _ _ et1).

Böylece, 1 ile argüman azaltmak tercih edebilir exptreeolduğunu et 0. Bu çok kaldırır S nbazı deliller daha kolay yapabilir tanımında, ancak bölme bir aldığı her yapıcıda tekrar halinde gelen ilk durum gerektirdiğinde (yerine tek bir enjeksiyon kurucu ilave bir bağımsız değişken ). Bu örnekte, bölünecek tek bir kurucu var, bu yüzden bu iyi bir seçim olmalı.aaa

Inductive et : nat -> Type -> Type :=
  | omicron_0 : forall a, a -> et 0 a
  | omicron_S : forall n a, et n a -> et (S n) a
  | epsilon : forall n a, et n a
  | delta : forall n a, et n a -> et n a -> et n a
  | iota : forall n a, et (S n) a -> et n a
.
Definition exptree := et 0.
Definition et1 : exptree nat :=
  delta _ _ (omicron_0 _ 42) (epsilon _ _).
Definition et2 : exptree nat :=
  (iota _ _ (omicron_S _ _ et1)).

Bence bu, Ralph Mattes tarafından daha genel bir biçimde önerilen aynı prensip .

Referanslar

Thierry Coquand ve Christine Paulin. Endüktif olarak tanımlanmış tipler . In COLOG'88 Kitabı , LNCS 417, 1990 [ Springer ] [ Google ]

Eduardo Giménez. Tip Teorisinde Yapısal Özyinelemeli Tanımlar . In ICALP'98: Tutanakları 25 Özdevinir, Dil ve Programlama Uluslararası Kolokyumu arasında. Springer-Verlag, 1998. [ PDF ]


8

Ralph Matthes, "Yinelemeli Güçler için Bir Veri Yapısı" ( kod , kağıt ) içinde Coq'da bunun gibi türlerin nasıl simüle edileceğini açıklar .


6

Coq'un yaptığı ilk şeylerden biri, az önce tanımladığınız endüktif tip ile ilişkili indüksiyon prensibini inşa etmek ve temeldeki indüksiyon prensibini anlamak iyi bir egzersizdir.

Örneğin O : nat | S : nat -> natindüksiyon prensibini üretecektir P O -> (∀ n, P n -> P (S n)) -> ∀ n, P n.

Tümevarım ilkesi neye karşılık gelir iota? Hiçbir yüklem olduğu görülmektedir Pbahsetmek mümkün olacaktır P tve P (iota t)bu konuda konuşmak gerekir, çünkü exptree a, exptree (exptree a), exptree (exptree (exptree a))...

Ayrıca Omicronaynı şeyi yapar ama türü her seferinde daha küçüktür. Hem daha küçük bir türe hem de daha büyük bir türe referans vermenin işleri dağınık hale getireceğini hissetmelisiniz. ( OmicronDoğru yol dedi )

Bu, tanımın neden kabul edilmemesi gerektiğini söyleyen kesin ölçütler değil, bu benim için neden yanlış hissettirdiğini açıklıyor.

exptreeifadeler için bir dilbilgisi oluşturuyormuşsunuz gibi görünüyor, genellikle bu özyinelemeli olmayan bir şey . Bununla ilgili yardım ister misiniz?

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.