Ich habe meinen Kopf für eine Weile gegen dieses Problem gestoßen: Ich habe Datensatztypen, mit abhängigen Feldern, und ich möchte Gleichheiten bei Datensatztransformationen beweisen. Ich habe versucht, den Kern meines Problems in ein kleines Beispiel zu zerlegen. Betrachten Sie den folgenden Satztyp Rec
, die Abhängigkeit zwischen den Feldern hat:Gleichheit auf abhängigen Datensatztypen
module Bar where
open import Data.Nat
open import Relation.Binary.PropositionalEquality as PE
open import Relation.Binary.HeterogeneousEquality as HE
record Rec : Set where
field val : ℕ
inc : {n : ℕ} -> ℕ
succ : inc {0} ≡ val
open Rec
Die succ
Eigenschaft Staaten eine Beziehung zwischen den beiden anderen Bereichen: dass inc {0}
kehrt val
. Die folgende Funktion definiert einen incR
Rec
Transformator, der den Wert und die Inkrementierer um einen festen Wert erhöht m
, die ihre Wechselwirkung bewahrt:
succPrf : {x : Rec} {m : ℕ} -> (inc x {0} + m) ≡ val x + m
succPrf {x} {m} rewrite (PE.cong (\x -> x + m) (succ x)) = refl
incR : Rec -> ℕ -> Rec
incR x m = record {
val = val x + m
; inc = λ{n} -> inc x {n} + m
; succ = succPrf {x} {m} }
succPrf
Hier gibt den Beweis, daß die inc
/val
Beziehung hält.
Nun möchte ich folgendes beweisen:
incR0 : forall {x : Rec} -> incR x 0 ≡ x
incR0 {x} = {!!}
Das macht ziemlich schwierig, aber sein, weil der Abhängigkeit innerhalb der Datensätze.
versuchte ich es in einzelne Gleichheiten auf den Feldern zu brechen, mit dem Ziel, eine Kongruenz mit ihm zusammen zu setzen: und es scheint, kann ich ziemlich weit kommen:
postulate
ext : {A : Set} {B : Set}
{f g : {a : A} -> B} ->
(forall {n : A} -> f {n} ≡ g {n})
-> (λ {n : A} -> f {n}) ≡ (λ {n : A} -> g {n})
-- Trivial, but for tersity just postulated
runit : {n : ℕ} -> n + 0 ≡ n
incRVal : forall {x : Rec} -> val (incR x 0) ≡ val x
incRVal {x} rewrite runit {val x} = refl
incRinc : forall {x : Rec} -> (λ{n : ℕ} -> inc (incR x 0) {n}) ≡ (λ{n : ℕ} -> inc x {n})
incRinc {x} rewrite ext (λ{n : ℕ} -> runit {inc x {n}}) = refl
Und auf der succ
Feld wir müssen zu heterogener Gleichheit greifen
succIncR : {x : Rec} -> (inc (incR x 0) {0} ≡ val (incR x 0) + 0)
≡ (inc x {0} ≡ val x)
succIncR {x} rewrite runit {inc x {0}} | runit {val x} | incRVal {x}
= refl
incRsucc : forall {x : Rec} -> succ (incR x 0) ≅ succ x
incRsucc {x} rewrite succIncR {x} | succ x | runit {val x}
= HE.reflexive refl
Aber ich bemühe mich, diese zusammen angemessen zu kombinieren. Ich brauche wirklich eine Art von Kongruenz für Pi-Typen, so dass ich incRinc
und incRsucc
zusammen auf einmal verbinden kann, aber ich habe es versäumt, dies zu bauen. Ich bin an dem Punkt, wo ich den Wald für die Bäume nicht sehen kann, obwohl ich sehen würde, was SO dachte. Fehle mir hier eine leichte Technik?