@@ -191,7 +191,10 @@ struct QuantumOp {
191191/// Check if a gate type is a rotation gate that takes angle parameters.
192192#[ must_use]
193193pub fn is_rotation_gate ( gate_type : GateType ) -> bool {
194- matches ! ( gate_type, GateType :: RX | GateType :: RY | GateType :: RZ )
194+ matches ! (
195+ gate_type,
196+ GateType :: RX | GateType :: RY | GateType :: RZ | GateType :: CRZ
197+ )
195198}
196199
197200/// Try to extract a constant numeric value from a HUGR Const node.
@@ -437,6 +440,16 @@ fn trace_back_for_const(hugr: &Hugr, node: Node, depth: usize) -> Option<(f64, b
437440 return trace_back_for_const ( hugr, src_node, depth + 1 ) ;
438441 }
439442 }
443+
444+ // Handle float negation (fneg) - used for negative rotation angles
445+ if op_name == "fneg" {
446+ let input_port = IncomingPort :: from ( 0 ) ;
447+ if let Some ( ( src_node, _) ) = hugr. single_linked_output ( node, input_port)
448+ && let Some ( ( val, is_half_turns) ) = trace_back_for_const ( hugr, src_node, depth + 1 )
449+ {
450+ return Some ( ( -val, is_half_turns) ) ;
451+ }
452+ }
440453 }
441454
442455 // For UnpackTuple, trace through
@@ -456,7 +469,8 @@ fn trace_back_for_const(hugr: &Hugr, node: Node, depth: usize) -> Option<(f64, b
456469 // 2. Numeric argument values
457470 let mut is_division = false ;
458471 let mut is_multiplication = false ;
459- let mut numeric_values: Vec < ( usize , f64 ) > = Vec :: new ( ) ;
472+ let mut is_negation = false ;
473+ let mut numeric_values: Vec < ( usize , f64 , bool ) > = Vec :: new ( ) ;
460474
461475 // Get the number of input ports for this node
462476 let num_inputs = hugr. num_inputs ( node) ;
@@ -476,19 +490,29 @@ fn trace_back_for_const(hugr: &Hugr, node: Node, depth: usize) -> Option<(f64, b
476490 if func_name. contains ( "__mul__" ) || func_name. contains ( "__rmul__" ) {
477491 is_multiplication = true ;
478492 }
493+ if func_name. contains ( "__neg__" ) {
494+ is_negation = true ;
495+ }
479496 }
480497
481498 // Try to get a numeric value from this input
482- if let Some ( ( val, _) ) = trace_back_for_const ( hugr, src_node, depth + 1 ) {
483- numeric_values. push ( ( port_idx, val) ) ;
499+ if let Some ( ( val, is_half_turns) ) = trace_back_for_const ( hugr, src_node, depth + 1 )
500+ {
501+ numeric_values. push ( ( port_idx, val, is_half_turns) ) ;
484502 }
485503 }
486504 }
487505
506+ // If this is a negation call and we have a numeric value, negate it
507+ if is_negation && !numeric_values. is_empty ( ) {
508+ let ( _, val, is_half_turns) = numeric_values[ 0 ] ;
509+ return Some ( ( -val, is_half_turns) ) ;
510+ }
511+
488512 // If this is a division call and we have two numeric values, compute the result
489513 if is_division && numeric_values. len ( ) >= 2 {
490514 // Sort by port index to get correct order (numerator first, denominator second)
491- numeric_values. sort_by_key ( |( idx, _) | * idx) ;
515+ numeric_values. sort_by_key ( |( idx, _, _ ) | * idx) ;
492516 let numerator = numeric_values[ 0 ] . 1 ;
493517 let denominator = numeric_values[ 1 ] . 1 ;
494518 if denominator != 0.0 {
@@ -498,14 +522,14 @@ fn trace_back_for_const(hugr: &Hugr, node: Node, depth: usize) -> Option<(f64, b
498522
499523 // If this is a multiplication call and we have two numeric values, compute the result
500524 if is_multiplication && numeric_values. len ( ) >= 2 {
501- numeric_values. sort_by_key ( |( idx, _) | * idx) ;
525+ numeric_values. sort_by_key ( |( idx, _, _ ) | * idx) ;
502526 let factor1 = numeric_values[ 0 ] . 1 ;
503527 let factor2 = numeric_values[ 1 ] . 1 ;
504528 return Some ( ( factor1 * factor2, false ) ) ;
505529 }
506530
507531 // For other calls, try to return the first numeric value found
508- if let Some ( ( _, val) ) = numeric_values. first ( ) {
532+ if let Some ( ( _, val, _ ) ) = numeric_values. first ( ) {
509533 return Some ( ( * val, false ) ) ;
510534 }
511535 }
0 commit comments