ovmi/predicates/
there_exists.rs1use crate::executor::*;
2use crate::predicates::*;
3
4pub struct ThereExistsPredicate<'a, Ext: ExternalCall> {
5 pub ext: &'a Ext,
6}
7
8impl<'a, Ext: ExternalCall> ThereExistsPredicate<'a, Ext> {
9 fn replace_variable(
11 &self,
12 property_bytes: &Vec<u8>,
13 placeholder: &Vec<u8>,
14 quantified: &Vec<u8>,
15 ) -> ExecResultT<Vec<u8>, AddressOf<Ext>> {
16 if Ext::is_placeholder(property_bytes) {
20 if &Ext::get_input_value(property_bytes) == placeholder {
21 return Ok(quantified.clone());
22 }
23 }
24 let mut property: Property<AddressOf<Ext>> = Ext::bytes_to_property(&property_bytes)?;
25 if property.predicate_address == Ext::not_address() {
26 require!(property.inputs.len() > 0);
27 property.inputs[0] =
28 self.replace_variable(&property.inputs[0], placeholder, quantified)?;
29 } else if property.predicate_address == self.ext.ext_address() {
30 require!(property.inputs.len() > 2);
31 property.inputs[2] =
32 self.replace_variable(&property.inputs[2], placeholder, quantified)?;
33 } else if property.predicate_address == Ext::and_address()
34 || property.predicate_address == Ext::or_address()
35 {
36 property.inputs = property
37 .inputs
38 .iter()
39 .map(|input| self.replace_variable(input, placeholder, quantified))
40 .collect::<Result<Vec<_>, _>>()?;
41 } else {
42 property.inputs = property
43 .inputs
44 .iter()
45 .map(|input| {
46 if Ext::is_placeholder(input) {
47 if &Ext::get_input_value(input) == placeholder {
48 return quantified.clone();
49 }
50 }
51 input.clone()
52 })
53 .collect();
54 }
55 Ok(property.encode())
56 }
57}
58
59impl<'a, Ext: ExternalCall> LogicalConnectiveInterface<AddressOf<Ext>>
60 for ThereExistsPredicate<'a, Ext>
61{
62 fn is_valid_challenge(
64 &self,
65 inputs: Vec<Vec<u8>>,
66 _challenge_inputs: Vec<Vec<u8>>,
67 challenge: Property<AddressOf<Ext>>,
68 ) -> ExecResult<AddressOf<Ext>> {
69 require_with_message!(
71 challenge.predicate_address == Ext::for_all_address(),
72 "challenge must be ForAllSuchThat"
73 );
74 require!(inputs.len() > 2);
75 let new_inputs = vec![inputs[2].clone()];
76 let p = Property::<AddressOf<Ext>> {
77 predicate_address: Ext::not_address().clone(),
78 inputs: new_inputs,
79 };
80
81 require!(challenge.inputs.len() > 2);
82 require_with_message!(inputs[1] == challenge.inputs[1], "variable must be same");
83 require_with_message!(p.encode() == challenge.inputs[2], "inputs must be same");
84 Ok(true)
85 }
86}
87
88impl<'a, Ext: ExternalCall> DecidablePredicateInterface<AddressOf<Ext>>
89 for ThereExistsPredicate<'a, Ext>
90{
91 fn decide_with_witness(
93 &self,
94 inputs: Vec<Vec<u8>>,
95 witness: Vec<Vec<u8>>,
96 ) -> ExecResult<AddressOf<Ext>> {
97 require!(inputs.len() > 2);
98 require!(witness.len() > 0);
99 let property_bytes = self.replace_variable(&inputs[2], &inputs[1], &witness[0])?;
100 let property: Property<AddressOf<Ext>> = Ext::bytes_to_property(&property_bytes)?;
101 Ok(Ext::bytes_to_bool(
102 &self.ext.ext_call(
103 &property.predicate_address,
104 PredicateCallInputs::DecidablePredicate(
105 DecidablePredicateCallInputs::DecideWithWitness {
106 inputs: property.inputs,
107 witness: witness
108 .as_slice()
109 .get(1..)
110 .unwrap_or(vec![].as_slice())
111 .to_vec(),
112 },
113 ),
114 )?,
115 )?)
116 }
117}