2017-06-19 6 views
1

J'essaie d'utiliser une fonction de style point de repère dans le contexte d'une instance de classe de type, mais cela ne semble pas fonctionner. Y a-t-il quelque chose de plus que je dois faire pour que cela fonctionne? Pour l'instant, j'ai utilisé un hack pour déplacer la fonction en dehors de la classe de type et la déclarer explicitement Fixpoint. Cela semble horrible, cependant.Fonctions Fixpoint dans les instances de classe de type

Voici l'exemple court:

Inductive cexp : Type := 
| CAnd : cexp -> cexp -> cexp 
| COr : cexp -> cexp -> cexp 
| CProp : bool -> cexp. 

Class Propable (A : Type) := { compile : A -> Prop }. 

Instance: Propable cexp := 
    { compile c := 
     match c with 
     | CAnd x y => (compile x) /\ (compile y) 
     | COr x y => (compile x) \/ (compile y) 
     | CProp _ => False 
     end 
    }. 

Cela échoue avec:

Error: Unable to satisfy the following constraints: 
In environment: 
c, x, y : cexp 

?Propable : "Propable cexp" 

Que doit-on faire pour faire ce travail?

Répondre

2

Vous pouvez utiliser fix pour le faire:

Instance: Propable cexp := 
    { compile := fix compile c := 
     match c with 
     | CAnd x y => (compile x) /\ (compile y) 
     | COr x y => (compile x) \/ (compile y) 
     | CProp _ => False 
     end 
    }. 

Permettez-moi d'illustrer comment on peut venir avec elle. Prenons le morceau de code suivant:

Fixpoint silly n := 
    match n with 
    | 0 => 0 
    | S n => silly n 
    end. 

Fixpoint ici est une commande vernaculaire qui rend la définition un peu plus facile sur les yeux, mais il cache ce qui se passe ici. Il se trouve que ce Coq ne fait quelque chose comme ceci:

Definition silly' := 
    fix self n := 
    match n with 
    | 0 => 0 
    | S n => self n 
    end. 

Vous pouvez le vérifier en utilisant Print silly. après la définition.

+0

Cela fonctionne, mais je remarque que lorsque j'applique la tactique «simple», j'obtiens une énorme définition de point fixe indisciplinée au lieu d'une simple formule avec des identifiants. Existe-t-il un moyen de dire à Coq de cuire des identifiants de meilleure qualité plutôt que d'imprimer toute la fonction en ligne? – jsinglet

+0

Ceci est un problème fréquent. Ces questions peuvent fournir quelques informations: [1] (https://stackoverflow.com/q/39355817/2747511), [2] (https://stackoverflow.com/q/28432187/2747511), [3] (https : //stackoverflow.com/q/41404337/2747511). "fold" peut aider (mais rarement), peut-être vous avez besoin d'un meilleur contrôle sur où la réduction se produit. Si cela ne vous aide pas, envoyez-moi un lien vers le code actuel - j'essaierai d'y jeter un coup d'œil. –