Coq'ta iki argüman üzerinde bir işlevi tümevarımsal olarak nasıl tanımlayabilirim?


14

Coq'u aşağıda verilen özyinelemeli fonksiyonun sona erdiğine nasıl ikna edebilirim? İşlev iki endüktif argüman alır. Sezgisel olarak, her iki argüman da ayrıştırıldığı için özyineleme sona erer.

Özellikle, fonksiyon girdi olarak iki ağacı alır.

Inductive Tree :=
| Tip: Tree
| Bin: Tree -> Tree -> Tree.

Ağaçlarda, aşağıdaki indüksiyon stilini yapmayı seviyorum.

Inductive TreePair :=
| TipTip : TreePair
| TipBin : Tree -> Tree -> TreePair
| BinTip : Tree -> Tree -> TreePair
| BinBin : TreePair -> TreePair -> TreePair.

Fixpoint pair (l r: Tree): TreePair :=
  match l with
    | Tip =>
      match r with
        | Tip => TipTip
        | Bin rl rr => TipBin rl rr
      end
    | Bin ll lr =>
      match r with
        | Tip => BinTip ll lr
        | Bin rl rr => BinBin (pair l rl) (pair lr r)
      end
  end.

TreePair'in tanımı kabul edilir, ancak işlev çiftinin tanımı hata iletisini verir:

Error: Cannot guess decreasing argument of fix.

Bu yüzden Coq'u feshin nasıl ikna edeceğiyle ilgileniyorum.


1
Curry kullanmak yerine l ve r'yi bir ürün olarak bir araya getirmeyi denediniz mi? Bu yardımcı olur.
Per Vognsen

1
Bazı insanlar bu sorunun programlama ve bu web sitesinin kapsamı dışında olduğunu düşünmektedir. Kabul edip etmediğimden emin olmasam da, olası sorunu bilmek isteyebilirsiniz. Herkesin uygunluk hakkında söyleyeceği bir şey varsa, lütfen bağlantı verdiğim meta tartışmaya yaz.
Tsuyoshi Ito

3
Bu soru gerçekten operasyonun pairiyi tanımlanmasını sağlamak için veri yapıları üzerinde monoton olarak azalan sınırların belirlenmesi ile ilgilidir. Coq sadece araç.
Dave Clarke

Yanıtlar:


12

Coq'un düzeltme noktası tanımları, endüktif çağrıların yapısal olarak daha küçük bir argüman almasını gerektirir. Derinlemesine, bir düzeltme noktası yapısı tek bir argüman alır: iki argüman üzerinde özyinelemeli bir tanım için yerleşik bir kavram yoktur. Neyse ki, Coq'un yapısal olarak daha küçük tanımı , son derece güçlü olan yüksek dereceli türleri içerir.

İki argümanlı düzeltme noktası tanımınız basit bir kalıbı izler: ya ilk argüman küçülür ya da ilk argüman aynı kalır ve ikinci argüman küçülür. Oldukça yaygın olan bu model, basit bir düzeltme çözümü ile ele alınabilir.

Fixpoint pair l := fix pair1 (r : Tree) :=
  match l with
    | Tip => match r with
              | Tip => TipTip
              | Bin rl rr => TipBin rl rr
            end
    | Bin ll lr => match r with
                    | Tip => BinTip ll lr
                    | Bin rl rr => BinBin (pair1 rl) (pair lr r)
                   end
  end.

Daha karmaşık durumlar için veya zevkleriniz bu şekilde çalışırsa, özyinelemeyi matematik derslerinde öğretildiği şekle daha yakın bir şekilde kullanabilir , genellikle bir tamsayı ölçüsü kullanarak bir adım hesaplamasından ve ayrı bir sağlamlık argümanından saptama noktası oluşturabilirsiniz . Ayrıca tanımınızı, yerel dili kullanarak ayrı bir sonlandırma ile toplam olmayan bir dilde klasik bir programa benzetebilirsiniz .Program


Şimdi istediğimi biliyorum!
yhirai

fix pair1 rüst seviyenin ikinci koluna itersem match(ve elbette ilk dalı buna göre bir fonksiyon tipi döndürecek şekilde uyarlarsam) bir fark yaratacak mı?
gün

@plmday: İki yönlü çalışma. Uzantıların makul bir şekilde tanımlanması için geniş ölçüde eşdeğerdirler ve daha da önemlisi her ikisi de iyi yazılmıştır (genişletilmiş yeniden yazma, ilgili kovaryans (pozitiflik) özelliklerinden hiçbirini değiştirmez).
Gilles 'SO- kötü olmayı bırak'
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.