-
Notifications
You must be signed in to change notification settings - Fork 22
Add prune_with_tracker method
#323
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Add `prune_with_tracker` method to `node::redeem::RedeemNode` to allow passing custom execution trackers during node pruning. The existing `prune` method is now a wrapper around this new method; it passes `SetTracker` to preserve the original behavior. Also modify the `bit_machine::ExecTracker` trait to include two new methods: `contains_left` and `contains_right`. These check if the left or right branch of a case node contains a given `Ihr`, allowing us to replicate the `SetTracker` logic inside old `prune` method. Removed `bit_machine::BitMachine::exec_prune`, because after the change, it appears that this function is no longer used anywhere. Since it is visible only within the crate, I assume it is safe to remove.
|
By adding the ability to pass a tracker here in /// Check if left branch of the case node contains given `ihr`.
fn contains_left(&self, ihr: &Ihr) -> bool;
/// Check if right branch of the case node contains given `ihr`.
fn contains_right(&self, ihr: &Ihr) -> bool;
/// Track the execution of the left branch of the case node with the given `ihr`.
fn track_left(&mut self, ihr: Ihr);
/// Track the execution of the right branch of the case node with the given `ihr`.
fn track_right(&mut self, ihr: Ihr);Which, in my opinion, is not the right way to go. By looking more closely at the Instead, I would propose adding more capabilities to the You can add optional Here is a rough idea of how sink logic can be handled: fn default_debug_sink(label: &str, value: &dyn core::fmt::Display) {
println!("DBG: {label} = {value}");
}
fn default_jet_trace_sink(jet: Elements, args: &[Value], result: &Value) {
print!("{jet:?}(");
for (i, a) in args.iter().enumerate() {
if i > 0 {
print!(", ");
}
print!("{a}");
}
println!(") = {result}");
}
/// Create a new tracker bound to the provided debug symbol table.
#[must_use]
pub fn new(debug_symbols: &'a DebugSymbols) -> Self {
Self {
debug_symbols,
debug_sink: None,
jet_trace_sink: None,
}
}
/// Enable forwarding of debug!() calls to the provided sink.
#[must_use]
pub fn with_debug_sink<F>(mut self, sink: F) -> Self
where
F: FnMut(&str, &dyn core::fmt::Display) + 'a,
{
self.debug_sink = Some(Box::new(sink));
Self { ..self }
}
/// Enable the default debug!() sink that prints to stdout.
#[must_use]
pub fn with_default_debug_sink(self) -> Self {
self.with_debug_sink(default_debug_sink)
}
/// Enable forwarding of jet call traces to the provided sink.
#[must_use]
pub fn with_jet_trace_sink<F>(mut self, sink: F) -> Self
where
F: FnMut(Elements, &[Value], &Value) + 'a,
{
self.jet_trace_sink = Some(Box::new(sink));
Self { ..self }
}
/// Enable the default jet trace sink that prints to stdout.
#[must_use]
pub fn with_default_jet_trace_sink(self) -> Self {
self.with_jet_trace_sink(default_jet_trace_sink)
}
// ...
fn track_jet_call(
&mut self,
jet: &Elements,
input_buffer: &[UWORD],
output_buffer: &[UWORD],
_: bool,
) {
if let Some(sink) = self.jet_trace_sink.as_mut()
&& let (Ok(args), Ok(result)) = (
parse_args(*jet, input_buffer),
parse_result(*jet, output_buffer),
)
{
sink(*jet, &args, &result);
}
}
fn track_dbg_call(&mut self, cmr: &Cmr, value: simplicityhl::simplicity::Value) {
if let Some(sink) = self.debug_sink.as_mut()
&& let Some(tracked_call) = self.debug_symbols.get(cmr)
&& let Some(Either::Right(debug_value)) =
tracked_call.map_value(&StructuralValue::from(value))
{
sink(debug_value.text(), &debug_value.value());
}
}
fn is_track_debug_enabled(&self) -> bool {
self.debug_sink.is_some()
}So if the user wants, they will be able to construct a structure for getting logs. We should also make enough effort to write good Rust docs for the new function to make it as easy as possible for the user to see the logs of |
|
This PR does multiple things:
Can you split these into multiple commits?
We already expose I think we should back up and come up with a principled API for |
|
I propose we do this #324 |
|
See #325 for an alternate approach. |
|
Closing this in favor of #325 |
…ion trait 3bf7cef bit_machine: add example StderrTracker which outputs stuff to stderr (Andrew Poelstra) 6013bd5 bit_machine: replace `ExecTracker` API with a much more general one (Andrew Poelstra) 4134976 bit_machine: add PruneTracker trait and RedeemNode::prune_with_tracker (Andrew Poelstra) ca4e497 bit_machine: move tracker stuff to its own module (Andrew Poelstra) eaa02d0 bit_machine: rename private new/move/drop methods and variants (Andrew Poelstra) 228a85f bit_machine: put pub(super) on all public methods of Frame (Andrew Poelstra) 8622a8f bit_machine: return concrete type from `as_bit_iter` (Andrew Poelstra) 7ecf394 BitIter: add ExactSizeIterator bound, size_hint and tests (Andrew Poelstra) Pull request description: Adds the ability for the execution tracker to track every visited node, to view the "input" (top read frame) of every node and the "output" (top write frame after execution) of every terminal node. Allows it to read this data in the form of a bit iterator, which is much easier to work with than the `&[UWORD]` that the old jet interface provided. Allows tracking "debug" nodes without special-purpose methods that enable/disable costly conversions. Also adds a `PruneTracker` extension trait which can be used to introspect or manipulate the pruning process. See #323 and #324 for motivation. Fixes #324. ACKs for top commit: KyrylR: ACK 3bf7cef Tree-SHA512: 81969779ca6f45d0ae3556475f10de6e661a8169c65409e15d697277e6806689b104644f5e5f25ce22d806f51fbfd892ebd0649ae8d24f2cd58bd551f4b476e7
Add
prune_with_trackermethod tonode::redeem::RedeemNodeto allow passing custom execution trackers during node pruning. The existingprunemethod is now a wrapper around this new method; it passesSetTrackerto preserve the original behavior.Also modify the
bit_machine::ExecTrackertrait to include two new methods:contains_leftandcontains_right. These check if the left or right branch of a case node contains a givenIhr, allowing us to replicate theSetTrackerlogic inside oldprunemethod.Removed
bit_machine::BitMachine::exec_prune, because after the change, it appears that this function is no longer used anywhere. Since it is visible only within the crate, I assume it is safe to remove.