Skip to content

Commit 29a5d91

Browse files
committed
fix(linear_relation): better handling of trivial constraints.
Instead of throwing an error for trivial constraints, we now skip processing them.
1 parent 07cad99 commit 29a5d91

File tree

1 file changed

+33
-24
lines changed

1 file changed

+33
-24
lines changed

src/linear_relation/mod.rs

Lines changed: 33 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,7 @@ impl<G: PrimeGroup> CanonicalLinearRelation<G> {
390390
/// Process a single constraint equation and add it to the canonical relation
391391
fn process_constraint(
392392
&mut self,
393-
image_var: GroupVar<G>,
393+
&image_var: &GroupVar<G>,
394394
equation: &LinearCombination<G>,
395395
original_relation: &LinearRelation<G>,
396396
weighted_group_cache: &mut HashMap<GroupVar<G>, Vec<(G::Scalar, GroupVar<G>)>>,
@@ -679,39 +679,48 @@ impl<G: PrimeGroup> TryFrom<&LinearRelation<G>> for CanonicalLinearRelation<G> {
679679
return Err(InvalidInstance::new("Image contains identity element"));
680680
}
681681

682-
// If any linear combination is empty, the relation is invalid
683-
if relation
684-
.linear_map
685-
.linear_combinations
686-
.iter()
687-
.any(|lc| lc.0.is_empty())
688-
{
689-
return Err(InvalidInstance::new("Linear combinations cannot be empty"));
690-
}
691-
692-
// If any linear combination has no witness variables, the relation is invalid
693-
if relation.linear_map.linear_combinations.iter().any(|lc| {
694-
lc.0.iter()
695-
.all(|weighted| matches!(weighted.term.scalar, ScalarTerm::Unit))
696-
}) {
697-
return Err(InvalidInstance::new(
698-
"A linear combination does not have any witness variables",
699-
));
700-
}
701-
702682
let mut canonical = CanonicalLinearRelation::new();
703683
canonical.num_scalars = relation.linear_map.num_scalars;
704684

705685
// Cache for deduplicating weighted group elements
706686
let mut weighted_group_cache = HashMap::new();
707687

708688
// Process each constraint using the modular helper method
709-
for (image_var, equation) in
689+
for (lhs, rhs) in
710690
iter::zip(&relation.image, &relation.linear_map.linear_combinations)
711691
{
692+
693+
// If the linear combination is empty, skip it
694+
if rhs.0.is_empty() {
695+
continue;
696+
}
697+
698+
// If the linear combination is trivial, check it directly and skip processing.
699+
if !rhs.0.is_empty() && rhs.0.iter().all(|weighted| matches!(weighted.term.scalar, ScalarTerm::Unit)) {
700+
let lhs_value = relation
701+
.linear_map
702+
.group_elements
703+
.get(*lhs)
704+
.map_err(|_| InvalidInstance::new("Unassigned group variable in image"))?;
705+
706+
let rhs_value = rhs.0.iter().fold(G::identity(), |acc, weighted| {
707+
acc + relation
708+
.linear_map
709+
.group_elements
710+
.get(weighted.term.elem)
711+
.unwrap_or_else(|_| panic!("Unassigned group variable in linear combination"))
712+
* weighted.weight
713+
});
714+
if lhs_value != rhs_value {
715+
return Err(InvalidInstance::new("Trivial linear combination does not match image"));
716+
} else {
717+
continue; // Skip processing trivial constraints
718+
}
719+
}
720+
712721
canonical.process_constraint(
713-
*image_var,
714-
equation,
722+
lhs,
723+
rhs,
715724
relation,
716725
&mut weighted_group_cache,
717726
)?;

0 commit comments

Comments
 (0)