Skip to content

Commit 4134976

Browse files
committed
bit_machine: add PruneTracker trait and RedeemNode::prune_with_tracker
This eliminates the private `exec_prune` method which was weirdly-named and no longer makes sense now that we're using a generic tracker rather than a SetTracker.
1 parent ca4e497 commit 4134976

3 files changed

Lines changed: 42 additions & 44 deletions

File tree

src/bit_machine/mod.rs

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use crate::{Cmr, FailEntropy, Value};
2222
use frame::Frame;
2323

2424
pub use self::limits::LimitError;
25-
pub use self::tracker::{ExecTracker, NoTracker, SetTracker};
25+
pub use self::tracker::{ExecTracker, NoTracker, PruneTracker, SetTracker};
2626

2727
/// An iterator over the contents of a read or write frame which yields bits.
2828
pub type FrameIter<'a> = crate::BitIter<core::iter::Copied<core::slice::Iter<'a, u8>>>;
@@ -226,26 +226,6 @@ impl BitMachine {
226226
self.exec_with_tracker(program, env, &mut NoTracker)
227227
}
228228

229-
/// Execute the given `program` on the Bit Machine and track executed case branches.
230-
///
231-
/// If the program runs successfully, then two sets of IHRs are returned:
232-
///
233-
/// 1) The IHRs of case nodes whose _left_ branch was executed.
234-
/// 2) The IHRs of case nodes whose _right_ branch was executed.
235-
///
236-
/// ## Precondition
237-
///
238-
/// The Bit Machine is constructed via [`Self::for_program()`] to ensure enough space.
239-
pub(crate) fn exec_prune<J: Jet>(
240-
&mut self,
241-
program: &RedeemNode<J>,
242-
env: &J::Environment,
243-
) -> Result<SetTracker, ExecutionError> {
244-
let mut tracker = SetTracker::default();
245-
self.exec_with_tracker(program, env, &mut tracker)?;
246-
Ok(tracker)
247-
}
248-
249229
/// Execute the given `program` on the Bit Machine, using the given environment and tracker.
250230
///
251231
/// ## Precondition

src/bit_machine/tracker.rs

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -44,29 +44,21 @@ pub trait ExecTracker<J: Jet> {
4444
fn is_track_debug_enabled(&self) -> bool;
4545
}
4646

47+
pub trait PruneTracker<J: Jet>: ExecTracker<J> {
48+
/// Returns true if the left branch of the of the `Case` node with the IHR `ihr` was taken.
49+
fn contains_left(&self, ihr: Ihr) -> bool;
50+
51+
/// Returns true if the right branch of the of the `Case` node with the IHR `ihr` was taken.
52+
fn contains_right(&self, ihr: Ihr) -> bool;
53+
}
54+
4755
/// Tracker of executed left and right branches for each case node.
4856
#[derive(Clone, Debug, Default)]
4957
pub struct SetTracker {
5058
left: HashSet<Ihr>,
5159
right: HashSet<Ihr>,
5260
}
5361

54-
impl SetTracker {
55-
/// Access the set of IHRs of case nodes whose left branch was executed.
56-
pub fn left(&self) -> &HashSet<Ihr> {
57-
&self.left
58-
}
59-
60-
/// Access the set of IHRs of case nodes whose right branch was executed.
61-
pub fn right(&self) -> &HashSet<Ihr> {
62-
&self.right
63-
}
64-
}
65-
66-
/// Tracker that does not do anything (noop).
67-
#[derive(Copy, Clone, Debug)]
68-
pub struct NoTracker;
69-
7062
impl<J: Jet> ExecTracker<J> for SetTracker {
7163
fn track_left(&mut self, ihr: Ihr) {
7264
self.left.insert(ihr);
@@ -85,6 +77,20 @@ impl<J: Jet> ExecTracker<J> for SetTracker {
8577
}
8678
}
8779

80+
impl<J: Jet> PruneTracker<J> for SetTracker {
81+
fn contains_left(&self, ihr: Ihr) -> bool {
82+
self.left.contains(&ihr)
83+
}
84+
85+
fn contains_right(&self, ihr: Ihr) -> bool {
86+
self.right.contains(&ihr)
87+
}
88+
}
89+
90+
/// Tracker that does not do anything (noop).
91+
#[derive(Copy, Clone, Debug)]
92+
pub struct NoTracker;
93+
8894
impl<J: Jet> ExecTracker<J> for NoTracker {
8995
fn track_left(&mut self, _: Ihr) {}
9096

src/node/redeem.rs

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// SPDX-License-Identifier: CC0-1.0
22

33
use crate::analysis::NodeBounds;
4-
use crate::bit_machine::{ExecutionError, SetTracker};
4+
use crate::bit_machine::{ExecutionError, PruneTracker, SetTracker};
55
use crate::dag::{DagLike, InternalSharing, MaxSharing, PostOrderIterItem};
66
use crate::jet::Jet;
77
use crate::types::{self, arrow::FinalArrow};
@@ -290,13 +290,25 @@ impl<J: Jet> RedeemNode<J> {
290290
/// In this case, the witness data needs to be revised.
291291
/// The other pruning steps (2 & 3) never fail.
292292
pub fn prune(&self, env: &J::Environment) -> Result<Arc<RedeemNode<J>>, ExecutionError> {
293-
struct Pruner<'brand, J> {
293+
self.prune_with_tracker(env, &mut SetTracker::default())
294+
}
295+
296+
pub fn prune_with_tracker<T: PruneTracker<J>>(
297+
&self,
298+
env: &J::Environment,
299+
tracker: &mut T,
300+
) -> Result<Arc<RedeemNode<J>>, ExecutionError> {
301+
struct Pruner<'brand, 't, J, T> {
294302
inference_context: types::Context<'brand>,
295-
tracker: SetTracker,
303+
tracker: &'t mut T,
296304
phantom: PhantomData<J>,
297305
}
298306

299-
impl<'brand, J: Jet> Converter<Redeem<J>, Construct<'brand, J>> for Pruner<'brand, J> {
307+
impl<'brand, 't, J, T> Converter<Redeem<J>, Construct<'brand, J>> for Pruner<'brand, 't, J, T>
308+
where
309+
J: Jet,
310+
T: PruneTracker<J>,
311+
{
300312
type Error = std::convert::Infallible;
301313

302314
fn convert_witness(
@@ -332,8 +344,8 @@ impl<J: Jet> RedeemNode<J> {
332344
// but the Converter trait gives us access to the unpruned node (`data`).
333345
// The Bit Machine tracked (un)used case branches based on the unpruned IHR.
334346
match (
335-
self.tracker.left().contains(&data.node.ihr()),
336-
self.tracker.right().contains(&data.node.ihr()),
347+
self.tracker.contains_left(data.node.ihr()),
348+
self.tracker.contains_right(data.node.ihr()),
337349
) {
338350
(true, true) => Ok(Hide::Neither),
339351
(false, true) => Ok(Hide::Left),
@@ -418,7 +430,7 @@ impl<J: Jet> RedeemNode<J> {
418430
// 1) Run the Bit Machine and mark (un)used branches.
419431
// This is the only fallible step in the pruning process.
420432
let mut mac = BitMachine::for_program(self)?;
421-
let tracker = mac.exec_prune(self, env)?;
433+
mac.exec_with_tracker(self, env, tracker)?;
422434

423435
// 2) Prune out unused case branches.
424436
// Because the types of the pruned program may change,

0 commit comments

Comments
 (0)