1use super::bytes::Bytes;
2use super::bytes_n::BytesN;
3use super::choice::OrdChoice;
4use super::cond::Cond;
5use super::depend::SpecDepend;
6use super::fail::Fail;
7use super::map::{Mapped, SpecIso};
8use super::preceded::Preceded;
9use super::refined::Refined;
10use super::tag::{Tag, TagPred};
11use super::uints::{U16, U32, U64, U8};
12use crate::properties::*;
13use vstd::prelude::*;
14
15verus! {
16
17pub trait DisjointFrom<Other> where Self: SpecCombinator, Other: SpecCombinator {
19 spec fn disjoint_from(&self, other: &Other) -> bool;
21
22 proof fn parse_disjoint_on(&self, other: &Other, buf: Seq<u8>)
25 requires
26 self.disjoint_from(
27 other,
28 ),
29 ensures
32 self.spec_parse(buf).is_ok() ==> other.spec_parse(buf).is_err(),
33 ;
34}
35
36macro_rules! impl_disjoint_for_int_tag {
37 ($combinator:ty) => {
38 ::builtin_macros::verus! {
39 impl DisjointFrom<$combinator> for $combinator {
40 open spec fn disjoint_from(&self, other: &$combinator) -> bool {
42 self.0.predicate.0 != other.0.predicate.0
43 }
44
45 proof fn parse_disjoint_on(&self, other: &$combinator, buf: Seq<u8>) {
46 }
47 }
48 }
49 };
50}
51
52macro_rules! impl_disjoint_for_refined_int {
53 ($combinator:ty) => {
54 ::builtin_macros::verus! {
55 impl DisjointFrom<$combinator> for $combinator {
56 open spec fn disjoint_from(&self, other: &$combinator) -> bool {
58 self.predicate.0 != other.predicate.0
59 }
60
61 proof fn parse_disjoint_on(&self, other: &$combinator, buf: Seq<u8>) {
62 }
63 }
64 }
65 };
66}
67
68impl_disjoint_for_int_tag!(Tag<U8, u8>);
69
70impl_disjoint_for_int_tag!(Tag<U16, u16>);
71
72impl_disjoint_for_int_tag!(Tag<U32, u32>);
73
74impl_disjoint_for_int_tag!(Tag<U64, u64>);
75
76impl_disjoint_for_refined_int!(Refined<U8, TagPred<u8>>);
77
78impl_disjoint_for_refined_int!(Refined<U16, TagPred<u16>>);
79
80impl_disjoint_for_refined_int!(Refined<U32, TagPred<u32>>);
81
82impl_disjoint_for_refined_int!(Refined<U64, TagPred<u64>>);
83
84impl<const N: usize> DisjointFrom<Tag<BytesN<N>, Seq<u8>>> for Tag<BytesN<N>, Seq<u8>> {
86 open spec fn disjoint_from(&self, other: &Tag<BytesN<N>, Seq<u8>>) -> bool {
87 self.0.predicate.0 != other.0.predicate.0
88 }
89
90 proof fn parse_disjoint_on(&self, other: &Tag<BytesN<N>, Seq<u8>>, buf: Seq<u8>) {
91 }
92}
93
94impl DisjointFrom<Tag<Bytes, Seq<u8>>> for Tag<Bytes, Seq<u8>> {
96 open spec fn disjoint_from(&self, other: &Tag<Bytes, Seq<u8>>) -> bool {
97 self.0.predicate.0 != other.0.predicate.0 && self.0.inner.0 == other.0.inner.0
99 }
100
101 proof fn parse_disjoint_on(&self, other: &Tag<Bytes, Seq<u8>>, buf: Seq<u8>) {
102 }
103}
104
105impl<const N: usize> DisjointFrom<Refined<BytesN<N>, TagPred<Seq<u8>>>> for Refined<BytesN<N>, TagPred<Seq<u8>>> {
106 open spec fn disjoint_from(&self, other: &Refined<BytesN<N>, TagPred<Seq<u8>>>) -> bool {
107 self.predicate.0 != other.predicate.0
108 }
109
110 proof fn parse_disjoint_on(&self, other: &Refined<BytesN<N>, TagPred<Seq<u8>>>, buf: Seq<u8>) {
111 }
112}
113
114impl DisjointFrom<Refined<Bytes, TagPred<Seq<u8>>>> for Refined<Bytes, TagPred<Seq<u8>>> {
115 open spec fn disjoint_from(&self, other: &Refined<Bytes, TagPred<Seq<u8>>>) -> bool {
116 self.predicate.0 != other.predicate.0 && self.inner.0 == other.inner.0
117 }
118
119 proof fn parse_disjoint_on(&self, other: &Refined<Bytes, TagPred<Seq<u8>>>, buf: Seq<u8>) {
120 }
121}
122
123impl<U1, U2, V1, V2> DisjointFrom<(U2, V2)> for (U1, V1) where
125 U1: DisjointFrom<U2>,
126 U1: SecureSpecCombinator,
127 U2: SecureSpecCombinator,
128 V1: SpecCombinator,
129 V2: SpecCombinator,
130 {
131 open spec fn disjoint_from(&self, other: &(U2, V2)) -> bool {
132 self.0.disjoint_from(&other.0)
133 }
134
135 proof fn parse_disjoint_on(&self, other: &(U2, V2), buf: Seq<u8>) {
136 self.0.parse_disjoint_on(&other.0, buf)
137 }
138}
139
140impl<U1, U2, V1, V2> DisjointFrom<Preceded<U2, V2>> for Preceded<U1, V1> where
142 U1: DisjointFrom<U2>,
143 U1: SecureSpecCombinator<SpecResult = ()>,
144 U2: SecureSpecCombinator<SpecResult = ()>,
145 V1: SpecCombinator,
146 V2: SpecCombinator,
147 {
148 open spec fn disjoint_from(&self, other: &Preceded<U2, V2>) -> bool {
149 self.0.disjoint_from(&other.0)
150 }
151
152 proof fn parse_disjoint_on(&self, other: &Preceded<U2, V2>, buf: Seq<u8>) {
153 self.0.parse_disjoint_on(&other.0, buf)
154 }
155}
156
157impl<U1, U2, V1, V2> DisjointFrom<SpecDepend<U2, V2>> for SpecDepend<U1, V1> where
158 U1: DisjointFrom<U2>,
159 U1: SecureSpecCombinator,
160 U2: SecureSpecCombinator,
161 V1: SpecCombinator,
162 V2: SpecCombinator,
163 {
164 open spec fn disjoint_from(&self, other: &SpecDepend<U2, V2>) -> bool {
165 self.fst.disjoint_from(&other.fst)
166 }
167
168 proof fn parse_disjoint_on(&self, other: &SpecDepend<U2, V2>, buf: Seq<u8>) {
169 self.fst.parse_disjoint_on(&other.fst, buf)
170 }
171}
172
173impl<S1, S2, S3> DisjointFrom<S3> for OrdChoice<S1, S2> where
178 S1: SpecCombinator + DisjointFrom<S3>,
179 S2: SpecCombinator + DisjointFrom<S1> + DisjointFrom<S3>,
180 S3: SpecCombinator,
181 {
182 open spec fn disjoint_from(&self, other: &S3) -> bool {
183 self.0.disjoint_from(other) && self.1.disjoint_from(other)
184 }
185
186 proof fn parse_disjoint_on(&self, other: &S3, buf: Seq<u8>) {
187 self.0.parse_disjoint_on(other, buf);
188 self.1.parse_disjoint_on(other, buf);
189 }
190}
191
192impl<U1, U2, M1, M2> DisjointFrom<Mapped<U2, M2>> for Mapped<U1, M1> where
193 U1: DisjointFrom<U2>,
194 U2: SpecCombinator,
195 M1: SpecIso<Src = U1::SpecResult>,
196 M2: SpecIso<Src = U2::SpecResult>,
197 U1::SpecResult: SpecFrom<M1::Dst>,
198 U2::SpecResult: SpecFrom<M2::Dst>,
199 M1::Dst: SpecFrom<U1::SpecResult>,
200 M2::Dst: SpecFrom<U2::SpecResult>,
201 {
202 open spec fn disjoint_from(&self, other: &Mapped<U2, M2>) -> bool {
203 self.inner.disjoint_from(&other.inner)
204 }
205
206 proof fn parse_disjoint_on(&self, other: &Mapped<U2, M2>, buf: Seq<u8>) {
207 self.inner.parse_disjoint_on(&other.inner, buf)
208 }
209}
210
211impl<Inner1, Inner2> DisjointFrom<Cond<Inner2>> for Cond<Inner1> where
213 Inner1: SpecCombinator,
214 Inner2: SpecCombinator,
215 {
216 open spec fn disjoint_from(&self, other: &Cond<Inner2>) -> bool {
217 self.cond ==> !other.cond
218 }
219
220 proof fn parse_disjoint_on(&self, other: &Cond<Inner2>, buf: Seq<u8>) {
221 }
222}
223
224impl<'a, 'b, T1, T2> DisjointFrom<&'a T1> for &'b T2 where
225 T1: SpecCombinator,
226 T2: SpecCombinator + DisjointFrom<T1>,
227 {
228 open spec fn disjoint_from(&self, other: &&T1) -> bool {
229 (*self).disjoint_from(*other)
230 }
231
232 proof fn parse_disjoint_on(&self, other: &&T1, buf: Seq<u8>) {
233 (*self).parse_disjoint_on(*other, buf)
234 }
235}
236
237impl<T> DisjointFrom<T> for Fail where T: SpecCombinator {
239 open spec fn disjoint_from(&self, c: &T) -> bool {
240 true
241 }
242
243 proof fn parse_disjoint_on(&self, c: &T, buf: Seq<u8>) {
244 }
245}
246
247}