11use std:: sync:: Arc ;
22
33use simplicity:: dag:: { InternalSharing , PostOrderIterItem } ;
4- use simplicity:: jet:: { Elements , Jet } ;
4+ use simplicity:: jet:: Jet ;
55use simplicity:: node:: {
6- self , CommitData , ConstructData as WitnessData , Constructible , Converter , CoreConstructible ,
7- Inner , JetConstructible , NoDisconnect , NoWitness , Node , WitnessConstructible ,
6+ self , Converter , CoreConstructible , Inner , NoDisconnect , NoWitness , Node , WitnessConstructible ,
87} ;
9- use simplicity:: types:: arrow:: Arrow ;
10- use simplicity:: { types, CommitNode , FailEntropy } ;
11- use simplicity:: { Cmr , ConstructNode as WitnessNode } ;
8+ use simplicity:: Cmr ;
9+ use simplicity:: { types, FailEntropy } ;
1210
1311use crate :: str:: WitnessName ;
1412use crate :: value:: StructuralValue ;
1513use crate :: witness:: WitnessValues ;
1614
17- /// Marker for [`ConstructNode`].
1815#[ derive( Copy , Clone , PartialEq , Eq , PartialOrd , Ord , Debug , Hash ) ]
19- pub struct Construct < N > {
20- /// Makes the type non-constructible.
21- never : std:: convert:: Infallible ,
22- /// Required by Rust.
23- phantom : std:: marker:: PhantomData < N > ,
24- }
25-
26- /// Sharing ID of [`ConstructNode`].
27- /// Cannot be constructed because there is no sharing.
28- #[ derive( Copy , Clone , PartialEq , Eq , PartialOrd , Ord , Debug , Hash ) ]
29- pub enum ConstructId { }
16+ pub struct WithNames < T > ( T ) ;
3017
31- impl < J : Jet > node:: Marker for Construct < J > {
32- type CachedData = ConstructData < J > ;
18+ impl < M : node :: Marker > node:: Marker for WithNames < M > {
19+ type CachedData = M :: CachedData ;
3320 type Witness = WitnessName ;
21+ // It's quite difficult to wrap M::Disconnect because of Rust's lack of HKTs, and
22+ // we don't use disconnect in this library right now, so punt on it for now.
3423 type Disconnect = NoDisconnect ;
35- type SharingId = ConstructId ;
36- type Jet = J ;
24+ type SharingId = M :: SharingId ;
25+ type Jet = M :: Jet ;
26+
27+ fn compute_sharing_id ( cmr : Cmr , cached_data : & Self :: CachedData ) -> Option < Self :: SharingId > {
28+ M :: compute_sharing_id ( cmr, cached_data)
29+ }
30+ }
31+
32+ /// Helper trait so we can abstract over witness and disconnects of any type,
33+ /// as long as we can produce them from a no-witness no-disconnect object.
34+ pub trait Nullable {
35+ fn none ( ) -> Self ;
36+ }
3737
38- fn compute_sharing_id ( _: Cmr , _cached_data : & Self :: CachedData ) -> Option < Self :: SharingId > {
38+ impl < T > Nullable for Option < T > {
39+ fn none ( ) -> Self {
3940 None
4041 }
4142}
4243
44+ impl Nullable for NoWitness {
45+ fn none ( ) -> Self {
46+ NoWitness
47+ }
48+ }
49+
50+ impl Nullable for NoDisconnect {
51+ fn none ( ) -> Self {
52+ NoDisconnect
53+ }
54+ }
55+
4356/// [`simplicity::ConstructNode`] with named witness nodes.
4457///
4558/// Nodes other than witness don't have names.
46- pub type ConstructNode = Node < Construct < Elements > > ;
59+ pub type ConstructNode < J > = Node < WithNames < node:: Construct < J > > > ;
60+
61+ /// [`simplicity::CommitNode`] with named witness nodes.
62+ ///
63+ /// Nodes other than witness don't have names.
64+ pub type CommitNode < J > = Node < WithNames < node:: Commit < J > > > ;
4765
4866// FIXME: The following methods cannot be implemented for simplicity::node::Node because that is a foreign type
4967
5068/// Convert [`ConstructNode`] into [`CommitNode`] by dropping the name of witness nodes.
51- pub fn to_commit_node ( node : & ConstructNode ) -> Result < Arc < CommitNode < Elements > > , types:: Error > {
69+ pub fn forget_names < M > ( node : & Node < WithNames < M > > ) -> Arc < Node < M > >
70+ where
71+ M : node:: Marker ,
72+ M :: Disconnect : Nullable ,
73+ M :: Witness : Nullable ,
74+ {
5275 struct Forgetter ;
5376
54- impl < J : Jet > Converter < Construct < J > , node:: Commit < J > > for Forgetter {
55- type Error = types:: Error ;
77+ impl < M > Converter < WithNames < M > , M > for Forgetter
78+ where
79+ M : node:: Marker ,
80+ M :: Disconnect : Nullable ,
81+ M :: Witness : Nullable ,
82+ {
83+ type Error = core:: convert:: Infallible ;
5684
5785 fn convert_witness (
5886 & mut self ,
59- _: & PostOrderIterItem < & Node < Construct < J > > > ,
87+ _: & PostOrderIterItem < & Node < WithNames < M > > > ,
6088 _: & WitnessName ,
61- ) -> Result < NoWitness , Self :: Error > {
62- Ok ( NoWitness )
89+ ) -> Result < M :: Witness , Self :: Error > {
90+ Ok ( M :: Witness :: none ( ) )
6391 }
6492
6593 fn convert_disconnect (
6694 & mut self ,
67- _: & PostOrderIterItem < & Node < Construct < J > > > ,
68- _: Option < & Arc < CommitNode < J > > > ,
95+ _: & PostOrderIterItem < & Node < WithNames < M > > > ,
96+ _: Option < & Arc < Node < M > > > ,
6997 _: & NoDisconnect ,
70- ) -> Result < NoDisconnect , Self :: Error > {
71- Ok ( NoDisconnect )
98+ ) -> Result < M :: Disconnect , Self :: Error > {
99+ Ok ( M :: Disconnect :: none ( ) )
72100 }
73101
74102 fn convert_data (
75103 & mut self ,
76- data : & PostOrderIterItem < & Node < Construct < J > > > ,
77- inner : Inner < & Arc < CommitNode < J > > , J , & NoDisconnect , & NoWitness > ,
78- ) -> Result < Arc < CommitData < J > > , Self :: Error > {
79- let arrow = data. node . cached_data ( ) . arrow ( ) ;
80- let inner = inner. map ( Arc :: as_ref) . map ( CommitNode :: < J > :: cached_data) ;
81- CommitData :: new ( arrow, inner) . map ( Arc :: new)
104+ data : & PostOrderIterItem < & Node < WithNames < M > > > ,
105+ _: Inner < & Arc < Node < M > > , M :: Jet , & M :: Disconnect , & M :: Witness > ,
106+ ) -> Result < M :: CachedData , Self :: Error > {
107+ Ok ( data. node . cached_data ( ) . clone ( ) )
82108 }
83109 }
84110
85- node. convert :: < InternalSharing , _ , _ > ( & mut Forgetter )
111+ match node. convert :: < InternalSharing , _ , _ > ( & mut Forgetter ) {
112+ Ok ( ret) => ret,
113+ Err ( inf) => match inf { } ,
114+ }
86115}
87116
88- /// Convert [`ConstructNode`] into [`WitnessNode`] by populating witness nodes with their assigned values.
117+ /// Converts a named [`ConstructNode`] into a standard [`node::ConstructNode`], by populating
118+ /// witness nodes with their assigned values.
89119///
90120/// Each witness node has a name. If there is no value assigned to this name,
91121/// then the node is left empty.
92122///
93- /// When [`WitnessNode `] is finalized to [`node::RedeemNode`], there will be an error if any witness
123+ /// When [`node::ConstructNode `] is finalized to [`node::RedeemNode`], there will be an error if any witness
94124/// node on a used (unpruned) branch is empty. It is the responsibility of the caller to ensure that
95125/// all used witness nodes have an assigned value.
96126///
@@ -99,18 +129,20 @@ pub fn to_commit_node(node: &ConstructNode) -> Result<Arc<CommitNode<Elements>>,
99129/// It is the responsibility of the caller to ensure that the given witness `values` match the
100130/// types in the construct `node`. This can be done by calling [`WitnessValues::is_consistent`]
101131/// on the original SimplicityHL program before it is compiled to Simplicity.
102- pub fn to_witness_node ( node : & ConstructNode , values : WitnessValues ) -> Arc < WitnessNode < Elements > > {
132+ pub fn populate_witnesses < J : Jet > (
133+ node : & ConstructNode < J > ,
134+ values : WitnessValues ,
135+ ) -> Arc < node:: ConstructNode < J > > {
103136 struct Populator {
104137 values : WitnessValues ,
105- inference_context : types:: Context ,
106138 }
107139
108- impl < J : Jet > Converter < Construct < J > , node:: Construct < J > > for Populator {
109- type Error = ( ) ;
140+ impl < J : Jet > Converter < WithNames < node :: Construct < J > > , node:: Construct < J > > for Populator {
141+ type Error = core :: convert :: Infallible ;
110142
111143 fn convert_witness (
112144 & mut self ,
113- _: & PostOrderIterItem < & Node < Construct < J > > > ,
145+ _: & PostOrderIterItem < & ConstructNode < J > > ,
114146 witness : & WitnessName ,
115147 ) -> Result < Option < simplicity:: Value > , Self :: Error > {
116148 let maybe_value = self
@@ -123,129 +155,40 @@ pub fn to_witness_node(node: &ConstructNode, values: WitnessValues) -> Arc<Witne
123155
124156 fn convert_disconnect (
125157 & mut self ,
126- _: & PostOrderIterItem < & Node < Construct < J > > > ,
127- _: Option < & Arc < WitnessNode < J > > > ,
158+ _: & PostOrderIterItem < & ConstructNode < J > > ,
159+ _: Option < & Arc < node :: ConstructNode < J > > > ,
128160 _: & NoDisconnect ,
129- ) -> Result < Option < Arc < WitnessNode < J > > > , Self :: Error > {
161+ ) -> Result < Option < Arc < node :: ConstructNode < J > > > , Self :: Error > {
130162 Ok ( None )
131163 }
132164
133165 fn convert_data (
134166 & mut self ,
135- _ : & PostOrderIterItem < & Node < Construct < J > > > ,
136- inner : Inner <
137- & Arc < WitnessNode < J > > ,
167+ data : & PostOrderIterItem < & ConstructNode < J > > ,
168+ _ : Inner <
169+ & Arc < node :: ConstructNode < J > > ,
138170 J ,
139- & Option < Arc < WitnessNode < J > > > ,
171+ & Option < Arc < node :: ConstructNode < J > > > ,
140172 & Option < simplicity:: Value > ,
141173 > ,
142- ) -> Result < WitnessData < J > , Self :: Error > {
143- let inner = inner
144- . map ( Arc :: as_ref)
145- . map ( WitnessNode :: < J > :: cached_data)
146- . map_witness ( Option :: < simplicity:: Value > :: clone) ;
147- Ok ( WitnessData :: from_inner ( & self . inference_context , inner) . unwrap ( ) )
148- }
149- }
150-
151- let mut populator = Populator {
152- inference_context : types:: Context :: new ( ) ,
153- values,
154- } ;
155- node. convert :: < InternalSharing , _ , _ > ( & mut populator)
156- . unwrap ( )
157- }
158-
159- /// Copy of [`node::ConstructData`] with an implementation of [`WitnessConstructible<WitnessName>`].
160- #[ derive( Clone , Debug ) ]
161- pub struct ConstructData < J > {
162- arrow : Arrow ,
163- phantom : std:: marker:: PhantomData < J > ,
164- }
165-
166- impl < J > ConstructData < J > {
167- /// Access the arrow of the node.
168- pub fn arrow ( & self ) -> & Arrow {
169- & self . arrow
170- }
171- }
172-
173- impl < J > From < Arrow > for ConstructData < J > {
174- fn from ( arrow : Arrow ) -> Self {
175- Self {
176- arrow,
177- phantom : std:: marker:: PhantomData ,
174+ ) -> Result < node:: ConstructData < J > , Self :: Error > {
175+ Ok ( data. node . cached_data ( ) . clone ( ) )
178176 }
179177 }
180- }
181-
182- impl < J > CoreConstructible for ConstructData < J > {
183- fn iden ( inference_context : & types:: Context ) -> Self {
184- Arrow :: iden ( inference_context) . into ( )
185- }
186-
187- fn unit ( inference_context : & types:: Context ) -> Self {
188- Arrow :: unit ( inference_context) . into ( )
189- }
190-
191- fn injl ( child : & Self ) -> Self {
192- Arrow :: injl ( & child. arrow ) . into ( )
193- }
194-
195- fn injr ( child : & Self ) -> Self {
196- Arrow :: injr ( & child. arrow ) . into ( )
197- }
198-
199- fn take ( child : & Self ) -> Self {
200- Arrow :: take ( & child. arrow ) . into ( )
201- }
202-
203- fn drop_ ( child : & Self ) -> Self {
204- Arrow :: drop_ ( & child. arrow ) . into ( )
205- }
206-
207- fn comp ( left : & Self , right : & Self ) -> Result < Self , types:: Error > {
208- Arrow :: comp ( & left. arrow , & right. arrow ) . map ( Self :: from)
209- }
210-
211- fn case ( left : & Self , right : & Self ) -> Result < Self , types:: Error > {
212- Arrow :: case ( & left. arrow , & right. arrow ) . map ( Self :: from)
213- }
214-
215- fn assertl ( left : & Self , right : Cmr ) -> Result < Self , types:: Error > {
216- Arrow :: assertl ( & left. arrow , right) . map ( Self :: from)
217- }
218-
219- fn assertr ( left : Cmr , right : & Self ) -> Result < Self , types:: Error > {
220- Arrow :: assertr ( left, & right. arrow ) . map ( Self :: from)
221- }
222-
223- fn pair ( left : & Self , right : & Self ) -> Result < Self , types:: Error > {
224- Arrow :: pair ( & left. arrow , & right. arrow ) . map ( Self :: from)
225- }
226-
227- fn fail ( inference_context : & types:: Context , entropy : FailEntropy ) -> Self {
228- Arrow :: fail ( inference_context, entropy) . into ( )
229- }
230-
231- fn const_word ( inference_context : & types:: Context , word : simplicity:: Word ) -> Self {
232- Arrow :: const_word ( inference_context, word) . into ( )
233- }
234-
235- fn inference_context ( & self ) -> & types:: Context {
236- self . arrow . inference_context ( )
237- }
238- }
239178
240- impl < J : Jet > JetConstructible < J > for ConstructData < J > {
241- fn jet ( inference_context : & types:: Context , jet : J ) -> Self {
242- Arrow :: jet ( inference_context, jet) . into ( )
179+ let mut populator = Populator { values } ;
180+ match node. convert :: < InternalSharing , _ , _ > ( & mut populator) {
181+ Ok ( ret) => ret,
182+ Err ( inf) => match inf { } ,
243183 }
244184}
245185
246- impl < J > WitnessConstructible < WitnessName > for ConstructData < J > {
186+ // This awkward construction is required by rust-simplicity to implement WitnessConstructible
187+ // for Node<WithNames<Construct>>. See
188+ // https://docs.rs/simplicity-lang/latest/simplicity/node/trait.WitnessConstructible.html#foreign-impls
189+ impl < J : Jet > WitnessConstructible < WitnessName > for node:: ConstructData < J > {
247190 fn witness ( inference_context : & types:: Context , _: WitnessName ) -> Self {
248- Arrow :: witness ( inference_context, ( ) ) . into ( )
191+ WitnessConstructible :: < Option < _ > > :: witness ( inference_context, None )
249192 }
250193}
251194
0 commit comments