Come definire induttivamente una funzione su due argomenti in Coq?


14

Come posso convincere Coq che la funzione ricorsiva indicata di seguito termina? La funzione accetta due argomenti induttivi. Intuitivamente, la ricorsione termina perché uno dei due argomenti è decomposto.

In particolare, la funzione accetta due alberi come input.

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

Su Trees, mi piace fare il seguente stile di induzione.

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.

La definizione di TreePair è accettata, ma la definizione della coppia di funzioni genera il messaggio di errore:

Error: Cannot guess decreasing argument of fix.

Quindi sono interessato a come convincere Coq della risoluzione.


1
Hai provato a passare insieme er come prodotto anziché utilizzare il curry? Questo dovrebbe essere d'aiuto.
Per Vognsen,

1
Alcune persone pensano che questa domanda riguardi la programmazione e la portata di questo sito Web. Anche se non sono sicuro di essere d'accordo, potresti voler conoscere il potenziale problema. Se qualcuno ha qualcosa da dire sull'adeguatezza, si prega di scrivere sulla meta discussione a cui mi sono collegato.
Tsuyoshi Ito,

3
Questa domanda riguarda davvero la specifica dei limiti decrescenti monotonicamente sulle strutture di dati al fine di garantire che l'operazione pairsia ben definita. Coq è semplicemente il veicolo.
Dave Clarke,

Risposte:


12

Le definizioni di fixpoint di Coq richiedono che le chiamate induttive ricevano un argomento strutturalmente più piccolo. In fondo, un costrutto fixpoint prende un singolo argomento: non esiste un concetto integrato di definizione ricorsiva su due argomenti. Fortunatamente, la definizione di Coq di strutturalmente più piccola include tipi di ordine superiore, che è estremamente potente.

La definizione del fixpoint a due argomenti segue un modello semplice: o il primo argomento diventa più piccolo o il primo argomento rimane identico e il secondo argomento diventa più piccolo. Questo modello abbastanza comune può essere gestito da un semplice fix-in-fix.

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.

Per casi più complessi, o se i tuoi gusti corrono in quel modo, puoi usare la ricorsione più vicina al modo in cui viene insegnata nei corsi di matematica, costruendo il punto fisso da un calcolo di passi e un argomento di fondatezza separato , spesso usando una misura intera . Puoi anche rendere la tua definizione più simile a un programma classico in una lingua non totale con una terminazione separata usando il Programvolgare .


Ora so che è quello che ho chiesto!
yhirai,

farà qualche differenza se spingo fix pair1 rnel secondo ramo del livello superiore match(e naturalmente adatterò il primo ramo per restituire un tipo di funzione di conseguenza)?
giorno

@plmday: lavoro in entrambe le direzioni. Sono estensivamente equivalenti per una ragionevole definizione di estendibilità e, cosa più importante, sono entrambi ben tipizzati (la riscrittura delle estensioni non cambia nessuna delle proprietà di covarianza (positività) rilevanti).
Gilles 'SO- smetti di essere malvagio' il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.