From 6feff2ae69d331c5cab9b775da07294f7ea79acc Mon Sep 17 00:00:00 2001 From: "Eduard S." Date: Tue, 10 Jun 2025 15:06:57 +0200 Subject: [PATCH] display statement/statement_tmpl as in pod lang v1 (#269) * display statement/statement_tmpl as in pod lang v1 * fix tests --- src/backends/plonky2/circuits/common.rs | 1 + src/backends/plonky2/mainpod/statement.rs | 2 +- src/examples/custom.rs | 17 ++--- src/frontend/custom.rs | 4 ++ src/lang/mod.rs | 20 +++++- src/middleware/custom.rs | 87 +++++++++++++++++------ src/middleware/mod.rs | 7 +- src/middleware/statement.rs | 28 ++++---- 8 files changed, 114 insertions(+), 52 deletions(-) diff --git a/src/backends/plonky2/circuits/common.rs b/src/backends/plonky2/circuits/common.rs index 7e470d2..1d3ea88 100644 --- a/src/backends/plonky2/circuits/common.rs +++ b/src/backends/plonky2/circuits/common.rs @@ -543,6 +543,7 @@ impl CustomPredicateEntryTarget { conjunction: predicate.conjunction, statements, args_len: predicate.args_len, + wildcard_names: predicate.wildcard_names.clone(), }; self.predicate.set_targets(pw, params, &predicate)?; Ok(()) diff --git a/src/backends/plonky2/mainpod/statement.rs b/src/backends/plonky2/mainpod/statement.rs index 4f05ab3..d121252 100644 --- a/src/backends/plonky2/mainpod/statement.rs +++ b/src/backends/plonky2/mainpod/statement.rs @@ -131,7 +131,7 @@ impl fmt::Display for Statement { if i != 0 { write!(f, " ")?; } - write!(f, "{}", arg)?; + arg.fmt(f)?; } } Ok(()) diff --git a/src/examples/custom.rs b/src/examples/custom.rs index 3ca357d..75c2f0d 100644 --- a/src/examples/custom.rs +++ b/src/examples/custom.rs @@ -41,7 +41,7 @@ pub fn eth_friend_batch(params: &Params, mock: bool) -> Result Result Result Result Vec { + names.iter().map(|s| s.to_string()).collect() + } + #[test] fn test_e2e_simple_predicate() -> Result<(), LangError> { let input = r#" @@ -86,6 +90,7 @@ mod tests { "is_equal".to_string(), expected_statements, 2, // args_len (PodA, PodB) + names(&["PodA", "PodB"]), )?; let expected_batch = CustomPredicateBatch::new(¶ms, "PodlogBatch".to_string(), vec![expected_predicate]); @@ -180,6 +185,7 @@ mod tests { "uses_private".to_string(), expected_statements, 1, // args_len (A) + names(&["A", "Temp"]), )?; let expected_batch = CustomPredicateBatch::new(¶ms, "PodlogBatch".to_string(), vec![expected_predicate]); @@ -226,6 +232,7 @@ mod tests { "my_pred".to_string(), expected_pred_statements, 2, // args_len (X, Y) + names(&["X", "Y"]), )?; let expected_batch = CustomPredicateBatch::new(¶ms, "PodlogBatch".to_string(), vec![expected_predicate]); @@ -516,7 +523,7 @@ mod tests { eth_friend(?intermed_key, ?dst_key) ) - eth_dos_distance(src_key, dst_key, distance_key, private: intermed_key, shorter_distance_key) = OR( + eth_dos_distance(src_key, dst_key, distance_key) = OR( eth_dos_distance_base(?src_key, ?dst_key, ?distance_key) eth_dos_distance_ind(?src_key, ?dst_key, ?distance_key) ) @@ -566,6 +573,7 @@ mod tests { true, // AND expected_friend_stmts, 2, // public_args_len: src_key, dst_key + names(&["src_key", "dst_key", "attestation_pod"]), )?; // eth_dos_distance_base (Index 1) @@ -588,6 +596,7 @@ mod tests { true, // AND expected_base_stmts, 3, // public_args_len + names(&["src_key", "dst_key", "distance_key"]), )?; // eth_dos_distance_ind (Index 2) @@ -630,6 +639,14 @@ mod tests { true, // AND expected_ind_stmts, 3, // public_args_len + names(&[ + "src_key", + "dst_key", + "distance_key", + "one_key", + "shorter_distance_key", + "intermed_key", + ]), )?; // eth_dos_distance (Index 3) @@ -659,6 +676,7 @@ mod tests { false, // OR expected_dist_stmts, 3, // public_args_len + names(&["src_key", "dst_key", "distance_key"]), )?; let expected_batch = CustomPredicateBatch::new( diff --git a/src/middleware/custom.rs b/src/middleware/custom.rs index ec9584a..3c188fa 100644 --- a/src/middleware/custom.rs +++ b/src/middleware/custom.rs @@ -23,7 +23,11 @@ impl Wildcard { impl fmt::Display for Wildcard { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "*{}[{}]", self.index, self.name) + if f.alternate() { + write!(f, "?{}:{}", self.index, self.name) + } else { + write!(f, "?{}", self.name) + } } } @@ -43,8 +47,8 @@ pub enum KeyOrWildcard { impl fmt::Display for KeyOrWildcard { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - Self::Key(k) => write!(f, "{}", k), - Self::Wildcard(wc) => write!(f, "{}", wc), + Self::Key(k) => k.fmt(f), + Self::Wildcard(wc) => wc.fmt(f), } } } @@ -75,7 +79,7 @@ impl fmt::Display for SelfOrWildcard { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { Self::SELF => write!(f, "SELF"), - Self::Wildcard(wc) => write!(f, "{}", wc), + Self::Wildcard(wc) => wc.fmt(f), } } } @@ -166,9 +170,14 @@ impl fmt::Display for StatementTmplArg { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { Self::None => write!(f, "none"), - Self::Literal(v) => write!(f, "{}", v), - Self::AnchoredKey(pod_id, key) => write!(f, "({}, {})", pod_id, key), - Self::WildcardLiteral(v) => write!(f, "{}", v), + Self::Literal(v) => v.fmt(f), + Self::AnchoredKey(pod_id, key) => { + pod_id.fmt(f)?; + write!(f, "[")?; + key.fmt(f)?; + write!(f, "]") + } + Self::WildcardLiteral(v) => v.fmt(f), } } } @@ -191,12 +200,13 @@ impl StatementTmpl { impl fmt::Display for StatementTmpl { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}(", self.pred)?; + self.pred.fmt(f)?; + write!(f, "(")?; for (i, arg) in self.args.iter().enumerate() { if i != 0 { write!(f, ", ")?; } - write!(f, "{}", arg)?; + arg.fmt(f)?; } writeln!(f) } @@ -240,6 +250,9 @@ pub struct CustomPredicate { pub(crate) conjunction: bool, pub(crate) statements: Vec, pub(crate) args_len: usize, + /// Names of the wildcards, the first `args_len` entries correspond to the `args_len` arguments + /// of the custom predicate. + pub(crate) wildcard_names: Vec, // TODO: Add private args length? // TODO: Add args type information? } @@ -254,6 +267,7 @@ impl CustomPredicate { args: vec![], }], args_len: 0, + wildcard_names: vec![], } } pub fn and( @@ -261,16 +275,18 @@ impl CustomPredicate { name: String, statements: Vec, args_len: usize, + wildcard_names: Vec, ) -> Result { - Self::new(params, name, true, statements, args_len) + Self::new(params, name, true, statements, args_len, wildcard_names) } pub fn or( params: &Params, name: String, statements: Vec, args_len: usize, + wildcard_names: Vec, ) -> Result { - Self::new(params, name, false, statements, args_len) + Self::new(params, name, false, statements, args_len, wildcard_names) } pub fn new( params: &Params, @@ -278,6 +294,7 @@ impl CustomPredicate { conjunction: bool, statements: Vec, args_len: usize, + wildcard_names: Vec, ) -> Result { if statements.len() > params.max_custom_predicate_arity { return Err(Error::max_length( @@ -293,12 +310,20 @@ impl CustomPredicate { params.max_statement_args, )); } + if wildcard_names.len() > params.max_custom_predicate_wildcards { + return Err(Error::max_length( + "custom_predicate_wildcards.len".to_string(), + wildcard_names.len(), + params.max_custom_predicate_wildcards, + )); + } Ok(Self { name, conjunction, statements, args_len, + wildcard_names, }) } pub fn pad_statement_tmpl(&self) -> StatementTmpl { @@ -346,25 +371,33 @@ impl ToFields for CustomPredicate { impl fmt::Display for CustomPredicate { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - writeln!(f, "{}<", if self.conjunction { "and" } else { "or" })?; + write!(f, "{}(", self.name)?; + for (i, name) in self.wildcard_names.iter().enumerate() { + if i != 0 { + write!(f, ", ")?; + } + if i == self.args_len { + write!(f, "private: ")?; + } + if f.alternate() { + write!(f, "{}:", i)?; + } + write!(f, "{}", name)?; + } + writeln!(f, ") = {}(", if self.conjunction { "AND" } else { "OR" })?; for st in &self.statements { - write!(f, " {}(", st.pred)?; + write!(f, " ")?; + st.pred.fmt(f)?; + write!(f, "(")?; for (i, arg) in st.args.iter().enumerate() { if i != 0 { write!(f, ", ")?; } - write!(f, "{}", arg)?; + arg.fmt(f)?; } - writeln!(f, "),")?; + writeln!(f, ")")?; } - write!(f, ">(")?; - for i in 0..self.args_len { - if i != 0 { - write!(f, ", ")?; - } - write!(f, "*{}", i)?; - } - writeln!(f, ")")?; + write!(f, ")")?; Ok(()) } } @@ -467,6 +500,9 @@ mod tests { index: i, } } + fn names(names: &[&str]) -> Vec { + names.iter().map(|s| s.to_string()).collect() + } type STA = StatementTmplArg; type KOW = KeyOrWildcard; @@ -507,6 +543,7 @@ mod tests { ), ], 2, + names(&["1", "2", "3", "4", "5"]), )?], ); @@ -570,6 +607,7 @@ mod tests { ), ], 4, + names(&["1", "2", "3", "4"]), )?; let eth_friend_batch = @@ -596,6 +634,7 @@ mod tests { ), ], 6, + names(&["0", "1", "2", "3", "4", "5"]), )?; // 1 @@ -640,6 +679,7 @@ mod tests { ), ], 6, + names(&["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"]), )?; // 2 @@ -671,6 +711,7 @@ mod tests { ), ], 6, + names(&["0", "1", "2", "3", "4", "5"]), )?; let eth_dos_distance_batch = CustomPredicateBatch::new( diff --git a/src/middleware/mod.rs b/src/middleware/mod.rs index cf6a37e..ef357f2 100644 --- a/src/middleware/mod.rs +++ b/src/middleware/mod.rs @@ -484,7 +484,7 @@ impl ToFields for Key { impl fmt::Display for Key { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}", self.name)?; + write!(f, "\"{}\"", self.name)?; Ok(()) } } @@ -546,7 +546,10 @@ impl AnchoredKey { impl fmt::Display for AnchoredKey { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}.{}", self.pod_id, self.key)?; + self.pod_id.fmt(f)?; + write!(f, "[")?; + self.key.fmt(f)?; + write!(f, "]")?; Ok(()) } } diff --git a/src/middleware/statement.rs b/src/middleware/statement.rs index aee4407..b36c0a1 100644 --- a/src/middleware/statement.rs +++ b/src/middleware/statement.rs @@ -73,8 +73,8 @@ impl fmt::Display for WildcardValue { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { WildcardValue::None => write!(f, "none"), - WildcardValue::PodId(pod_id) => write!(f, "{}", pod_id), - WildcardValue::Key(key) => write!(f, "{}", key), + WildcardValue::PodId(pod_id) => pod_id.fmt(f), + WildcardValue::Key(key) => key.fmt(f), } } } @@ -147,13 +147,17 @@ impl fmt::Display for Predicate { Self::Native(p) => write!(f, "{:?}", p), Self::BatchSelf(i) => write!(f, "self.{}", i), Self::Custom(CustomPredicateRef { batch, index }) => { - write!( - f, - "{}.{}[{}]", - batch.name, - index, - batch.predicates()[*index].name - ) + if f.alternate() { + write!( + f, + "{}.{}:{}", + batch.name, + index, + batch.predicates()[*index].name + ) + } else { + write!(f, "{}", batch.predicates()[*index].name) + } } } } @@ -368,9 +372,9 @@ impl fmt::Display for StatementArg { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { StatementArg::None => write!(f, "none"), - StatementArg::Literal(v) => write!(f, "{}", v), - StatementArg::Key(r) => write!(f, "{}.{}", r.pod_id, r.key), - StatementArg::WildcardLiteral(v) => write!(f, "{}", v), + StatementArg::Literal(v) => v.fmt(f), + StatementArg::Key(r) => r.fmt(f), + StatementArg::WildcardLiteral(v) => v.fmt(f), } } }