ergotree_ir/mir/
sigma_and.rs1use std::convert::TryInto;
4
5use crate::serialization::op_code::OpCode;
6use crate::serialization::sigma_byte_reader::SigmaByteRead;
7use crate::serialization::sigma_byte_writer::SigmaByteWrite;
8use crate::serialization::SigmaParsingError;
9use crate::serialization::SigmaSerializable;
10use crate::serialization::SigmaSerializeResult;
11use crate::sigma_protocol::sigma_boolean::SigmaConjectureItems;
12use crate::types::stype::SType;
13
14use super::expr::Expr;
15use super::expr::InvalidArgumentError;
16use crate::has_opcode::HasStaticOpCode;
17
18#[derive(PartialEq, Eq, Debug, Clone)]
20pub struct SigmaAnd {
21 pub items: SigmaConjectureItems<Expr>,
23}
24
25impl SigmaAnd {
26 pub fn new(items: Vec<Expr>) -> Result<Self, InvalidArgumentError> {
28 let item_types: Vec<SType> = items
29 .clone()
30 .into_iter()
31 .map(|it| it.post_eval_tpe())
32 .collect();
33 if item_types
34 .iter()
35 .all(|tpe| matches!(tpe, SType::SSigmaProp))
36 {
37 Ok(Self {
38 items: items.try_into()?,
39 })
40 } else {
41 Err(InvalidArgumentError(format!(
42 "Sigma conjecture: expected all items be of type SSigmaProp, got {:?},\n items: {:?}",
43 item_types, items
44 )))
45 }
46 }
47
48 pub fn tpe(&self) -> SType {
50 SType::SSigmaProp
51 }
52}
53
54impl HasStaticOpCode for SigmaAnd {
55 const OP_CODE: OpCode = OpCode::SIGMA_AND;
56}
57
58impl SigmaSerializable for SigmaAnd {
59 fn sigma_serialize<W: SigmaByteWrite>(&self, w: &mut W) -> SigmaSerializeResult {
60 self.items.sigma_serialize(w)
61 }
62
63 fn sigma_parse<R: SigmaByteRead>(r: &mut R) -> Result<Self, SigmaParsingError> {
64 Ok(Self::new(Vec::<Expr>::sigma_parse(r)?)?)
65 }
66}
67
68#[cfg(feature = "arbitrary")]
70#[allow(clippy::unwrap_used)]
71mod arbitrary {
72 use super::*;
73 use crate::mir::constant::Constant;
74 use proptest::collection::vec;
75 use proptest::prelude::*;
76
77 impl Arbitrary for SigmaAnd {
78 type Strategy = BoxedStrategy<Self>;
79 type Parameters = ();
80
81 fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
82 vec(any_with::<Constant>(SType::SSigmaProp.into()), 2..5)
83 .prop_map(|constants| Self {
84 items: constants
85 .into_iter()
86 .map(|c| c.into())
87 .collect::<Vec<Expr>>()
88 .try_into()
89 .unwrap(),
90 })
91 .boxed()
92 }
93 }
94}
95
96#[cfg(test)]
97#[allow(clippy::panic)]
98mod tests {
99 use super::*;
100 use crate::mir::expr::Expr;
101 use crate::serialization::sigma_serialize_roundtrip;
102 use proptest::prelude::*;
103
104 proptest! {
105
106 #[test]
107 fn ser_roundtrip(v in any::<SigmaAnd>()) {
108 let expr: Expr = v.into();
109 prop_assert_eq![sigma_serialize_roundtrip(&expr), expr];
110 }
111
112 }
113}