1use super::fail::Fail;
2use super::modifier::{Cond, Mapped, Refined, SpecIso, SpecPartialIsoFn, SpecPred, TryMap};
3use super::sequence::{Preceded, SpecPair};
4use super::tag::Tag;
5use super::variant::Choice;
6use crate::properties::*;
7use crate::regular::end::End;
8use vstd::prelude::*;
9
10verus! {
11
12pub trait DisjointFrom<Other> where Self: SpecCombinator, Other: SpecCombinator {
14 spec fn disjoint_from(&self, other: &Other) -> bool;
16
17 proof fn parse_disjoint_on(&self, other: &Other, buf: Seq<u8>)
20 requires
21 self.disjoint_from(
22 other,
23 ),
24 ensures
27 self.spec_parse(buf) is Some ==> other.spec_parse(buf) is None,
28 ;
29}
30
31impl<Inner, T> DisjointFrom<Tag<Inner, T>> for Tag<Inner, T> where Inner: SpecCombinator<Type = T> {
33 open spec fn disjoint_from(&self, other: &Tag<Inner, T>) -> bool {
34 self.0.disjoint_from(&other.0)
35 }
36
37 proof fn parse_disjoint_on(&self, other: &Tag<Inner, T>, buf: Seq<u8>) {
38 }
39}
40
41impl<U1, U2, V1, V2> DisjointFrom<(U2, V2)> for (U1, V1) where
43 U1: DisjointFrom<U2>,
44 U1: SecureSpecCombinator,
45 U2: SecureSpecCombinator,
46 V1: SpecCombinator,
47 V2: SpecCombinator,
48 {
49 open spec fn disjoint_from(&self, other: &(U2, V2)) -> bool {
50 self.0.disjoint_from(&other.0)
51 }
52
53 proof fn parse_disjoint_on(&self, other: &(U2, V2), buf: Seq<u8>) {
54 self.0.parse_disjoint_on(&other.0, buf)
55 }
56}
57
58impl<U1, U2, V1, V2> DisjointFrom<Preceded<U2, V2>> for Preceded<U1, V1> where
60 U1: DisjointFrom<U2>,
61 U1: SecureSpecCombinator<Type = ()>,
62 U2: SecureSpecCombinator<Type = ()>,
63 V1: SpecCombinator,
64 V2: SpecCombinator,
65 {
66 open spec fn disjoint_from(&self, other: &Preceded<U2, V2>) -> bool {
67 self.0.disjoint_from(&other.0)
68 }
69
70 proof fn parse_disjoint_on(&self, other: &Preceded<U2, V2>, buf: Seq<u8>) {
71 self.0.parse_disjoint_on(&other.0, buf)
72 }
73}
74
75impl<U1, U2, V1, V2> DisjointFrom<SpecPair<U2, V2>> for SpecPair<U1, V1> where
76 U1: DisjointFrom<U2>,
77 U1: SecureSpecCombinator,
78 U2: SecureSpecCombinator,
79 V1: SpecCombinator,
80 V2: SpecCombinator,
81 {
82 open spec fn disjoint_from(&self, other: &SpecPair<U2, V2>) -> bool {
83 self.fst.disjoint_from(&other.fst)
84 }
85
86 proof fn parse_disjoint_on(&self, other: &SpecPair<U2, V2>, buf: Seq<u8>) {
87 self.fst.parse_disjoint_on(&other.fst, buf)
88 }
89}
90
91impl<S1, S2, S3> DisjointFrom<S3> for Choice<S1, S2> where
96 S1: SpecCombinator + DisjointFrom<S3>,
97 S2: SpecCombinator + DisjointFrom<S1> + DisjointFrom<S3>,
98 S3: SpecCombinator,
99 {
100 open spec fn disjoint_from(&self, other: &S3) -> bool {
101 self.0.disjoint_from(other) && self.1.disjoint_from(other)
102 }
103
104 proof fn parse_disjoint_on(&self, other: &S3, buf: Seq<u8>) {
105 self.0.parse_disjoint_on(other, buf);
106 self.1.parse_disjoint_on(other, buf);
107 }
108}
109
110impl<U1, U2, M1, M2> DisjointFrom<Mapped<U2, M2>> for Mapped<U1, M1> where
111 U1: DisjointFrom<U2>,
112 U2: SpecCombinator,
113 M1: SpecIso<Src = U1::Type>,
114 M2: SpecIso<Src = U2::Type>,
115 U1::Type: SpecFrom<M1::Dst>,
116 U2::Type: SpecFrom<M2::Dst>,
117 M1::Dst: SpecFrom<U1::Type>,
118 M2::Dst: SpecFrom<U2::Type>,
119 {
120 open spec fn disjoint_from(&self, other: &Mapped<U2, M2>) -> bool {
121 self.inner.disjoint_from(&other.inner)
122 }
123
124 proof fn parse_disjoint_on(&self, other: &Mapped<U2, M2>, buf: Seq<u8>) {
125 self.inner.parse_disjoint_on(&other.inner, buf)
126 }
127}
128
129impl<U, M1, M2> DisjointFrom<TryMap<U, M2>> for TryMap<U, M1> where
132 U: SpecCombinator,
133 M1: SpecPartialIsoFn<Src = U::Type>,
134 M2: SpecPartialIsoFn<Src = U::Type>,
135 U::Type: SpecTryFrom<M1::Dst>,
136 U::Type: SpecTryFrom<M2::Dst>,
137 M1::Dst: SpecTryFrom<U::Type>,
138 M2::Dst: SpecTryFrom<U::Type>,
139 {
140 open spec fn disjoint_from(&self, other: &TryMap<U, M2>) -> bool {
141 self.inner == other.inner && forall|t|
142 {
143 <M1 as SpecPartialIsoFn>::spec_apply(t) is Ok
144 ==> <M2 as SpecPartialIsoFn>::spec_apply(t) is Err
145 }
146 }
147
148 proof fn parse_disjoint_on(&self, other: &TryMap<U, M2>, buf: Seq<u8>) {
149 }
150}
151
152impl<Inner1, Inner2> DisjointFrom<Cond<Inner2>> for Cond<Inner1> where
154 Inner1: SpecCombinator,
155 Inner2: SpecCombinator,
156 {
157 open spec fn disjoint_from(&self, other: &Cond<Inner2>) -> bool {
158 self.cond ==> !other.cond
159 }
160
161 proof fn parse_disjoint_on(&self, other: &Cond<Inner2>, buf: Seq<u8>) {
162 }
163}
164
165impl<Inner, P1, P2> DisjointFrom<Refined<Inner, P2>> for Refined<Inner, P1> where
168 Inner: SpecCombinator,
169 P1: SpecPred<Inner::Type>,
170 P2: SpecPred<Inner::Type>,
171 {
172 open spec fn disjoint_from(&self, other: &Refined<Inner, P2>) -> bool {
173 self.inner == other.inner && forall|i|
174 { self.predicate.spec_apply(&i) ==> !other.predicate.spec_apply(&i) }
175 }
176
177 proof fn parse_disjoint_on(&self, other: &Refined<Inner, P2>, buf: Seq<u8>) {
178 }
179}
180
181impl<'a, 'b, T1, T2> DisjointFrom<&'a T1> for &'b T2 where
182 T1: SpecCombinator,
183 T2: SpecCombinator + DisjointFrom<T1>,
184 {
185 open spec fn disjoint_from(&self, other: &&T1) -> bool {
186 (*self).disjoint_from(*other)
187 }
188
189 proof fn parse_disjoint_on(&self, other: &&T1, buf: Seq<u8>) {
190 (*self).parse_disjoint_on(*other, buf)
191 }
192}
193
194impl<T> DisjointFrom<T> for Fail where T: SpecCombinator {
196 open spec fn disjoint_from(&self, c: &T) -> bool {
197 true
198 }
199
200 proof fn parse_disjoint_on(&self, c: &T, buf: Seq<u8>) {
201 }
202}
203
204impl<T> DisjointFrom<T> for End where T: SecureSpecCombinator {
205 open spec fn disjoint_from(&self, c: &T) -> bool {
206 c.requires() && c.is_productive()
207 }
208
209 proof fn parse_disjoint_on(&self, c: &T, buf: Seq<u8>) {
210 if let Some((n, v)) = self.spec_parse(buf) {
211 assert(n == 0);
212 c.lemma_parse_productive(buf);
213 c.lemma_parse_length(buf);
214 }
215 }
216}
217
218}