Skip to content
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

refactor!: rename predicate to TupleSum/UnitSum #557

Merged
merged 11 commits into from
Oct 23, 2023
Merged

Conversation

ss2165
Copy link
Member

@ss2165 ss2165 commented Sep 26, 2023

Closes #448

BREAKING CHANGE: previous uses of type/value constructor methods for "predicates" will need updating

@ss2165 ss2165 requested a review from acl-cqc September 26, 2023 14:34
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.

Yes-ish. I think I'd like @cqc-alec's looking over here, not for nitpicking details, but whether this name-change "works" overall.

  • "Unit Choice" is clearly an improvement over "Simple Predicate", but then "Unit Predicate" would have been too
  • My general feeling is I'm not as persuaded as I thought I'd be. I guess I just feel that one is far more likely to use the word choice by accident, when one didn't mean a Choice, and in spoken English capitalization is hard to determine.
  • Perhaps this is OK if we are 100% consistent on always capitalizing here, and it may also help to tighten up the distinction between Choice types and Choice values (if that's what they are called) - by which perhaps I mean never to use "Choice" on its own without being immediately followed by either "type" or "value"...
  • I do like "choice_variants" or "choice_rows", too. Perhaps a general theme here that maybe Choice works better if we always use it as an adjective not as a noun?

I'm not sure whether I see a good alternative that is less likely to be used by accident. "Selector" perhaps, but is that better than Predicate? "Chooser"? Partway through I was actually wondering if we could just say "sum-of-tuples" explicitly, but then I gave up when I looked at the builder code....

@@ -424,7 +424,7 @@ output of each of these is a sum type, whose arity is the number of outgoing
control edges; the remaining outputs are those that are passed to all
succeeding nodes.

The three nodes labelled "Const" are simply generating a predicate with one empty
The three nodes labelled "Const" are simply generating a choice with one empty
Copy link
Contributor

Choose a reason for hiding this comment

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

If a Choice (capitalized) is a type, is the corresponding value a choice (lowercase)? Or should "choice" here be "value of Choice type"? (the "one empty value to pass" might need changing too, not quite sure I understand that

appended are sent to this child, and all outputs of the child are the
outputs of the Conditional; that child is evaluated, but the others are
not. That is, Conditional-nodes act as "if-then-else" followed by a
control-flow merge.

A **Predicate(T0, T1…TN)** type is an algebraic “sum of products” type,
A **Choice(T0, T1…TN)** type is an algebraic “sum of products” type,
Copy link
Contributor

Choose a reason for hiding this comment

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

Drive-by, but I think we should be consistent between T<i> on this line and #t<i> on the next

src/builder/cfg.rs Outdated Show resolved Hide resolved
src/builder/cfg.rs Outdated Show resolved Hide resolved
@@ -245,7 +245,7 @@ pub type BlockBuilder<B> = DFGWrapper<B, BasicBlockID>;

impl<B: AsMut<Hugr> + AsRef<Hugr>> BlockBuilder<B> {
/// Set the outputs of the block, with `branch_wire` being the value of the
/// predicate. `outputs` are the remaining outputs.
/// Choice. `outputs` are the remaining outputs.
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is it branch_wire not choice_wire (why wasn't it predicate_wire before)?

Copy link
Member Author

Choose a reason for hiding this comment

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

I guess we are trying to map to normal cfg terminology here?

src/types.rs Outdated Show resolved Hide resolved
@@ -80,8 +80,8 @@ mod test {
let t = Type::new_sum(vec![USIZE_T, FLOAT64_TYPE]);
assert_eq!(ser_roundtrip(&t), t);

// A simple predicate
let t = Type::new_simple_predicate(4);
// A unit choice
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
// A unit choice
// A unit Choice

But I don't think this comment adds much tbh....(!)

src/values.rs Outdated Show resolved Hide resolved
src/values.rs Outdated Show resolved Hide resolved
src/values.rs Outdated
@@ -113,7 +113,7 @@ impl Value {
}
}

/// Sum value (could be of any compatible type, e.g. a predicate)
/// Sum value (could be of any compatible type, e.g. a Choice)
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
/// Sum value (could be of any compatible type, e.g. a Choice)
/// Sum value (could be of any compatible type - e.g., if `value` was a Tuple, a Choice type)

@cqc-alec
Copy link
Collaborator

Yes-ish. I think I'd like @cqc-alec's looking over here, not for nitpicking details, but whether this name-change "works" overall.

* "Unit Choice" is clearly an improvement over "Simple Predicate", but then "Unit Predicate" would have been too

Or "Simple Choice"?

* My general feeling is I'm not as persuaded as I thought I'd be. I guess I just feel that one is far more likely to use the word choice by accident, when one didn't mean a Choice, and in spoken English capitalization is hard to determine.

* Perhaps this is OK if we are 100% consistent on always capitalizing here, and it may also help to tighten up the distinction between Choice types and Choice values (if that's what they are called) - by which perhaps I mean never to use "Choice" on its own without being immediately followed by either "type" or "value"...

* I do like "choice_variants" or "choice_rows", too. Perhaps a general theme here that maybe Choice works better if we always use it as an adjective not as a noun?

I'm not sure whether I see a good alternative that is less likely to be used by accident. "Selector" perhaps, but is that better than Predicate? "Chooser"? Partway through I was actually wondering if we could just say "sum-of-tuples" explicitly, but then I gave up when I looked at the builder code....

"Choice" seems better than "predicate" but perhaps it isn't ideal. We could use "variant" (variant type or variant value), as in C++17. That can be heard as a noun or adjective, but I'm not sure if that ambiguity matters. I'm less keen on "chooser" or "selector" because they imply an action that is not really part of the type.

@ss2165
Copy link
Member Author

ss2165 commented Sep 28, 2023

what about borrowing SOP (sum of products) from boolean algebra?

@cqc-alec
Copy link
Collaborator

what about borrowing SOP (sum of products) from boolean algebra?

Has the advantage of being precise, but I feel like a more understandable name (for exactly that concept) would be preferable. If "Choice" and "Variant" are a bit too vague, could we use "DataChoice" or "DataVariant"? Not really convinced, just trying out ideas...

@ss2165
Copy link
Member Author

ss2165 commented Sep 28, 2023

Variant is too close to Sum for me (indeed we use it in Tierkreis instead of Sum). How about just simple SumTuple and SumUnit then?
new_sum_tuple, new_sum_unit etc.
We could keep using Choice just as a shorthand in the spec, and use precise naming in the code.

@cqc-alec
Copy link
Collaborator

Variant is too close to Sum for me (indeed we use it in Tierkreis instead of Sum). How about just simple SumTuple and SumUnit then? new_sum_tuple, new_sum_unit etc. We could keep using Choice just as a shorthand in the spec, and use precise naming in the code.

I'd personally find it confusing to have different terminology used in the spec and implementation. I'd be OK with something like SumTuple and SumUnit, though I would turn these around to TupleSum and UnitSum!

@acl-cqc
Copy link
Contributor

acl-cqc commented Sep 29, 2023

If TupleSum seems ok (I guess it's no longer than predicate!) then that could work. I'm wondering if "choice value" and "choice type" might be alright tho - specifically, if we always use choice as an adjective, then that's different from its normal/accidental use in English, i.e. as a noun. Perhaps Type::new_choice is obviously-enough a new choice type to avoid having to write Type::new_choice_type...

@ss2165
Copy link
Member Author

ss2165 commented Sep 29, 2023

Yeah I see what you mean Alan, Choice reads nicer in the spec, but I'm happy with TupleSum and UnitSum everywhere

@cqc-alec
Copy link
Collaborator

Yeah I see what you mean Alan, Choice reads nicer in the spec, but I'm happy with TupleSum and UnitSum everywhere

OK for me

@cqc-alec cqc-alec closed this Sep 29, 2023
@cqc-alec cqc-alec reopened this Sep 29, 2023
@cqc-alec
Copy link
Collaborator

Sorry closed by mistake!

Copy link
Collaborator

@cqc-alec cqc-alec left a comment

Choose a reason for hiding this comment

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

Do we go with TupleSum and UnitSum then?

@acl-cqc
Copy link
Contributor

acl-cqc commented Oct 10, 2023

So I'd be happy with the "Choice, but only as an adjective" approach, but I'm also happy with UnitSum/UnitTuple. TBH when it comes to the spec we should probably prioritise precision, rigor and definitiveness over reading nicely....

@ss2165 ss2165 changed the title refactor!: rename predicate to choice refactor!: rename predicate to TupleSum/UnitSum Oct 13, 2023
@ss2165 ss2165 requested a review from acl-cqc October 13, 2023 14:46
github-merge-queue bot pushed a commit that referenced this pull request Oct 16, 2023
I read this as part of #557 and was just bewildered, so thought I'd see
if I can do better. Admit it's not easy! How does this strike you?
@ss2165 ss2165 removed the request for review from acl-cqc October 20, 2023 13:53
@ss2165 ss2165 requested a review from cqc-alec October 20, 2023 13:53
src/ops/constant.rs Outdated Show resolved Hide resolved
@@ -1209,11 +1210,11 @@ mod test {
entry_extensions: ExtensionSet,
exit_types: impl Into<TypeRow>,
) -> Result<([Node; 3], Node), Box<dyn Error>> {
let entry_predicate_type = Type::new_predicate(entry_predicates.clone());
let entry_predicate_type = Type::new_tuple_sum(entry_predicates.clone());
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should we rename entry_predicates?

@ss2165 ss2165 enabled auto-merge October 23, 2023 08:45
@ss2165 ss2165 added this pull request to the merge queue Oct 23, 2023
Merged via the queue into main with commit bb446e2 Oct 23, 2023
7 checks passed
@ss2165 ss2165 deleted the refactor/choice branch October 23, 2023 08:50
@github-actions github-actions bot mentioned this pull request Jan 3, 2024
github-merge-queue bot pushed a commit that referenced this pull request Jan 15, 2024
## 🤖 New release
* `quantinuum-hugr`: 0.1.0

<details><summary><i><b>Changelog</b></i></summary><p>

<blockquote>

## 0.1.0 (2024-01-15)

### Bug Fixes

- Subgraph boundaries with copies
([#440](#440))
- [**breaking**] Use internal tag for SumType enum serialisation
([#462](#462))
- Check kind before unwrap in insert_identity
([#475](#475))
- Allow for variables to get solved in inference
([#478](#478))
- In IdentityInsertion add noop to correct parent
([#477](#477))
- Failing release tests ([#485](#485))
- [**breaking**] Serialise `Value`, `PrimValue`, and `TypeArg` with
internal tags ([#496](#496))
- Serialise custom constants with internal tag
([#502](#502))
- [**breaking**] Reduce max int width in arithmetic extension to 64
([#504](#504))
- HugrView::get_function_type
([#507](#507))
- TODO in resolve_extension_ops: copy across input_extensions
([#510](#510))
- Use given input extensions in `define_function`
([#524](#524))
- Lessen requirements for hugrs in outline_cfg
([#528](#528))
- Make unification logic less strict
([#538](#538))
- Simple replace incorrectly copying metadata
([#545](#545))
- Account for self-referencial constraints
([#551](#551))
- Consider shunted metas when comparing equality
([#555](#555))
- Join labels in issue workflow
([#563](#563))
- Comment out broken priority code
([#562](#562))
- Handling of issues with no priority label
([#573](#573))
- Don't insert temporary wires when extracting a subgraph
([#582](#582))
- Improve convexity checking and fix test
([#585](#585))
- Ignore input->output links in
SiblingSubgraph::try_new_dataflow_subgraph
([#589](#589))
- Enforce covariance of SiblingMut::RootHandle
([#594](#594))
- Erratic stack overflow in infer.rs (live_var)
([#638](#638))
- Work harder in variable instantiation
([#591](#591))
- Actually add the error type to prelude
([#672](#672))
- Serialise dynamically computed opaqueOp signatures
([#690](#690))
- FuncDefns don't require that their extensions match their children
([#688](#688))
- Binary compute_signature returning a PolyFuncType with binders
([#710](#710))
- Use correct number of args for int ops
([#723](#723))
- [**breaking**] Add serde tag to TypeParam enum
([#722](#722))
- Allow widening and narrowing to same width.
([#735](#735))
- Case node should not have an external signature
([#749](#749))
- [**breaking**] Normalize input/output value/static/other ports in
`OpType` ([#783](#783))
- No dataflow_signature for block types
([#792](#792))
- Ignore unsupported test in miri
([#794](#794))
- Include schema rather than read file
([#807](#807))

### Documentation

- Add operation constraint to quantum extension
([#543](#543))
- Coverage check section in DEVELOPMENT.md
([#648](#648))
- Remove "quantum extension" from HUGR spec.
([#694](#694))
- Improve crate-level docs, including example code.
([#698](#698))
- Spec cleanups and clarifications
([#742](#742))
- Spec clarifications ([#738](#738))
- Spec updates ([#741](#741))
- [spec] Remove references to causal cone and Order edges from Input
([#762](#762))
- Mention experimental inference in readme
([#800](#800))
- Collection of spec updates for 0.1
([#801](#801))
- Add schema v0 ([#805](#805))
- Update spec wrt. polymorphism
([#791](#791))

### Features

- Derive things for builder structs
([#229](#229))
- Return a slice of types from the signature
([#238](#238))
- Move `dot_string` to `HugrView`
([#271](#271))
- [**breaking**] Change `TypeParam::USize` to `TypeParam::BoundedNat`
and use in int extensions
([#445](#445))
- TKET2 compatibility requirements
([#450](#450))
- Split methods between `HugrMut` and `HugrMutInternals`
([#441](#441))
- Add `HugrView::node_connections` to get all links between nodes
([#460](#460))
- Location information in extension inference error
([#464](#464))
- Add T, Tdg, X gates ([#466](#466))
- [**breaking**] Add `ApplyResult` associated type to `Rewrite`
([#472](#472))
- Implement rewrite `IdentityInsertion`
([#474](#474))
- Instantiate inferred extensions
([#461](#461))
- Default DFG builders to open extension sets
([#473](#473))
- Some helper methods ([#482](#482))
- Extension inference for conditional nodes
([#465](#465))
- Add ConvexChecker ([#487](#487))
- Add clippy lint for mut calls in a debug_assert
([#488](#488))
- Default more builder methods to open extension sets
([#492](#492))
- Port is serializable ([#489](#489))
- More general portgraph references
([#494](#494))
- Add extension deltas to CFG ops
([#503](#503))
- Implement petgraph traits on Hugr
([#498](#498))
- Make extension delta a parameter of CFG builders
([#514](#514))
- [**breaking**] SiblingSubgraph does not borrow Hugr
([#515](#515))
- Validate TypeArgs to ExtensionOp
([#509](#509))
- Derive Debug & Clone for `ExtensionRegistry`.
([#530](#530))
- Const nodes are built with some extension requirements
([#527](#527))
- Some python errors and bindings
([#533](#533))
- Insert_hugr/insert_view return node map
([#535](#535))
- Add `SiblingSubgraph::try_from_nodes_with_checker`
([#547](#547))
- PortIndex trait for undirected port parameters
([#553](#553))
- Insert/extract subgraphs from a HugrView
([#552](#552))
- Add `new_array` operation to prelude
([#544](#544))
- Add a `DataflowParentID` node handle
([#559](#559))
- Make TypeEnum and it's contents public
([#558](#558))
- Optional direction check when querying a port index
([#566](#566))
- Extension inference for CFGs
([#529](#529))
- Better subgraph verification errors
([#587](#587))
- Compute affected nodes for `SimpleReplacement`
([#600](#600))
- Move `SimpleReplace::invalidation_set` to the `Rewrite` trait
([#602](#602))
- [**breaking**] Resolve extension ops (mutating Hugr) in
(infer_and_->)update_validate
([#603](#603))
- Add accessors for node index and const values
([#605](#605))
- [**breaking**] Expose the value of ConstUsize
([#621](#621))
- Nicer debug and display for core types
([#628](#628))
- [**breaking**] Static checking of Port direction
([#614](#614))
- Builder and HugrMut add_op_xxx default to open extensions
([#622](#622))
- [**breaking**] Add panicking integer division ops
([#625](#625))
- Add hashable `Angle` type to Quantum extension
([#608](#608))
- [**breaking**] Remove "rotations" extension.
([#645](#645))
- Port.as_directed to match on either direction
([#647](#647))
- Impl GraphRef for PetgraphWrapper
([#651](#651))
- Provide+implement Replace API
([#613](#613))
- Require the node's metadata to always be a Map
([#661](#661))
- [**breaking**] Polymorphic function types (inc OpDefs) using dyn trait
([#630](#630))
- Make prelude error type public
([#669](#669))
- Shorthand for retrieving custom constants from `Const`, `Value`
([#679](#679))
- [**breaking**] HugrView API improvements
([#680](#680))
- Make FuncDecl/FuncDefn polymorphic
([#692](#692))
- [**breaking**] Simplify `SignatureFunc` and add custom arg validation.
([#706](#706))
- [**breaking**] Drop the `pyo3` feature
([#717](#717))
- [**breaking**] `OpEnum` trait for common opdef functionality
([#721](#721))
- MakeRegisteredOp trait for easier registration
([#726](#726))
- Getter for `PolyFuncType::body`
([#727](#727))
- `Into<OpType>` for custom ops
([#731](#731))
- Always require a signature in `OpaqueOp`
([#732](#732))
- Values (and hence Consts) know their extensions
([#733](#733))
- [**breaking**] Use ConvexChecker trait
([#740](#740))
- Custom const for ERROR_TYPE
([#756](#756))
- Implement RemoveConst and RemoveConstIgnore
([#757](#757))
- Constant folding implemented for core and float extension
([#769](#769))
- Constant folding for arithmetic conversion operations
([#720](#720))
- DataflowParent trait for getting inner signatures
([#782](#782))
- Constant folding for logic extension
([#793](#793))
- Constant folding for list operations
([#795](#795))
- Add panic op to prelude
([#802](#802))
- Const::from_bool function
([#803](#803))

### HugrMut

- Validate nodes for set_metadata/get_metadata_mut, too
([#531](#531))

### HugrView

- Validate nodes, and remove Base
([#523](#523))

### Miscellaneous Tasks

- [**breaking**] Update portgraph 0.10 and pyo3 0.20
([#612](#612))
- [**breaking**] Hike MSRV to 1.75
([#761](#761))

### Performance

- Use lazy static definittion for prelude registry
([#481](#481))

### Refactor

- Move `rewrite` inside `hugr`, `Rewrite` -> `Replace` implementing new
'Rewrite' trait ([#119](#119))
- Use an excluded upper bound instead of max log width.
([#451](#451))
- Add extension info to `Conditional` and `Case`
([#463](#463))
- `ExtensionSolution` only consists of input extensions
([#480](#480))
- Remove builder from more DFG tests
([#490](#490))
- Separate hierarchy views
([#500](#500))
- [**breaking**] Use named struct for float constants
([#505](#505))
- Allow NodeType::new to take any Into<Option<ExtensionSet>>
([#511](#511))
- Move apply_rewrite from Hugr to HugrMut
([#519](#519))
- Use SiblingSubgraph in SimpleReplacement
([#517](#517))
- CFG takes a FunctionType
([#532](#532))
- Remove check_custom_impl by inlining into check_custom
([#604](#604))
- Insert_subgraph just return HashMap, make InsertionResult new_root
compulsory ([#609](#609))
- [**breaking**] Rename predicate to TupleSum/UnitSum
([#557](#557))
- Simplify infer.rs/report_mismatch using early return
([#615](#615))
- Move the core types to their own module
([#627](#627))
- Change &NodeType->&OpType conversion into op() accessor
([#623](#623))
- Infer.rs 'fn results' ([#631](#631))
- Be safe ([#637](#637))
- NodeType constructors, adding new_auto
([#635](#635))
- Constraint::Plus stores an ExtensionSet, which is a BTreeSet
([#636](#636))
- [**breaking**] Remove `SignatureDescription`
([#644](#644))
- [**breaking**] Remove add_op_<posn> by generalizing add_node_<posn>
with "impl Into" ([#642](#642))
- Rename accidentally-changed Extension::add_node_xxx back to add_op
([#659](#659))
- [**breaking**] Remove quantum extension
([#670](#670))
- Use type schemes in extension definitions wherever possible
([#678](#678))
- [**breaking**] Flatten `Prim(Type/Value)` in to parent enum
([#685](#685))
- [**breaking**] Rename `new_linear()` to `new_endo()`.
([#697](#697))
- Replace NodeType::signature() with io_extensions()
([#700](#700))
- Validate ExtensionRegistry when built, not as we build it
([#701](#701))
- [**breaking**] One way to add_op to extension
([#704](#704))
- Remove Signature struct
([#714](#714))
- Use `MakeOpDef` for int_ops
([#724](#724))
- [**breaking**] Use enum op traits for floats + conversions
([#755](#755))
- Avoid dynamic dispatch for non-folding operations
([#770](#770))
- Simplify removeconstignore verify
([#768](#768))
- [**breaking**] Unwrap BasicBlock enum
([#781](#781))
- Make clear const folding only for leaf ops
([#785](#785))
- [**breaking**] `s/RemoveConstIgnore/RemoveLoadConstant`
([#789](#789))
- Put extension inference behind a feature gate
([#786](#786))

### SerSimpleType

- Use Vec not TypeRow ([#381](#381))

### SimpleReplace+OutlineCfg

- Use HugrMut methods rather than .hierarchy/.graph
([#280](#280))

### Testing

- Update inference test to not use DFG builder
([#550](#550))
- Strengthen "failing_sccs_test", rename to "sccs" as it's not failing!
([#660](#660))
- [**breaking**] Improve coverage in signature and validate
([#643](#643))
- Use insta snapshots to add dot_string coverage
([#682](#682))
- Miri ignore file-opening test
([#684](#684))
- Unify the serialisation tests
([#730](#730))
- Add schema validation to roundtrips
([#806](#806))

### `ConstValue

- :F64` and `OpaqueOp::new`
([#206](#206))

### Cleanup

- Remove outdated comment
([#536](#536))

### Cosmetic

- Format + remove stray TODO
([#444](#444))

### Doc

- Crate name as README title + add reexport
([#199](#199))

### S/EdgeKind

- :Const/EdgeKind::Static/
([#201](#201))

### Simple_replace.rs

- Use HugrMut::remove_node, includes clearing op_types
([#242](#242))

### Spec

- Remove "Draft 3" from title of spec document.
([#590](#590))
- Rephrase confusing paragraph about TailLoop inputs/outputs
([#567](#567))

### Src/ops/validate.rs

- Common-up some type row calculations
([#254](#254))
</blockquote>


</p></details>

---
This PR was generated with
[release-plz](https://github.com/MarcoIeni/release-plz/).

---------

Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Agustín Borgna <121866228+aborgna-q@users.noreply.github.com>
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.

Rename Predicate/SimplePredicate (to Choice + UnitChoice?)
3 participants