Skip to content

Commit c2a4d53

Browse files
committed
proof(solo-core/idris): hvSubst variable substitution (slice B, toward #108)
The variable case of the QTT substitution lemma (mirrors Coq hv_subst), green under %default total. Prefix-I induction; matches n=Z/S n0 at runtime and bridges varInv's erased witness via predEq'. Two leaves: - substituted variable itself -> returns u, usage scaled by q (uaddZeroL) - any other variable -> unchanged, Zero-scaled (uaddUscaleZeroR), re-weakened by htShift0 + substVarSucc Refs #108
1 parent 174b31c commit c2a4d53

1 file changed

Lines changed: 65 additions & 0 deletions

File tree

proofs/verification/idris/solo-core/Substitution.idr

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -678,3 +678,68 @@ substVarSucc k u n with (compare n k) proof eq
678678
substVarSucc Z u Z | GT = void (eqNotGT eq)
679679
substVarSucc (S j) u Z | GT = void (ltNotGT eq)
680680
substVarSucc k u (S n0) | GT = rewrite minusZeroRight n0 in sym (shiftVarLemma 0 n0)
681+
682+
------------------------------------------------------------
683+
-- 4c (cont). Variable substitution
684+
------------------------------------------------------------
685+
686+
||| Substituting `u` for the boundary variable in a `HasVar`: either the
687+
||| substituted variable itself (returns `u`, usage scaled by `q`), or a
688+
||| different variable (unchanged, `Zero`-scaled). The general prefix-`I` form
689+
||| (mirrors Coq `hv_subst`); `htSubst`'s `Var` case is this lemma.
690+
public export
691+
hvSubst : (i, g : Tctx) -> (a : Ty) -> (dg : Uvec) -> (q : Q) -> (di : Uvec)
692+
-> (n : Nat) -> (b : Ty) -> (du : Uvec) -> (u : Tm)
693+
-> ulen di = tlen i
694+
-> HasVar (tappend (TSnoc g a) i) (uappend (USnoc dg q) di) n b
695+
-> Has g du u a
696+
-> (dgr : Uvec ** (uadd dg (uscale q du) = Just dgr,
697+
Has (tappend g i) (uappend dgr di)
698+
(substAt (tlen i) (shiftn (tlen i) u) (Var n)) b))
699+
hvSubst TEmpty g a dg q (USnoc _ _) n b du u hlen hv hu = void (sNotZ' hlen)
700+
hvSubst TEmpty g a dg q UEmpty Z b du u hlen hv hu =
701+
case varInv hv of
702+
VIT hdq hn hv' => void (zNotS' hn)
703+
VIH hdq hn hb =>
704+
let (hdg, hq) = usnocInj hdq
705+
in (du ** (rewrite hdg in rewrite hq in rewrite uscaleOne du in
706+
uaddZeroL g du (shapeType g u hu),
707+
rewrite hb in hu))
708+
hvSubst TEmpty g a dg q UEmpty (S n0) b du u hlen hv hu =
709+
case varInv hv of
710+
VIH hdq hn hb => void (sNotZ' hn)
711+
VIT hdq hn hv' =>
712+
let (hdg, hq) = usnocInj hdq
713+
hv'' : HasVar g dg n0 b
714+
hv'' = rewrite hdg in rewrite predEq' hn in hv'
715+
in (dg ** (rewrite hq in
716+
uaddUscaleZeroR dg du (trans (shapeVar g hv'') (sym (shapeType g u hu))),
717+
rewrite minusZeroRight n0 in THVar hv''))
718+
hvSubst (TSnoc i' c) g a dg q UEmpty n b du u hlen hv hu = void (zNotS' hlen)
719+
hvSubst (TSnoc i' c) g a dg q (USnoc di' qd) Z b du u hlen hv hu =
720+
case varInv hv of
721+
VIT hdq hn hv' => void (zNotS' hn)
722+
VIH hdq hn hb =>
723+
let (hdgdi, hqd) = usnocInj hdq
724+
(hdg, hdi) = uappendInj di' (uzero i') (USnoc dg q) (USnoc (uzero g) Zero)
725+
(trans (predEq' hlen) (sym (uzeroLen i')))
726+
(trans hdgdi (uzeroTappend (TSnoc g a) i'))
727+
(hdgg, hqq) = usnocInj hdg
728+
in (uzero g **
729+
(rewrite hdgg in rewrite hqq in
730+
uaddUscaleZeroR (uzero g) du (trans (uzeroLen g) (sym (shapeType g u hu))),
731+
rewrite hb in rewrite hqd in rewrite hdi in
732+
rewrite sym (uzeroTappend g i') in THVar HVHere))
733+
hvSubst (TSnoc i' c) g a dg q (USnoc di' qd) (S n0) b du u hlen hv hu =
734+
case varInv hv of
735+
VIH hdq hn hb => void (sNotZ' hn)
736+
VIT hdq hn hv' =>
737+
let (hd0, hqd) = usnocInj hdq
738+
(dgr ** (hadd, hht)) = hvSubst i' g a dg q di' n0 b du u (predEq' hlen)
739+
(rewrite hd0 in rewrite predEq' hn in hv') hu
740+
in (dgr **
741+
(hadd,
742+
rewrite hqd in
743+
rewrite substVarSucc (tlen i') u n0 in
744+
htShift0 (tappend g i') c (uappend dgr di')
745+
(substAt (tlen i') (shiftn (tlen i') u) (Var n0)) hht))

0 commit comments

Comments
 (0)