@@ -4,13 +4,18 @@ use std::collections::{HashMap, VecDeque};
44use std:: ops:: { Index , IndexMut } ;
55
66use hugr:: core:: HugrNode ;
7+ use hugr:: hugr:: hugrmut:: HugrMut ;
8+ use hugr:: ops:: handle:: NodeHandle ;
79use hugr:: ops:: { OpTag , OpTrait } ;
8- use hugr:: { Hugr , HugrView } ;
10+ use hugr:: { Hugr , HugrView , Node } ;
911use rayon:: iter:: { IntoParallelIterator , IntoParallelRefIterator , IntoParallelRefMutIterator } ;
1012use tket_json_rs:: circuit_json:: { Command as PytketCommand , SerialCircuit } ;
1113
14+ use crate :: serialize:: pytket:: decoder:: PytketDecoderContext ;
1215use crate :: serialize:: pytket:: {
13- default_encoder_config, EncodeOptions , PytketEncodeError , PytketEncoderContext ,
16+ default_decoder_config, default_encoder_config, DecodeInsertionTarget , DecodeOptions ,
17+ EncodeOptions , PytketDecodeError , PytketDecodeErrorInner , PytketEncodeError ,
18+ PytketEncoderContext ,
1419} ;
1520use crate :: Circuit ;
1621
@@ -146,6 +151,97 @@ impl<'a, H: HugrView> EncodedCircuit<'a, H> {
146151 Ok ( ( ) )
147152 }
148153
154+ /// Reassemble the encoded circuits into a new [`Hugr`], containing a
155+ /// function defining the [`Self::head_region`] and expanding any opaque
156+ /// hugrs in pytket barrier operations back into Hugr subgraphs.
157+ ///
158+ /// Functions called by the internal hugrs may be added to the hugr module
159+ /// as well.
160+ ///
161+ /// # Arguments
162+ ///
163+ /// - `fn_name`: The name of the function to create. If `None`, we will use
164+ /// the name of the circuit, or "main" if the circuit has no name.
165+ /// - `options`: The options for the decoder.
166+ ///
167+ /// # Errors
168+ ///
169+ /// Returns a [`PytketDecodeErrorInner::NonDataflowHeadRegion`] error if
170+ /// [`Self::head_region`] is not a dataflow container in the hugr.
171+ ///
172+ /// Returns an error if a circuit being decoded is invalid. See
173+ /// [`PytketDecodeErrorInner`][super::error::PytketDecodeErrorInner] for
174+ /// more details.
175+ pub fn reassemble (
176+ & self ,
177+ fn_name : Option < String > ,
178+ options : DecodeOptions < H > ,
179+ ) -> Result < Hugr , PytketDecodeError > {
180+ let mut hugr = Hugr :: new ( ) ;
181+ let main_func = self . reassemble_inline (
182+ & mut hugr,
183+ DecodeInsertionTarget :: Function { fn_name } ,
184+ options,
185+ ) ?;
186+ hugr. set_entrypoint ( main_func) ;
187+ Ok ( hugr)
188+ }
189+
190+ /// Reassemble the encoded circuits inside an existing [`Hugr`], containing
191+ /// the [`Self::head_region`] at the given insertion target.
192+ ///
193+ /// Functions called by the internal hugrs may be added to the hugr module
194+ /// as well.
195+ ///
196+ /// # Arguments
197+ ///
198+ /// - `hugr`: The [`Hugr`] to reassemble the circuits in.
199+ /// - `target`: The target to insert the function at.
200+ /// - `options`: The options for the decoder.
201+ ///
202+ /// # Errors
203+ ///
204+ /// Returns a [`PytketDecodeErrorInner::NonDataflowHeadRegion`] error if
205+ /// [`Self::head_region`] is not a dataflow container in the hugr.
206+ ///
207+ /// Returns an error if a circuit being decoded is invalid. See
208+ /// [`PytketDecodeErrorInner`][super::error::PytketDecodeErrorInner] for
209+ /// more details.
210+ pub fn reassemble_inline (
211+ & self ,
212+ hugr : & mut Hugr ,
213+ target : DecodeInsertionTarget ,
214+ options : DecodeOptions < H > ,
215+ ) -> Result < Node , PytketDecodeError > {
216+ if !self . check_dataflow_head_region ( ) {
217+ let head_op = self . hugr . get_optype ( self . head_region ) . to_string ( ) ;
218+ return Err ( PytketDecodeErrorInner :: NonDataflowHeadRegion { head_op } . wrap ( ) ) ;
219+ } ;
220+ let serial_circuit = & self [ self . head_region ] ;
221+
222+ if self . len ( ) > 1 {
223+ unimplemented ! (
224+ "Reassembling an `EncodedCircuit` with nested subcircuits is not yet implemented."
225+ ) ;
226+ } ;
227+
228+ let config = options
229+ . config
230+ . unwrap_or_else ( || default_decoder_config ( ) . into ( ) ) ;
231+
232+ let mut decoder = PytketDecoderContext :: < H > :: new (
233+ serial_circuit,
234+ hugr,
235+ target,
236+ options. signature ,
237+ options. input_params ,
238+ config,
239+ ) ?;
240+ decoder. register_unsupported_subgraphs ( & self . opaque_subgraphs , self . hugr ) ;
241+ decoder. run_decoder ( & serial_circuit. commands ) ?;
242+ Ok ( decoder. finish ( ) ?. node ( ) )
243+ }
244+
149245 /// Extract the top-level pytket circuit as a standalone definition
150246 /// containing the whole original HUGR.
151247 ///
0 commit comments