Skip to content

feat: Type of constants in core Terms. #2411

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open

feat: Type of constants in core Terms. #2411

wants to merge 7 commits into from

Conversation

zrho
Copy link
Contributor

@zrho zrho commented Jul 4, 2025

This PR adds a Term::Const variant, representing the type of constants for a given runtime type. This corresponds to the core.const type in hugr-model.

Closes #2304.

@zrho zrho changed the title Type of constants in core Terms. feat: Type of constants in core Terms. Jul 4, 2025
Copy link

codecov bot commented Jul 4, 2025

Codecov Report

Attention: Patch coverage is 60.00000% with 14 lines in your changes missing coverage. Please review.

Project coverage is 82.54%. Comparing base (6a0e270) to head (8965810).

Files with missing lines Patch % Lines
hugr-core/src/types/type_param.rs 42.85% 4 Missing ⚠️
hugr-py/src/hugr/tys.py 70.00% 3 Missing ⚠️
hugr-core/src/import.rs 60.00% 0 Missing and 2 partials ⚠️
hugr-core/src/types/serialize.rs 0.00% 2 Missing ⚠️
hugr-core/src/extension/resolution/types.rs 0.00% 1 Missing ⚠️
hugr-core/src/extension/resolution/types_mut.rs 0.00% 1 Missing ⚠️
hugr-py/src/hugr/_serialization/tys.py 80.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2411      +/-   ##
==========================================
- Coverage   82.56%   82.54%   -0.02%     
==========================================
  Files         247      247              
  Lines       45894    45926      +32     
  Branches    41528    41545      +17     
==========================================
+ Hits        37891    37911      +20     
- Misses       5981     5992      +11     
- Partials     2022     2023       +1     
Flag Coverage Δ
python 91.18% <73.33%> (-0.07%) ⬇️
rust 81.63% <50.00%> (-0.02%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@zrho zrho force-pushed the push-kklpqyyxpskx branch 3 times, most recently from 3962e45 to 2c329cd Compare July 8, 2025 11:09
@zrho zrho requested a review from acl-cqc July 8, 2025 11:18
@zrho zrho marked this pull request as ready for review July 8, 2025 11:18
@zrho zrho requested a review from a team as a code owner July 8, 2025 11:18
@zrho zrho force-pushed the push-kklpqyyxpskx branch 3 times, most recently from 675c2ca to b9acbff Compare July 9, 2025 08:59
Copy link
Contributor

@acl-cqc acl-cqc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally fine, a couple of suggestions - naming?

And, it's a bit of a shocker to have only 35% coverage! Obviously one cannot get very far without any terms of type Term::Const(....) but I think at the least you could add some roundtrip serialization tests and things like that?

@@ -139,6 +139,9 @@ pub enum Term {
/// - see [`Term::new_var_use`]
#[display("{_0}")]
Variable(TermVar),

/// The type of constants for a runtime type.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// The type of constants for a runtime type.
/// The type of constants, i.e. terms that can be turned into runtime values of a given (runtime) type.

@@ -139,6 +139,9 @@ pub enum Term {
/// - see [`Term::new_var_use`]
#[display("{_0}")]
Variable(TermVar),

/// The type of constants for a runtime type.
Const(Box<Type>),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reckon this should be called ConstType, paralleling BytesType or RuntimeType. (In hindsight, using a Param suffix, rather than ...Type, would have been more similar to the python!).

There may never be a Const constructor (i.e. in the family of TypeArgs, a term that is/produces a runtime value) - rather, there will likely be a number of different ones, but I think we can still try to be consistent wrt. naming.

@@ -685,6 +696,7 @@ pub fn check_term_type(term: &Term, type_: &Term) -> Result<(), TermTypeError> {
(Term::ListType { .. }, Term::StaticType) => Ok(()),
(Term::TupleType(_), Term::StaticType) => Ok(()),
(Term::RuntimeType(_), Term::StaticType) => Ok(()),
(Term::Const(_), Term::StaticType) => Ok(()),

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we do not want to say that e.g. Term::BoundedNat is a const (e.g. of Runtime type usize) but rather wait for a different term that does that?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed! A Term::BoundedNat is a compile time value. It can be used as a parameter to a custom term that describes how to produce a particular type of runtime integer from it.

@@ -101,6 +102,7 @@ def test_tys_sum_str(ty: Type, string: str, repr_str: str):
"(Linear, Nat(3))",
),
(ListParam(StringParam()), "[String]"),
(ConstParam(Qubit), "Const(Qubit)"),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm sure this is valid** but it's a bit misleading, we are never going to have a Term that produces a Qubit "constant" are we?

** this is why we said constants have to be Copyable in hugr-core; I still feel it is a shame not to be able to here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Glad that I randomly picked that example then! Constants are descriptions on how to produce runtime values, so we can certainly have constants that produce qubits. Loading such a constant would mean preparing a qubit in a particular state.

(declare-ctr quantum.const_zero (core.const quantum.qubit))
(declare-ctr quantum.const_one (core.const quantum.qubit))
(declare-ctr quantum.const_plus (core.const quantum.qubit))
(declare-ctr quantum.const_minus (core.const quantum.qubit))

Note that the constant is always copyable since it is only the blueprint. The result of loading the constant need not be copyable. This is one of the advantages that are afforded by this system of constants.

@zrho
Copy link
Contributor Author

zrho commented Jul 9, 2025

Yeah, will add some roundtrip tests. I am looking forward to the day when we have custom terms so that PRs like this will become trivial.

@zrho zrho force-pushed the push-kklpqyyxpskx branch from 63469b2 to 0585551 Compare July 10, 2025 17:02
@zrho zrho force-pushed the push-kklpqyyxpskx branch from 0585551 to 402cc24 Compare July 14, 2025 15:50
@zrho zrho self-assigned this Jul 16, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

TypeParam for constants.
2 participants