-
Notifications
You must be signed in to change notification settings - Fork 52
feat(core): Add Sequence.empty<T>() syntax for creating empty sequences #1036
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
Changes from all commits
271fb5d
bdba95d
b573bb6
f22f601
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -103,9 +103,10 @@ fn map_get (K : Type, V : Type, m : Map K V, k : K) : V => m "[" k "]"; | |
| fn map_set (K : Type, V : Type, m : Map K V, k : K, v : V) : Map K V => | ||
| m "[" k ":=" v "]"; | ||
|
|
||
| // TODO: seq_empty is not yet supported in the grammar because the DDM parser | ||
| // cannot currently handle 0-ary polymorphic functions (no arguments to infer | ||
| // the type parameter from). The Factory definition exists for programmatic use. | ||
| // Unlike other seq_* ops, seq_empty has no value arguments from which DDM can | ||
| // infer the element type, so the type argument must be explicit in surface syntax. | ||
| fn seq_empty (A : Type) : Sequence A => | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This PR's functionality is also implemented in #1100 but could be merged before. |
||
| "Sequence.empty" "<" A ">" "(" ")"; | ||
|
atomb marked this conversation as resolved.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We need also the roundtrip of pretty-printing it that way |
||
| fn seq_length (A : Type, s : Sequence A) : int => "Sequence.length" "(" s ")"; | ||
| fn seq_select (A : Type, s : Sequence A, i : int) : A => "Sequence.select" "(" s ", " i ")"; | ||
| fn seq_append (A : Type, s1 : Sequence A, s2 : Sequence A) : Sequence A => | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -848,6 +848,13 @@ partial def translateExpr (p : Program) (bindings : TransBindings) (arg : Arg) : | |
| | .fn _ q`Core.re_all, [] => | ||
| let fn ← translateFn .none q`Core.re_all | ||
| return fn | ||
| -- Sequence.empty (0-ary polymorphic, takes only a type argument) | ||
| | .fn _ q`Core.seq_empty, [_atp] => | ||
| let ety ← translateLMonoTy bindings _atp | ||
| let fn : LExpr Core.CoreLParams.mono := | ||
| Core.coreOpExpr (.seq .Empty) | ||
| (.some (Core.seqTy ety)) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would you consider adding a small /-- The translation of `Sequence.empty<T>()` produces a `.seq .Empty` operator
annotated with `Sequence T`. -/
#guard
match translateExpr (mkTestPgm "Sequence.empty<int>()") with
| .ok (.op _ name (.some ty)) =>
name.name == "Sequence.empty" && ty == Core.seqTy .int
| _ => falseThe For an actual theorem, the nice property to prove is the round-trip with |
||
| return fn | ||
| -- Unary function applications | ||
| | .fn _ fni, [xa] => | ||
| match fni with | ||
|
|
@@ -913,7 +920,6 @@ partial def translateExpr (p : Program) (bindings : TransBindings) (arg : Arg) : | |
| let x ← translateExpr p bindings xa | ||
| return .mkApp () fn [m, i, x] | ||
| -- Seq operations | ||
| -- TODO: seq_empty is not yet parseable (see Grammar.lean); handle here when added. | ||
| | .fn _ q`Core.seq_length, [_atp, sa] => | ||
| let ety ← translateLMonoTy bindings _atp | ||
| let fn : LExpr Core.CoreLParams.mono := | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -305,3 +305,169 @@ Result: ✅ pass | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #eval verify seqOpsPgm | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --------------------------------------------------------------------- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note that the PR-description / commit-message wording is inconsistent with the actual scope: the commit message on
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Doesn't squash-merging use the PR description as the commit message? I don't think it includes messages from the intermediate commits on the branch. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ---------------------------------------------------------------------- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| -- Tests for Sequence.empty<T>() syntax (issue #1027) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ---------------------------------------------------------------------- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private def seqEmptyPgm := | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #strata | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| program Core; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| procedure SeqEmpty() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var s : Sequence int; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Create an empty sequence using the new syntax | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| s := Sequence.empty<int>(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| assert [empty_length]: Sequence.length(s) == 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Build on top of an empty sequence | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| s := Sequence.build(Sequence.empty<int>(), 42); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| assert [build_on_empty_length]: Sequence.length(s) == 1; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| assert [build_on_empty_elem]: Sequence.select(s, 0) == 42; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #end | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /-- info: true -/ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #guard_msgs in | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| -- No errors in translation. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #eval TransM.run Inhabited.default (translateProgram seqEmptyPgm) |>.snd |>.isEmpty | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /-- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| info: program Core; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| procedure SeqEmpty () | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var s : (Sequence int); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| s := Sequence.empty<int>(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| assert [empty_length]: Sequence.length(s) == 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| s := Sequence.build(Sequence.empty<int>(), 42); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| assert [build_on_empty_length]: Sequence.length(s) == 1; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| assert [build_on_empty_elem]: Sequence.select(s, 0) == 42; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| -/ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #guard_msgs in | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #eval TransM.run Inhabited.default (translateProgram seqEmptyPgm) |>.fst | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /-- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| info: [Strata.Core] Type checking succeeded. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| VCs: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Label: empty_length | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Property: assert | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Obligation: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Sequence.length(Sequence.empty<int>()) == 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Label: build_on_empty_length | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Property: assert | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Obligation: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Sequence.length(Sequence.build(Sequence.empty<int>(), 42)) == 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Label: build_on_empty_elem | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Property: assert | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Obligation: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Sequence.select(Sequence.build(Sequence.empty<int>(), 42), 0) == 42 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| info: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Obligation: empty_length | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Property: assert | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Result: ✅ pass | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Obligation: build_on_empty_length | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Property: assert | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Result: ✅ pass | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Obligation: build_on_empty_elem | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Property: assert | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Result: ✅ pass | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| -/ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Test coverage is narrow — only
Example follow-up test (feel free to consolidate into one procedure):
Suggested change
Also worth adding: a negative test showing that Related proof suggestion for |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #guard_msgs in | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #eval verify seqEmptyPgm | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ---------------------------------------------------------------------- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| -- Exercise various element types for Sequence.empty<T>(). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private def seqEmptyTypesPgm := | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #strata | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| program Core; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| procedure SeqEmptyTypes() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var sb : Sequence bool; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var ssi : Sequence (Sequence int); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var smi : Sequence (Map int bool); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| sb := Sequence.empty<bool>(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ssi := Sequence.empty<Sequence int>(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| smi := Sequence.empty<Map int bool>(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| assert [bool_len]: Sequence.length(sb) == 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| assert [seq_seq_len]: Sequence.length(ssi) == 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| assert [seq_map_len]: Sequence.length(smi) == 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #end | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /-- info: true -/ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #guard_msgs in | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #eval TransM.run Inhabited.default (translateProgram seqEmptyTypesPgm) |>.snd |>.isEmpty | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /-- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| info: program Core; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| procedure SeqEmptyTypes () | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var sb : (Sequence bool); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var ssi : (Sequence (Sequence int)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var smi : (Sequence (Map int bool)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| sb := Sequence.empty<bool>(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ssi := Sequence.empty<Sequence int>(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| smi := Sequence.empty<Map int bool>(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| assert [bool_len]: Sequence.length(sb) == 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| assert [seq_seq_len]: Sequence.length(ssi) == 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| assert [seq_map_len]: Sequence.length(smi) == 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| -/ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #guard_msgs in | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #eval TransM.run Inhabited.default (translateProgram seqEmptyTypesPgm) |>.fst | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /-- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| info: [Strata.Core] Type checking succeeded. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| VCs: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Label: bool_len | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Property: assert | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Obligation: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Sequence.length(Sequence.empty<bool>()) == 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Label: seq_seq_len | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Property: assert | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Obligation: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Sequence.length(Sequence.empty<Sequence int>()) == 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Label: seq_map_len | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Property: assert | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Obligation: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Sequence.length(Sequence.empty<Map int bool>()) == 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| info: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Obligation: bool_len | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Property: assert | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Result: ✅ pass | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Obligation: seq_seq_len | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Property: assert | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Result: ✅ pass | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Obligation: seq_map_len | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Property: assert | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Result: ✅ pass | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| -/ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #guard_msgs in | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #eval verify seqEmptyTypesPgm | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ---------------------------------------------------------------------- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.