This repository was archived by the owner on Jul 24, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 294
[Merged by Bors] - refactor(tactic/polyrith): use the autogenerated json parser #15429
Closed
Closed
Changes from 3 commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -5,6 +5,7 @@ Authors: Dhruv Bhatia, Eric Wieser | |||||||||||||||||||||||||||||||||
-/ | ||||||||||||||||||||||||||||||||||
import tactic.linear_combination | ||||||||||||||||||||||||||||||||||
import data.buffer.parser.numeral | ||||||||||||||||||||||||||||||||||
import data.json | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
/-! | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
|
@@ -275,34 +276,44 @@ ch '(' | |||||||||||||||||||||||||||||||||
<|> sub_parser poly_parser <|> mul_parser poly_parser <|> pow_parser poly_parser) | ||||||||||||||||||||||||||||||||||
<* ch ')' | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
meta instance : non_null_json_serializable poly := | ||||||||||||||||||||||||||||||||||
{ to_json := λ p, json.null, -- we don't actually need this, but the typeclass asks for it | ||||||||||||||||||||||||||||||||||
of_json := λ j, do | ||||||||||||||||||||||||||||||||||
s ← of_json string j, | ||||||||||||||||||||||||||||||||||
match poly_parser.run_string s with | ||||||||||||||||||||||||||||||||||
| sum.inl s := exceptional.fail format!"unable to parse polynomial from.\n\n{s}" | ||||||||||||||||||||||||||||||||||
| sum.inr p := pure p | ||||||||||||||||||||||||||||||||||
end} | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
/-- A schema for success messages from the python script -/ | ||||||||||||||||||||||||||||||||||
@[derive [non_null_json_serializable, inhabited]] | ||||||||||||||||||||||||||||||||||
structure sage_json_success := | ||||||||||||||||||||||||||||||||||
(success : {b : bool // b = tt}) | ||||||||||||||||||||||||||||||||||
(trace : option string := none) | ||||||||||||||||||||||||||||||||||
(data : option (list poly) := none) | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
/-- A schema for failure messages from the python script -/ | ||||||||||||||||||||||||||||||||||
@[derive [non_null_json_serializable, inhabited]] | ||||||||||||||||||||||||||||||||||
structure sage_json_failure := | ||||||||||||||||||||||||||||||||||
(success : {b : bool // b = ff}) | ||||||||||||||||||||||||||||||||||
(error_name : string) | ||||||||||||||||||||||||||||||||||
(error_value : string) | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
/-- Parse the json output from `scripts/polyrith.py` into either an error message, a list of `poly` | ||||||||||||||||||||||||||||||||||
objects, or `none` if only trace output was requested. -/ | ||||||||||||||||||||||||||||||||||
meta def convert_sage_output (j : json) : tactic (option (list poly)) := | ||||||||||||||||||||||||||||||||||
do | ||||||||||||||||||||||||||||||||||
json.object obj ← pure j | fail!"Must be an object", | ||||||||||||||||||||||||||||||||||
let obj := rbmap.from_list obj, | ||||||||||||||||||||||||||||||||||
json.of_bool success ← obj.find "success" | fail!"internal error: missing success field", | ||||||||||||||||||||||||||||||||||
if success then do | ||||||||||||||||||||||||||||||||||
do | ||||||||||||||||||||||||||||||||||
{ some t ← pure (obj.find "trace") | skip, | ||||||||||||||||||||||||||||||||||
json.of_string t ← pure t | fail!"internal error: trace must be a string", | ||||||||||||||||||||||||||||||||||
tactic.trace t }, | ||||||||||||||||||||||||||||||||||
do | ||||||||||||||||||||||||||||||||||
{ some d ← pure (obj.find "data") | pure none, | ||||||||||||||||||||||||||||||||||
json.array l ← some d | fail!"internal error: data field must be a string", | ||||||||||||||||||||||||||||||||||
l ← l.mmap $ λ x, do | ||||||||||||||||||||||||||||||||||
{ json.of_string poly_s ← pure x | fail!"internal error: entries must be strings", | ||||||||||||||||||||||||||||||||||
pure poly_s }, | ||||||||||||||||||||||||||||||||||
l ← l.mmap $ λ x, match poly_parser.run_string x with | ||||||||||||||||||||||||||||||||||
| sum.inl s := fail!"internal error: unable to parse polynomial from.\n\n{s}" | ||||||||||||||||||||||||||||||||||
| sum.inr p := pure p | ||||||||||||||||||||||||||||||||||
end, | ||||||||||||||||||||||||||||||||||
pure l } | ||||||||||||||||||||||||||||||||||
else do | ||||||||||||||||||||||||||||||||||
json.of_string kind ← obj.find "error_name", | ||||||||||||||||||||||||||||||||||
json.of_string message ← obj.find "error_value", | ||||||||||||||||||||||||||||||||||
fail!"polyrith failed to retrieve a solution from Sage! {kind}: {message}" | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
let e : exceptional (sage_json_success ⊕ sage_json_failure) := | ||||||||||||||||||||||||||||||||||
-- try the error format first, so that if both fail we get the message from the success parser | ||||||||||||||||||||||||||||||||||
(sum.inr <$> of_json sage_json_failure j) <|> (sum.inl <$> of_json sage_json_success j), | ||||||||||||||||||||||||||||||||||
match e with | ||||||||||||||||||||||||||||||||||
| exceptional.exception f := exceptional.exception (λ s, format!"internal json error: " ++ f s) | ||||||||||||||||||||||||||||||||||
| exceptional.success (sum.inr f) := | ||||||||||||||||||||||||||||||||||
fail!"polyrith failed to retrieve a solution from Sage! {f.error_name}: {f.error_value}" | ||||||||||||||||||||||||||||||||||
| exceptional.success (sum.inl s) := do | ||||||||||||||||||||||||||||||||||
do { some t ← pure s.trace | skip, tactic.trace t}, | ||||||||||||||||||||||||||||||||||
pure s.data | ||||||||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||||||||
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.
Suggested change
I think this is a slicker version of the same thing! 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. That doesn't work correctly, because if an error message is recieved the failure is treated as a parsing failure, and then it tries to reparse as a success message. Still a helpful comment though, I didn't know about |
||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
/-! | ||||||||||||||||||||||||||||||||||
# Parsing context into poly | ||||||||||||||||||||||||||||||||||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I trust this is right (also because it works), but what's the significance of this weird subtype? Is the idea that only json data with
success: false
should be parsed into this type? Is thenon_null_json_serializable
derive handler the part that's taking this into account?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
subtype.non_null_json_serializable
parser is the one that handles this; it parses the value, and uses decidability for the proof.I could also have used
and then the derive handler would have handled it; but then the
inhabited
derive handler (which I'm using only to appease the linter) wouldn't have worked.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!