From 74831038e0c6a5def78a4849b3834b18913b7f8b Mon Sep 17 00:00:00 2001 From: Lukas Heidemann Date: Tue, 21 Jan 2025 12:04:36 +0000 Subject: [PATCH] feat: Special cased array, float and int constants in hugr-model export (#1857) This PR special cases the import/export of array, float and int constants so that they are represented as terms in `hugr-model`. This representation is a lot more efficient to handle than the encoding as JSON. In the future we should do this for all constants. --- hugr-core/src/export.rs | 44 ++++++++++++ hugr-core/src/import.rs | 71 ++++++++++++++++++- .../std_extensions/arithmetic/float_types.rs | 3 + .../std_extensions/arithmetic/int_types.rs | 3 + .../src/std_extensions/collections/array.rs | 3 + .../snapshots/model__roundtrip_const.snap | 43 ++++++----- hugr-model/Cargo.toml | 1 + hugr-model/capnp/hugr-v0.capnp | 2 + hugr-model/src/v0/binary/read.rs | 5 ++ hugr-model/src/v0/binary/write.rs | 2 + hugr-model/src/v0/mod.rs | 10 +++ hugr-model/src/v0/text/hugr.pest | 57 ++++++++------- hugr-model/src/v0/text/parse.rs | 11 ++- hugr-model/src/v0/text/print.rs | 9 +++ hugr-model/tests/fixtures/model-const.edn | 31 +++++--- hugr-model/tests/fixtures/model-literals.edn | 1 + .../tests/snapshots/text__literals.snap | 2 + 17 files changed, 244 insertions(+), 54 deletions(-) diff --git a/hugr-core/src/export.rs b/hugr-core/src/export.rs index 645a7a0e6..dc5093f4c 100644 --- a/hugr-core/src/export.rs +++ b/hugr-core/src/export.rs @@ -3,6 +3,10 @@ use crate::{ extension::{ExtensionId, ExtensionSet, OpDef, SignatureFunc}, hugr::{IdentList, NodeMetadataMap}, ops::{constant::CustomSerialized, DataflowBlock, OpName, OpTrait, OpType, Value}, + std_extensions::{ + arithmetic::{float_types::ConstF64, int_types::ConstInt}, + collections::array::ArrayValue, + }, types::{ type_param::{TypeArgVariable, TypeParam}, type_row::TypeRowBase, @@ -1018,6 +1022,46 @@ impl<'a> Context<'a> { fn export_value(&mut self, value: &'a Value) -> model::TermId { match value { Value::Extension { e } => { + // NOTE: We have special cased arrays, integers, and floats for now. + // TODO: Allow arbitrary extension values to be exported as terms. + + if let Some(array) = e.value().downcast_ref::() { + let len = self.make_term(model::Term::Nat(array.get_contents().len() as u64)); + let element_type = self.export_type(array.get_element_type()); + let mut contents = + BumpVec::with_capacity_in(array.get_contents().len(), self.bump); + + for element in array.get_contents() { + contents.push(model::ListPart::Item(self.export_value(element))); + } + + let contents = self.make_term(model::Term::List { + parts: contents.into_bump_slice(), + }); + + let symbol = self.resolve_symbol(ArrayValue::CTR_NAME); + let args = self.bump.alloc_slice_copy(&[len, element_type, contents]); + return self.make_term(model::Term::ApplyFull { symbol, args }); + } + + if let Some(v) = e.value().downcast_ref::() { + let bitwidth = self.make_term(model::Term::Nat(v.log_width() as u64)); + let literal = self.make_term(model::Term::Nat(v.value_u())); + + let symbol = self.resolve_symbol(ConstInt::CTR_NAME); + let args = self.bump.alloc_slice_copy(&[bitwidth, literal]); + return self.make_term(model::Term::ApplyFull { symbol, args }); + } + + if let Some(v) = e.value().downcast_ref::() { + let literal = self.make_term(model::Term::Float { + value: v.value().into(), + }); + let symbol = self.resolve_symbol(ConstF64::CTR_NAME); + let args = self.bump.alloc_slice_copy(&[literal]); + return self.make_term(model::Term::ApplyFull { symbol, args }); + } + let json = match e.value().downcast_ref::() { Some(custom) => serde_json::to_string(custom.value()).unwrap(), None => serde_json::to_string(e.value()) diff --git a/hugr-core/src/import.rs b/hugr-core/src/import.rs index f542ac695..4b1e8a447 100644 --- a/hugr-core/src/import.rs +++ b/hugr-core/src/import.rs @@ -15,6 +15,10 @@ use crate::{ ExitBlock, FuncDecl, FuncDefn, Input, LoadConstant, LoadFunction, Module, OpType, OpaqueOp, Output, Tag, TailLoop, Value, CFG, DFG, }, + std_extensions::{ + arithmetic::{float_types::ConstF64, int_types::ConstInt}, + collections::array::ArrayValue, + }, types::{ type_param::TypeParam, type_row::TypeRowBase, CustomType, FuncTypeBase, MaybeRV, PolyFuncType, PolyFuncTypeBase, RowVariable, Signature, Type, TypeArg, TypeBase, TypeBound, @@ -922,6 +926,7 @@ impl<'a> Context<'a> { model::Term::Apply { .. } => Err(error_unsupported!("custom type as `TypeParam`")), model::Term::ApplyFull { .. } => Err(error_unsupported!("custom type as `TypeParam`")), model::Term::BytesType { .. } => Err(error_unsupported!("`bytes` as `TypeParam`")), + model::Term::FloatType { .. } => Err(error_unsupported!("`float` as `TypeParam`")), model::Term::Const { .. } => Err(error_unsupported!("`(const ...)` as `TypeParam`")), model::Term::FuncType { .. } => Err(error_unsupported!("`(fn ...)` as `TypeParam`")), @@ -947,6 +952,7 @@ impl<'a> Context<'a> { | model::Term::ConstFunc { .. } | model::Term::Bytes { .. } | model::Term::Meta + | model::Term::Float { .. } | model::Term::ConstAdt { .. } => Err(model::ModelError::TypeError(term_id).into()), model::Term::ControlType => { @@ -1000,8 +1006,10 @@ impl<'a> Context<'a> { model::Term::StaticType => Err(error_unsupported!("`static` as `TypeArg`")), model::Term::ControlType => Err(error_unsupported!("`ctrl` as `TypeArg`")), model::Term::BytesType => Err(error_unsupported!("`bytes` as `TypeArg`")), + model::Term::FloatType => Err(error_unsupported!("`float` as `TypeArg`")), model::Term::Bytes { .. } => Err(error_unsupported!("`(bytes ..)` as `TypeArg`")), model::Term::Const { .. } => Err(error_unsupported!("`const` as `TypeArg`")), + model::Term::Float { .. } => Err(error_unsupported!("float literal as `TypeArg`")), model::Term::ConstAdt { .. } => Err(error_unsupported!("adt constant as `TypeArg`")), model::Term::ConstFunc { .. } => { Err(error_unsupported!("function constant as `TypeArg`")) @@ -1136,6 +1144,8 @@ impl<'a> Context<'a> { | model::Term::NonLinearConstraint { .. } | model::Term::Bytes { .. } | model::Term::BytesType + | model::Term::FloatType + | model::Term::Float { .. } | model::Term::ConstFunc { .. } | model::Term::Meta | model::Term::ConstAdt { .. } => Err(model::ModelError::TypeError(term_id).into()), @@ -1356,7 +1366,64 @@ impl<'a> Context<'a> { } } - Err(error_unsupported!("constant value that is not JSON data")) + // NOTE: We have special cased arrays, integers, and floats for now. + // TODO: Allow arbitrary extension values to be imported from terms. + + if symbol_name == ArrayValue::CTR_NAME { + let element_type_term = + args.get(1).ok_or(model::ModelError::TypeError(term_id))?; + let element_type = self.import_type(*element_type_term)?; + + let contents = { + let contents = args.get(2).ok_or(model::ModelError::TypeError(term_id))?; + let contents = self.import_closed_list(*contents)?; + contents + .iter() + .map(|item| self.import_value(*item, *element_type_term)) + .collect::, _>>()? + }; + + return Ok(ArrayValue::new(element_type, contents).into()); + } + + if symbol_name == ConstInt::CTR_NAME { + let bitwidth = { + let bitwidth = args.first().ok_or(model::ModelError::TypeError(term_id))?; + let model::Term::Nat(bitwidth) = self.get_term(*bitwidth)? else { + return Err(model::ModelError::TypeError(term_id).into()); + }; + if *bitwidth > 6 { + return Err(model::ModelError::TypeError(term_id).into()); + } + *bitwidth as u8 + }; + + let value = { + let value = args.get(1).ok_or(model::ModelError::TypeError(term_id))?; + let model::Term::Nat(value) = self.get_term(*value)? else { + return Err(model::ModelError::TypeError(term_id).into()); + }; + *value + }; + + return Ok(ConstInt::new_u(bitwidth, value) + .map_err(|_| model::ModelError::TypeError(term_id))? + .into()); + } + + if symbol_name == ConstF64::CTR_NAME { + let value = { + let value = args.first().ok_or(model::ModelError::TypeError(term_id))?; + let model::Term::Float { value } = self.get_term(*value)? else { + return Err(model::ModelError::TypeError(term_id).into()); + }; + value.into_inner() + }; + + return Ok(ConstF64::new(value).into()); + } + + Err(error_unsupported!("unknown custom constant value")) // TODO: This should ultimately include the following cases: // - function definitions // - custom constructors for values @@ -1381,6 +1448,8 @@ impl<'a> Context<'a> { | model::Term::Bytes { .. } | model::Term::BytesType | model::Term::Meta + | model::Term::Float { .. } + | model::Term::FloatType | model::Term::NonLinearConstraint { .. } => { Err(model::ModelError::TypeError(term_id).into()) } diff --git a/hugr-core/src/std_extensions/arithmetic/float_types.rs b/hugr-core/src/std_extensions/arithmetic/float_types.rs index c5ffa5d6c..304b94045 100644 --- a/hugr-core/src/std_extensions/arithmetic/float_types.rs +++ b/hugr-core/src/std_extensions/arithmetic/float_types.rs @@ -64,6 +64,9 @@ impl std::ops::Deref for ConstF64 { } impl ConstF64 { + /// Name of the constructor for creating constant 64bit floats. + pub(crate) const CTR_NAME: &'static str = "arithmetic.float.const-f64"; + /// Create a new [`ConstF64`] pub fn new(value: f64) -> Self { // This function can't be `const` because `is_finite()` is not yet stable as a const function. diff --git a/hugr-core/src/std_extensions/arithmetic/int_types.rs b/hugr-core/src/std_extensions/arithmetic/int_types.rs index 88ee9d154..1342dd932 100644 --- a/hugr-core/src/std_extensions/arithmetic/int_types.rs +++ b/hugr-core/src/std_extensions/arithmetic/int_types.rs @@ -104,6 +104,9 @@ pub struct ConstInt { } impl ConstInt { + /// Name of the constructor for creating constant integers. + pub(crate) const CTR_NAME: &'static str = "arithmetic.int.const"; + /// Create a new [`ConstInt`] with a given width and unsigned value pub fn new_u(log_width: u8, value: u64) -> Result { if !is_valid_log_width(log_width) { diff --git a/hugr-core/src/std_extensions/collections/array.rs b/hugr-core/src/std_extensions/collections/array.rs index c1ccfe57e..618bd6182 100644 --- a/hugr-core/src/std_extensions/collections/array.rs +++ b/hugr-core/src/std_extensions/collections/array.rs @@ -42,6 +42,9 @@ pub struct ArrayValue { } impl ArrayValue { + /// Name of the constructor for creating constant arrays. + pub(crate) const CTR_NAME: &'static str = "collections.array.const"; + /// Create a new [CustomConst] for an array of values of type `typ`. /// That all values are of type `typ` is not checked here. pub fn new(typ: Type, contents: impl IntoIterator) -> Self { diff --git a/hugr-core/tests/snapshots/model__roundtrip_const.snap b/hugr-core/tests/snapshots/model__roundtrip_const.snap index 2b934fb46..78630ea50 100644 --- a/hugr-core/tests/snapshots/model__roundtrip_const.snap +++ b/hugr-core/tests/snapshots/model__roundtrip_const.snap @@ -4,10 +4,20 @@ expression: "roundtrip(include_str!(\"../../hugr-model/tests/fixtures/model-cons --- (hugr 0) +(import collections.array.array) + +(import collections.array.const) + (import compat.const-json) (import arithmetic.float.types.float64) +(import arithmetic.int.const) + +(import arithmetic.int.types.int) + +(import arithmetic.float.const-f64) + (define-func example.bools [] [(adt [[] []]) (adt [[] []])] (ext) (dfg @@ -19,7 +29,8 @@ expression: "roundtrip(include_str!(\"../../hugr-model/tests/fixtures/model-cons (define-func example.make-pair [] [(adt - [[(@ arithmetic.float.types.float64) (@ arithmetic.float.types.float64)]])] + [[(@ collections.array.array 5 (@ arithmetic.int.types.int 6)) + (@ arithmetic.float.types.float64)]])] (ext) (dfg [] [%0] @@ -27,32 +38,32 @@ expression: "roundtrip(include_str!(\"../../hugr-model/tests/fixtures/model-cons (-> [] [(adt - [[(@ arithmetic.float.types.float64) + [[(@ collections.array.array 5 (@ arithmetic.int.types.int 6)) (@ arithmetic.float.types.float64)]])] (ext))) (const (tag 0 [(@ - compat.const-json - (@ arithmetic.float.types.float64) - "{\"c\":\"ConstF64\",\"v\":{\"value\":2.0}}" - (ext arithmetic.float.types)) - (@ - compat.const-json - (@ arithmetic.float.types.float64) - "{\"c\":\"ConstF64\",\"v\":{\"value\":3.0}}" - (ext arithmetic.float.types))]) + collections.array.const + 5 + (@ arithmetic.int.types.int 6) + [(@ arithmetic.int.const 6 1) + (@ arithmetic.int.const 6 2) + (@ arithmetic.int.const 6 3) + (@ arithmetic.int.const 6 4) + (@ arithmetic.int.const 6 5)]) + (@ arithmetic.float.const-f64 -3.0)]) [] [%0] (signature (-> [] [(adt - [[(@ arithmetic.float.types.float64) + [[(@ collections.array.array 5 (@ arithmetic.int.types.int 6)) (@ arithmetic.float.types.float64)]])] (ext)))))) -(define-func example.f64 +(define-func example.f64-json [] [(@ arithmetic.float.types.float64)] (ext) (dfg [] [%0 %1] @@ -62,11 +73,7 @@ expression: "roundtrip(include_str!(\"../../hugr-model/tests/fixtures/model-cons [(@ arithmetic.float.types.float64) (@ arithmetic.float.types.float64)] (ext))) (const - (@ - compat.const-json - (@ arithmetic.float.types.float64) - "{\"c\":\"ConstF64\",\"v\":{\"value\":1.0}}" - (ext arithmetic.float.types)) + (@ arithmetic.float.const-f64 1.0) [] [%0] (signature (-> [] [(@ arithmetic.float.types.float64)] (ext)))) (const diff --git a/hugr-model/Cargo.toml b/hugr-model/Cargo.toml index ca333b7b1..33968ffcc 100644 --- a/hugr-model/Cargo.toml +++ b/hugr-model/Cargo.toml @@ -22,6 +22,7 @@ capnp = "0.20.1" derive_more = { version = "1.0.0", features = ["display"] } fxhash.workspace = true indexmap.workspace = true +ordered-float = "4.6.0" pest = "2.7.12" pest_derive = "2.7.12" pretty = "0.12.3" diff --git a/hugr-model/capnp/hugr-v0.capnp b/hugr-model/capnp/hugr-v0.capnp index 23d356791..2bbff0f1b 100644 --- a/hugr-model/capnp/hugr-v0.capnp +++ b/hugr-model/capnp/hugr-v0.capnp @@ -155,6 +155,8 @@ struct Term { bytes @24 :Data; bytesType @25 :Void; meta @26 :Void; + float @27 :Float64; + floatType @28 :Void; } struct Apply { diff --git a/hugr-model/src/v0/binary/read.rs b/hugr-model/src/v0/binary/read.rs index 8f0c9a50d..9118e3799 100644 --- a/hugr-model/src/v0/binary/read.rs +++ b/hugr-model/src/v0/binary/read.rs @@ -341,6 +341,11 @@ fn read_term<'a>(bump: &'a Bump, reader: hugr_capnp::term::Reader) -> ReadResult data: bump.alloc_slice_copy(bytes?), }, Which::BytesType(()) => model::Term::BytesType, + + Which::Float(value) => model::Term::Float { + value: value.into(), + }, + Which::FloatType(()) => model::Term::FloatType, }) } diff --git a/hugr-model/src/v0/binary/write.rs b/hugr-model/src/v0/binary/write.rs index 74dc763ab..b753807a2 100644 --- a/hugr-model/src/v0/binary/write.rs +++ b/hugr-model/src/v0/binary/write.rs @@ -224,6 +224,8 @@ fn write_term(mut builder: hugr_capnp::term::Builder, term: &model::Term) { model::Term::Meta => { builder.set_meta(()); } + model::Term::Float { value } => builder.set_float(value.into_inner()), + model::Term::FloatType => builder.set_float_type(()), } } diff --git a/hugr-model/src/v0/mod.rs b/hugr-model/src/v0/mod.rs index 32d79f7dc..c7748aaf2 100644 --- a/hugr-model/src/v0/mod.rs +++ b/hugr-model/src/v0/mod.rs @@ -87,6 +87,7 @@ //! [#1546]: https://github.com/CQCL/hugr/issues/1546 //! [#1553]: https://github.com/CQCL/hugr/issues/1553 //! [#1554]: https://github.com/CQCL/hugr/issues/1554 +use ordered_float::OrderedFloat; use smol_str::SmolStr; use thiserror::Error; @@ -718,6 +719,15 @@ pub enum Term<'a> { /// The type of metadata. Meta, + + /// A literal floating-point number. + Float { + /// The value of the floating-point number. + value: OrderedFloat, + }, + + /// The type of floating-point numbers. + FloatType, } /// A part of a list term. diff --git a/hugr-model/src/v0/text/hugr.pest b/hugr-model/src/v0/text/hugr.pest index 57229bce2..60e86d613 100644 --- a/hugr-model/src/v0/text/hugr.pest +++ b/hugr-model/src/v0/text/hugr.pest @@ -86,6 +86,7 @@ term = { | term_list_type | term_str | term_str_type + | term_float | term_nat | term_nat_type | term_ext_set @@ -102,33 +103,37 @@ term = { | term_bytes_type | term_bytes | term_meta + | term_float + | term_float_type } -term_wildcard = { "_" } -term_type = { "type" } -term_static = { "static" } -term_constraint = { "constraint" } -term_var = { "?" ~ identifier } -term_apply_full = { ("(" ~ "@" ~ symbol ~ term* ~ ")") } -term_apply = { symbol | ("(" ~ symbol ~ term* ~ ")") } -term_const = { "(" ~ "const" ~ term ~ term ~ ")" } -term_list = { "[" ~ (spliced_term | term)* ~ "]" } -term_list_type = { "(" ~ "list" ~ term ~ ")" } -term_str = { string } -term_str_type = { "str" } -term_nat = { (ASCII_DIGIT)+ } -term_nat_type = { "nat" } -term_ext_set = { "(" ~ "ext" ~ (spliced_term | ext_name)* ~ ")" } -term_ext_set_type = { "ext-set" } -term_adt = { "(" ~ "adt" ~ term ~ ")" } -term_func_type = { "(" ~ "->" ~ term ~ term ~ term ~ ")" } -term_ctrl = { "(" ~ "ctrl" ~ term ~ ")" } -term_ctrl_type = { "ctrl" } -term_non_linear = { "(" ~ "nonlinear" ~ term ~ ")" } -term_const_func = { "(" ~ "fn" ~ term ~ ")" } -term_const_adt = { "(" ~ "tag" ~ tag ~ term* ~ ")" } -term_bytes_type = { "bytes" } -term_bytes = { "(" ~ "bytes" ~ base64_string ~ ")" } -term_meta = { "meta" } +term_wildcard = { "_" } +term_type = { "type" } +term_static = { "static" } +term_constraint = { "constraint" } +term_var = { "?" ~ identifier } +term_apply_full = { ("(" ~ "@" ~ symbol ~ term* ~ ")") } +term_apply = { symbol | ("(" ~ symbol ~ term* ~ ")") } +term_const = { "(" ~ "const" ~ term ~ term ~ ")" } +term_list = { "[" ~ (spliced_term | term)* ~ "]" } +term_list_type = { "(" ~ "list" ~ term ~ ")" } +term_str = { string } +term_str_type = { "str" } +term_nat = @{ (ASCII_DIGIT)+ } +term_nat_type = { "nat" } +term_ext_set = { "(" ~ "ext" ~ (spliced_term | ext_name)* ~ ")" } +term_ext_set_type = { "ext-set" } +term_adt = { "(" ~ "adt" ~ term ~ ")" } +term_func_type = { "(" ~ "->" ~ term ~ term ~ term ~ ")" } +term_ctrl = { "(" ~ "ctrl" ~ term ~ ")" } +term_ctrl_type = { "ctrl" } +term_non_linear = { "(" ~ "nonlinear" ~ term ~ ")" } +term_const_func = { "(" ~ "fn" ~ term ~ ")" } +term_const_adt = { "(" ~ "tag" ~ tag ~ term* ~ ")" } +term_bytes_type = { "bytes" } +term_bytes = { "(" ~ "bytes" ~ base64_string ~ ")" } +term_meta = { "meta" } +term_float_type = { "float" } +term_float = @{ ("+" | "-")? ~ (ASCII_DIGIT)+ ~ "." ~ (ASCII_DIGIT)+ } spliced_term = { term ~ "..." } diff --git a/hugr-model/src/v0/text/parse.rs b/hugr-model/src/v0/text/parse.rs index 40692b67e..485610d76 100644 --- a/hugr-model/src/v0/text/parse.rs +++ b/hugr-model/src/v0/text/parse.rs @@ -114,6 +114,7 @@ impl<'a> ParseContext<'a> { debug_assert_eq!(pair.as_rule(), Rule::term); let pair = pair.into_inner().next().unwrap(); let rule = pair.as_rule(); + let str_slice = pair.as_str(); let mut inner = pair.into_inner(); let term = @@ -203,7 +204,7 @@ impl<'a> ParseContext<'a> { } Rule::term_nat => { - let value = inner.next().unwrap().as_str().parse().unwrap(); + let value = str_slice.trim().parse().unwrap(); Term::Nat(value) } @@ -278,6 +279,14 @@ impl<'a> ParseContext<'a> { Term::Bytes { data } } + Rule::term_float_type => Term::FloatType, + Rule::term_float => { + let value: f64 = str_slice.trim().parse().unwrap(); + Term::Float { + value: value.into(), + } + } + r => unreachable!("term: {:?}", r), }; diff --git a/hugr-model/src/v0/text/print.rs b/hugr-model/src/v0/text/print.rs index 0a8ed4929..77d6ef0cb 100644 --- a/hugr-model/src/v0/text/print.rs +++ b/hugr-model/src/v0/text/print.rs @@ -612,6 +612,15 @@ impl<'p, 'a: 'p> PrintContext<'p, 'a> { self.print_text("meta"); Ok(()) } + Term::Float { value } => { + // The debug representation of a float always includes a decimal point. + self.print_text(format!("{:?}", value.into_inner())); + Ok(()) + } + Term::FloatType => { + self.print_text("float"); + Ok(()) + } } } diff --git a/hugr-model/tests/fixtures/model-const.edn b/hugr-model/tests/fixtures/model-const.edn index 5e66a3c11..61748ab38 100644 --- a/hugr-model/tests/fixtures/model-const.edn +++ b/hugr-model/tests/fixtures/model-const.edn @@ -13,27 +13,42 @@ (define-func example.make-pair [] - [(adt [[(@ arithmetic.float.types.float64) (@ arithmetic.float.types.float64)]])] + [(adt + [[(@ collections.array.array 5 (@ arithmetic.int.types.int 6)) + (@ arithmetic.float.types.float64)]])] (ext) - (dfg [] [%pair] + (dfg + [] [%0] (signature (-> [] - [(adt [[(@ arithmetic.float.types.float64) (@ arithmetic.float.types.float64)]])] + [(adt + [[(@ collections.array.array 5 (@ arithmetic.int.types.int 6)) + (@ arithmetic.float.types.float64)]])] (ext))) (const (tag 0 - [(@ compat.const-json (@ arithmetic.float.types.float64) "{\"c\":\"ConstF64\",\"v\":{\"value\":2.0}}" (ext)) - (@ compat.const-json (@ arithmetic.float.types.float64) "{\"c\":\"ConstF64\",\"v\":{\"value\":3.0}}" (ext))]) - [] [%pair] + [(@ + collections.array.const + 5 + (@ arithmetic.int.types.int 6) + [(@ arithmetic.int.const 6 1) + (@ arithmetic.int.const 6 2) + (@ arithmetic.int.const 6 3) + (@ arithmetic.int.const 6 4) + (@ arithmetic.int.const 6 5)]) + (@ arithmetic.float.const-f64 -3.0)]) + [] [%0] (signature (-> [] - [(adt [[(@ arithmetic.float.types.float64) (@ arithmetic.float.types.float64)]])] + [(adt + [[(@ collections.array.array 5 (@ arithmetic.int.types.int 6)) + (@ arithmetic.float.types.float64)]])] (ext)))))) -(define-func example.f64 +(define-func example.f64-json [] [(@ arithmetic.float.types.float64)] (ext) diff --git a/hugr-model/tests/fixtures/model-literals.edn b/hugr-model/tests/fixtures/model-literals.edn index 68087e37f..7e961d930 100644 --- a/hugr-model/tests/fixtures/model-literals.edn +++ b/hugr-model/tests/fixtures/model-literals.edn @@ -2,3 +2,4 @@ (define-alias mod.string str "\"\n\r\t\\\u{1F44D}") (define-alias mod.bytes bytes (bytes "SGVsbG8gd29ybGQg8J+Yig==")) +(define-alias mod.float float -3.141) diff --git a/hugr-model/tests/snapshots/text__literals.snap b/hugr-model/tests/snapshots/text__literals.snap index e767e310a..3aae5ad2e 100644 --- a/hugr-model/tests/snapshots/text__literals.snap +++ b/hugr-model/tests/snapshots/text__literals.snap @@ -7,3 +7,5 @@ expression: "roundtrip(include_str!(\"fixtures/model-literals.edn\"))" (define-alias mod.string str "\"\n\r\t\\👍") (define-alias mod.bytes bytes (bytes "SGVsbG8gd29ybGQg8J+Yig==")) + +(define-alias mod.float float -3.141)