2017-10-04 3 views
2

Ich versuche Parität zusammen mit dem Boden der Hälfte zu berechnen, über die natürlichen Zahlen:Warum zerstört dieser "mit" -Block die Gesamtheit dieser Funktion?

data IsEven : Nat -> Nat -> Type where 
    Times2 : (n : Nat) -> IsEven (n + n) n 

data IsOdd : Nat -> Nat -> Type where 
    Times2Plus1 : (n : Nat) -> IsOdd (S (n + n)) n 

parity : (n : Nat) -> Either (Exists (IsEven n)) (Exists (IsOdd n)) 

ich mit der offensichtlichen Umsetzung parity gehen versucht:

parity Z = Left $ Evidence _ $ Times2 0 
parity (S Z) = Right $ Evidence _ $ Times2Plus1 0 
parity (S (S n)) with (parity n) 
    parity (S (S (k + k))) | Left (Evidence _ (Times2 k)) = 
     Left $ rewrite plusSuccRightSucc k k in Evidence _ $ Times2 (S k) 
    parity (S (S (S ((k + k))))) | Right (Evidence _ (Times2Plus1 k)) = 
     Right $ rewrite plusSuccRightSucc k k in Evidence _ $ Times2Plus1 (S k) 

Diese typechecks und arbeitet als erwartet. Allerdings, wenn ich versuchen parity als total zu markieren, beginnt Idris klagen:

parity is possibly not total due to: with block in parity 

Der einzige with Block I in parity sehen, ist das mit dem rekursiven Aufruf von parity (S (S n)) zu parity n, aber klar ist, dass eine fundierte, seit n ist strukturell kleiner als S (S n).

Wie überzeuge ich Idris, dass parity insgesamt ist?

+1

I [Ausgabe # 4100] geöffnet (https://github.com/idris-lang/ Idris-dev/issues/4100) auf GitHub. –

Antwort

2

Es sieht aus wie ein Bug zu mir, weil die folgenden Lösung basierend auf case die Gesamtheit checker passiert:

total 
parity : (n : Nat) -> Either (Exists (IsEven n)) (Exists (IsOdd n)) 
parity Z = Left $ Evidence _ $ Times2 0 
parity (S Z) = Right $ Evidence _ $ Times2Plus1 0 
parity (S (S k)) = 
    case (parity k) of 
    Left (Evidence k (Times2 k)) => 
     Left $ rewrite plusSuccRightSucc k k in Evidence _ $ Times2 (S k) 
    Right (Evidence k (Times2Plus1 k)) => 
     Right $ rewrite plusSuccRightSucc k k in Evidence _ $ Times2Plus1 (S k) 
+0

Ich kann bestätigen, dass diese Problemumgehung für mein Problem in der ursprünglichen Frage funktioniert - aber in anderen Situationen kann ein 'with' nicht immer in ein' case' umgeschrieben werden, richtig? Ich denke an Fälle, in denen die Musterübereinstimmung die Typen anderer Argumente verfeinert. – Cactus

+0

Richtig! Hier ist eine verwandte Frage: https://stackoverflow.com/q/35610366/2747511. Wir haben Glück, dass wir Beweise in diesem Zusammenhang haben. –

+0

Hmm, also, bedeutet das, dass ich versuchen sollte, diese '' '' '' '' '' '' '' '' '' manuell auszuklappen und zu sehen, ob das funktioniert? – Cactus

Verwandte Themen