This commit is contained in:
wborgeaud 2021-08-20 12:55:59 +02:00
parent 1d368782f2
commit 507577b7ad
4 changed files with 21 additions and 20 deletions

View File

@ -83,7 +83,7 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
gate,
input: swap_wire,
});
self.generate_copy(bit.target, swap_wire);
self.route(bit.target, swap_wire);
let input_wires = (0..12)
.map(|i| {

View File

@ -17,7 +17,7 @@ pub(crate) fn generate_partial_witness<F: Field>(
generators: &[Box<dyn WitnessGenerator<F>>],
timing: &mut TimingTree,
) {
let max_target_index = witness.nodes.len();
let max_target_index = witness.forest.len();
// Index generator indices by their watched targets.
let mut generator_indices_by_watches = vec![Vec::new(); max_target_index];
timed!(timing, "index generators by their watched targets", {

View File

@ -11,6 +11,7 @@ use crate::iop::target::{BoolTarget, Target};
use crate::iop::wire::Wire;
use crate::plonk::permutation_argument::ForestNode;
/// A witness holds information on the values of targets in a circuit.
pub trait Witness<F: Field> {
fn try_get_target(&self, target: Target) -> Option<F>;
@ -155,8 +156,6 @@ impl<F: Field> MatrixWitness<F> {
#[derive(Clone, Debug)]
pub struct PartialWitness<F: Field> {
// pub(crate) wire_values: Vec<Vec<Option<F>>>,
// pub(crate) virtual_target_values: Vec<Option<F>>,
pub(crate) target_values: HashMap<Target, F>,
}
@ -185,9 +184,11 @@ impl<F: Field> Witness<F> for PartialWitness<F> {
}
}
/// `PartitionWitness` holds a disjoint-set forest of the targets respecting a ciruit's copy constraints.
/// The value of a target is defined to be the value of its root in the forest.
#[derive(Clone)]
pub struct PartitionWitness<F: Field> {
pub nodes: Vec<ForestNode<Target, F>>,
pub forest: Vec<ForestNode<Target, F>>,
pub num_wires: usize,
pub num_routed_wires: usize,
pub degree: usize,
@ -195,12 +196,12 @@ pub struct PartitionWitness<F: Field> {
impl<F: Field> Witness<F> for PartitionWitness<F> {
fn try_get_target(&self, target: Target) -> Option<F> {
self.nodes[self.nodes[self.target_index(target)].parent].value
self.forest[self.forest[self.target_index(target)].parent].value
}
fn set_target(&mut self, target: Target, value: F) {
let i = self.nodes[self.target_index(target)].parent;
self.nodes[i].value = Some(value);
let i = self.forest[self.target_index(target)].parent;
self.forest[i].value = Some(value);
}
}

View File

@ -23,7 +23,7 @@ pub struct ForestNode<T: Debug + Copy + Eq + PartialEq, V: Field> {
impl<F: Field> PartitionWitness<F> {
pub fn new(num_wires: usize, num_routed_wires: usize, degree: usize) -> Self {
Self {
nodes: vec![],
forest: vec![],
num_wires,
num_routed_wires,
degree,
@ -32,9 +32,9 @@ impl<F: Field> PartitionWitness<F> {
/// Add a new partition with a single member.
pub fn add(&mut self, t: Target) {
let index = self.nodes.len();
let index = self.forest.len();
debug_assert_eq!(self.target_index(t), index);
self.nodes.push(ForestNode {
self.forest.push(ForestNode {
t,
parent: index,
size: 1,
@ -46,8 +46,8 @@ impl<F: Field> PartitionWitness<F> {
/// Path compression method, see https://en.wikipedia.org/wiki/Disjoint-set_data_structure#Finding_set_representatives.
pub fn find(&mut self, x: ForestNode<Target, F>) -> ForestNode<Target, F> {
if x.parent != x.index {
let root = self.find(self.nodes[x.parent]);
self.nodes[x.index].parent = root.index;
let root = self.find(self.forest[x.parent]);
self.forest[x.index].parent = root.index;
root
} else {
x
@ -56,8 +56,8 @@ impl<F: Field> PartitionWitness<F> {
/// Merge two sets.
pub fn merge(&mut self, tx: Target, ty: Target) {
let mut x = self.nodes[self.target_index(tx)];
let mut y = self.nodes[self.target_index(ty)];
let mut x = self.forest[self.target_index(tx)];
let mut y = self.forest[self.target_index(ty)];
x = self.find(x);
y = self.find(y);
@ -74,8 +74,8 @@ impl<F: Field> PartitionWitness<F> {
y.size += x.size;
}
self.nodes[x.index] = x;
self.nodes[y.index] = y;
self.forest[x.index] = x;
self.forest[y.index] = y;
}
}
impl<F: Field> PartitionWitness<F> {
@ -85,14 +85,14 @@ impl<F: Field> PartitionWitness<F> {
for input in 0..self.num_routed_wires {
let w = Wire { gate, input };
let t = Target::Wire(w);
let x = self.nodes[self.target_index(t)];
let x = self.forest[self.target_index(t)];
partition.entry(self.find(x).t).or_default().push(w);
}
}
// I'm not 100% sure this loop is needed, but I'm afraid removing it might lead to subtle bugs.
for index in 0..self.nodes.len() - self.degree * self.num_wires {
for index in 0..self.forest.len() - self.degree * self.num_wires {
let t = Target::VirtualTarget { index };
let x = self.nodes[self.target_index(t)];
let x = self.forest[self.target_index(t)];
self.find(x);
}