j'ai écrit la proposition suivante à Idris:Comment fonctionne exactement la réécriture dans Idris?
total
plusOneCommutes : (n : Nat) -> (m : Nat) -> (n + S m = S n + m)
plusOneCommutes Z k = Refl
plusOneCommutes (S k) j =
let inductiveHypothesis = plusOneCommutes k j in
rewrite inductiveHypothesis in Refl
En utilisant l'inspiration à partir du code source Prelude.Nat
, je comprends pourquoi il est logique d'utiliser l'appel récursif (dans le second cas) comme une hypothèse d'induction afin de prouver l'affaire. Cependant, en passant par les détails de la réécriture avec des trous, je ne sais pas vraiment ce qui se passe et pourquoi cela fonctionne.
Si je vous écris:
plusOneCommutes (S k) j = ?hole
Je reçois le texte suivant du compilateur:
- + HolyGrail.hole [P]
`-- k : Nat
j : Nat
------------------------------------------------------
HolyGrail.hole : S (plus k (S j)) = S (S (plus k j))
qui ne semble pas vraiment droit. Selon la signature de plusOneCommutes
ce trou devrait avoir le type (plus (S k) (S j)) = (plus (S (S k)) j)
.
Dans une étape ultérieure et l'introduction d'hypothèse de récurrence, si j'écrire:
plusOneCommutes (S k) j =
let inductiveHypothesis = plusOneCommutes k j in
?hole
puis type de hole
devient:
- + HolyGrail.hole [P]
`-- k : Nat
j : Nat
inductiveHypothesis : k + S j = S k + j
-------------------------------------------------------------------------
HolyGrail.hole : S (plus k (S j)) = S (S (plus k j))
puis en utilisant la règle de réécriture donnée par inductiveHypothesis
- + HolyGrail.hole [P]
`-- k : Nat
j : Nat
inductiveHypothesis : k + S j = S k + j
_rewrite_rule : k + S j = S k + j
-------------------------------------------------------------------------
HolyGrail.hole : (\replaced => S replaced = S (S (plus k j))) (S k + j)
qui conduit à S (plus (S k) j) = S (S (plus k j))
whi ch est le type attendu, et Idris peut compléter la preuve en remplaçant automatiquement ?hole
par Refl
. Ce qui m'intrigue alors est la différence inattendue de types entre ce que je déduis de la signature et ce que le compilateur déduit du trou. Si je présente volontairement une erreur:
Je reçois le message suivant:
- + Errors (1)
`-- HolyGrail.idr line 121 col 16:
When checking right hand side of plusOneCommutes with expected type
S k + S j = S (S k) + j
Type mismatch between
S (S (plus k j)) = S (S (plus k j)) (Type of Refl)
and
S (plus k (S j)) = S (S (plus k j)) (Expected type)
Specifically:
Type mismatch between
S (plus k j)
and
plus k (S j)
La partie Type mismatch...
est compatible avec les étapes ci-dessus, mais pas la partie When checking ...
qui donne le type que je me attends.
Merci, il me manquait la partie sur la définition de plus! Tout a un sens alors :) – insitu