From 2469bafb6f425535012d14a0fcf41b676de7e530 Mon Sep 17 00:00:00 2001 From: Christian Lewe Date: Thu, 9 Jan 2025 15:27:25 +0100 Subject: [PATCH] refactor: Remove manual pruning WitnessNode no longer needs to track whether it should be pruned, because we do pruning directly on the Bit Machine. --- src/node/witness.rs | 125 ++------------------------------------------ 1 file changed, 3 insertions(+), 122 deletions(-) diff --git a/src/node/witness.rs b/src/node/witness.rs index d7761305..568caaf4 100644 --- a/src/node/witness.rs +++ b/src/node/witness.rs @@ -10,9 +10,8 @@ use std::marker::PhantomData; use std::sync::Arc; use super::{ - Constructible, Converter, CoreConstructible, DisconnectConstructible, Hide, Inner, - JetConstructible, Marker, NoWitness, Node, Redeem, RedeemData, RedeemNode, - WitnessConstructible, + Converter, CoreConstructible, DisconnectConstructible, Inner, JetConstructible, Marker, + NoWitness, Node, Redeem, RedeemData, RedeemNode, WitnessConstructible, }; /// ID used to share [`WitnessNode`]s. @@ -45,112 +44,11 @@ impl Marker for Witness { pub type WitnessNode = Node>; impl WitnessNode { - /// Creates a copy of the node (and its entire DAG with the prune bit set) - #[must_use] - pub fn pruned(&self) -> Arc { - let new_data = WitnessData { - must_prune: true, - ..self.data.clone() - }; - Arc::new(WitnessNode { - data: new_data, - cmr: self.cmr, - inner: self - .inner - .as_ref() - .map(Arc::clone) - .map_disconnect(Option::>::clone) - .map_witness(Option::::clone), - }) - } - /// Accessor for the node's arrow pub fn arrow(&self) -> &Arrow { &self.data.arrow } - /// Whether the "must prune" bit is set on this node - pub fn must_prune(&self) -> bool { - self.data.must_prune - } - - pub fn prune_and_retype(&self) -> Arc { - struct Retyper { - inference_context: types::Context, - phantom: PhantomData, - } - - impl Converter, Witness> for Retyper { - type Error = types::Error; - fn convert_witness( - &mut self, - _: &PostOrderIterItem<&WitnessNode>, - wit: &Option, - ) -> Result, Self::Error> { - Ok(Option::::clone(wit)) - } - - fn prune_case( - &mut self, - _: &PostOrderIterItem<&WitnessNode>, - left: &Arc>, - right: &Arc>, - ) -> Result { - // If either child is marked as pruned, we hide it, which will cause this - // case node to become an assertl or assertr, potentially reducing the size - // of types since there will be fewer constraints to unify. - // - // If both children are marked pruned, this function will only hide the left - // one. This doesn't matter; in this case the node itself will be marked as - // pruned and eventually get dropped. - if left.cached_data().must_prune { - Ok(Hide::Left) - } else if right.cached_data().must_prune { - Ok(Hide::Right) - } else { - Ok(Hide::Neither) - } - } - - fn convert_disconnect( - &mut self, - _: &PostOrderIterItem<&WitnessNode>, - maybe_converted: Option<&Arc>>, - _: &Option>>, - ) -> Result>>, Self::Error> { - Ok(maybe_converted.map(Arc::clone)) - } - - fn convert_data( - &mut self, - data: &PostOrderIterItem<&WitnessNode>, - inner: Inner<&Arc>, J, &Option>>, &Option>, - ) -> Result, Self::Error> { - let converted_inner = inner - .map(|node| node.cached_data()) - .map_witness(Option::::clone); - // This next line does the actual retyping. - let mut retyped = - WitnessData::from_inner(&self.inference_context, converted_inner)?; - // Sometimes we set the prune bit on nodes without setting that - // of their children; in this case the prune bit inferred from - // `converted_inner` will be incorrect. - if data.node.data.must_prune { - retyped.must_prune = true; - } - Ok(retyped) - } - } - - // FIXME after running the `ReTyper` we should run a `WitnessShrinker` which - // shrinks the witness data in case the ReTyper shrank its types. - self.convert::(&mut Retyper { - inference_context: types::Context::new(), - phantom: PhantomData, - }) - .expect("type inference won't fail if it succeeded before") - } - /// Finalize the witness program as an unpruned redeem program. /// /// Witness nodes must be populated with sufficient data, @@ -250,7 +148,6 @@ impl WitnessNode { #[derive(Clone, Debug)] pub struct WitnessData { arrow: Arrow, - must_prune: bool, /// This isn't really necessary, but it helps type inference if every /// struct has a \ parameter, since it forces the choice of jets to /// be consistent without the user needing to specify it too many times. @@ -261,7 +158,6 @@ impl CoreConstructible for WitnessData { fn iden(inference_context: &types::Context) -> Self { WitnessData { arrow: Arrow::iden(inference_context), - must_prune: false, phantom: PhantomData, } } @@ -269,7 +165,6 @@ impl CoreConstructible for WitnessData { fn unit(inference_context: &types::Context) -> Self { WitnessData { arrow: Arrow::unit(inference_context), - must_prune: false, phantom: PhantomData, } } @@ -277,7 +172,6 @@ impl CoreConstructible for WitnessData { fn injl(child: &Self) -> Self { WitnessData { arrow: Arrow::injl(&child.arrow), - must_prune: child.must_prune, phantom: PhantomData, } } @@ -285,7 +179,6 @@ impl CoreConstructible for WitnessData { fn injr(child: &Self) -> Self { WitnessData { arrow: Arrow::injr(&child.arrow), - must_prune: child.must_prune, phantom: PhantomData, } } @@ -293,7 +186,6 @@ impl CoreConstructible for WitnessData { fn take(child: &Self) -> Self { WitnessData { arrow: Arrow::take(&child.arrow), - must_prune: child.must_prune, phantom: PhantomData, } } @@ -301,7 +193,6 @@ impl CoreConstructible for WitnessData { fn drop_(child: &Self) -> Self { WitnessData { arrow: Arrow::drop_(&child.arrow), - must_prune: child.must_prune, phantom: PhantomData, } } @@ -309,7 +200,6 @@ impl CoreConstructible for WitnessData { fn comp(left: &Self, right: &Self) -> Result { Ok(WitnessData { arrow: Arrow::comp(&left.arrow, &right.arrow)?, - must_prune: left.must_prune || right.must_prune, phantom: PhantomData, }) } @@ -320,7 +210,6 @@ impl CoreConstructible for WitnessData { // pruned is the case node itself pruned. Ok(WitnessData { arrow: Arrow::case(&left.arrow, &right.arrow)?, - must_prune: left.must_prune && right.must_prune, phantom: PhantomData, }) } @@ -328,7 +217,6 @@ impl CoreConstructible for WitnessData { fn assertl(left: &Self, right: Cmr) -> Result { Ok(WitnessData { arrow: Arrow::assertl(&left.arrow, right)?, - must_prune: left.must_prune, phantom: PhantomData, }) } @@ -336,7 +224,6 @@ impl CoreConstructible for WitnessData { fn assertr(left: Cmr, right: &Self) -> Result { Ok(WitnessData { arrow: Arrow::assertr(left, &right.arrow)?, - must_prune: right.must_prune, phantom: PhantomData, }) } @@ -344,7 +231,6 @@ impl CoreConstructible for WitnessData { fn pair(left: &Self, right: &Self) -> Result { Ok(WitnessData { arrow: Arrow::pair(&left.arrow, &right.arrow)?, - must_prune: left.must_prune || right.must_prune, phantom: PhantomData, }) } @@ -353,7 +239,6 @@ impl CoreConstructible for WitnessData { // Fail nodes always get pruned. WitnessData { arrow: Arrow::fail(inference_context, entropy), - must_prune: true, phantom: PhantomData, } } @@ -361,7 +246,6 @@ impl CoreConstructible for WitnessData { fn const_word(inference_context: &types::Context, word: Word) -> Self { WitnessData { arrow: Arrow::const_word(inference_context, word), - must_prune: false, phantom: PhantomData, } } @@ -376,17 +260,15 @@ impl DisconnectConstructible>>> for WitnessDat let right = right.as_ref(); Ok(WitnessData { arrow: Arrow::disconnect(&left.arrow, &right.map(|n| n.arrow()))?, - must_prune: left.must_prune || right.map(|n| n.must_prune()).unwrap_or(false), phantom: PhantomData, }) } } impl WitnessConstructible> for WitnessData { - fn witness(inference_context: &types::Context, witness: Option) -> Self { + fn witness(inference_context: &types::Context, _witness: Option) -> Self { WitnessData { arrow: Arrow::witness(inference_context, NoWitness), - must_prune: witness.is_none(), phantom: PhantomData, } } @@ -396,7 +278,6 @@ impl JetConstructible for WitnessData { fn jet(inference_context: &types::Context, jet: J) -> Self { WitnessData { arrow: Arrow::jet(inference_context, jet), - must_prune: false, phantom: PhantomData, } }