@@ -416,15 +416,27 @@ func dictMaxAssocLemma2(d1 dict[Key]Val, d2 dict[Key]Val, d3 dict[Key]Val) {
416416
417417ghost
418418requires domain(d1) === domain(d2) // requirement necessary, as some keys might point to an empty set
419- requires forall k Key, v io.Pkt :: keyInDict(d1, k, v) == keyInDict(d2, k, v)
419+ requires forall k Key, v io.Pkt :: { keyInDict(d1, k, v) }{ keyInDict(d2, k, v) } keyInDict(d1, k, v) == keyInDict(d2, k, v)
420420ensures d1 === d2
421421decreases
422422func dictExtensionality(d1 dict[Key]Val, d2 dict[Key]Val) {
423423 assert (d1 === d2) ==> (forall k Key, v io.Pkt :: keyInDict(d1, k, v) == keyInDict(d2, k, v))
424- assume false
425- // TODO
426- // assert forall k Key :: (k elem domain(d1) && forall v io.Pkt :: !keyInDict(d1, k, v)) ==> AsSet(d1[k]) == set[io.Pkt]{}
427- // assert forall k Key :: k elem domain(d1) && AsSet(d1[k]) == set[io.Pkt]{} ==> AsSet(d2[k]) == set[io.Pkt]{}
424+ assert forall k Key :: k elem domain(d1) ==> forall e io.Pkt :: e elem AsSet(d1[k]) == keyInDict(d1, k, e)
425+ assert forall k Key :: k elem domain(d1) ==> forall e io.Pkt :: e elem AsSet(d1[k]) ==> e elem AsSet(d2[k])
426+ assert forall k Key :: k elem domain(d2) ==> forall e io.Pkt :: e elem AsSet(d2[k]) ==> e elem AsSet(d1[k])
427+ lemmaSubSet()
428+ assert forall k Key :: k elem domain(d1) ==> AsSet(d1[k]) union AsSet(d2[k]) == AsSet(d2[k])
429+ assert forall k Key :: k elem domain(d2) ==> AsSet(d2[k]) union AsSet(d1[k]) == AsSet(d1[k])
430+ assert DictLessThan(d1, d2)
431+ assert DictLessThan(d2, d1)
432+ DictLessEq(d1, d2)
433+ }
434+
435+ ghost
436+ ensures forall s1 Val, s2 Val :: {s1 union s2} (forall e io.Pkt :: e elem s1 ==> e elem s2) ==> s1 union s2 == s2
437+ decreases
438+ func lemmaSubSet() {
439+ // proven
428440}
429441
430442ghost
0 commit comments