generated from amazon-archives/__template_Apache-2.0
-
Notifications
You must be signed in to change notification settings - Fork 23
Add support for function declaration statements #352
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
MikaelMayer
wants to merge
15
commits into
main
Choose a base branch
from
add-func-decl-to-statements
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
99ba9b8
Add support for function declarations within statement blocks
MikaelMayer 6b1cdc2
Fix Factory_wf proof using rotate_left to reorder goals
MikaelMayer a8a4a0c
Remove unnecessary Lambda namespace opening in Statement.lean
MikaelMayer b8ec252
Remove unnecessary Lambda namespace opening in Program.lean
MikaelMayer d666882
Restore proper function body formatting by adding ToFormat instance f…
MikaelMayer ed1f8ac
Remove B3 .gitignore (moved to .git/info/exclude for local use)
MikaelMayer c6ede80
Clean up: revert ProcedureWF.lean to main, remove unnecessary comment
MikaelMayer 77eb4fa
Merge main into add-func-decl-to-statements
MikaelMayer 62a5f70
Fix merge: add missing funcDecl cases in ProcedureInlining and apply …
MikaelMayer 5f65da9
Update funcDecl test to demonstrate variable capture semantics
MikaelMayer a13b470
Merge branch 'main' into add-func-decl-to-statements
MikaelMayer 6797599
Fix merge: convert Format to String for EvalError.Misc
MikaelMayer 5ceddf3
Implement value capture for funcDecl: substitute free variables at de…
MikaelMayer 86f6c90
Fix merge: convert Format errors to DiagnosticModel in funcDecl type …
MikaelMayer 776a87d
Merge branch 'main' into add-func-decl-to-statements
shigoel 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 hidden or 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
This file contains hidden or 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
This file contains hidden or 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 |
|---|---|---|
|
|
@@ -10,6 +10,8 @@ import Strata.DDM.AST | |
| import Strata.DDM.Util.Array | ||
| import Strata.DL.Util.List | ||
| import Strata.DL.Util.ListMap | ||
| import Strata.DL.Imperative.PureExpr | ||
| import Strata.DL.Imperative.MetaData | ||
|
|
||
| /-! | ||
| ## Lambda's Factory | ||
|
|
@@ -57,9 +59,11 @@ abbrev LTySignature := Signature IDMeta LTy | |
|
|
||
|
|
||
| /-- | ||
| A Lambda factory function, where the body can be optional. Universally | ||
| quantified type identifiers, if any, appear before this signature and can | ||
| quantify over the type identifiers in it. | ||
| A generic function structure, parameterized by identifier, expression, type, and metadata types. | ||
|
|
||
| This structure can be instantiated for different expression languages. | ||
| For Lambda expressions, use `LFunc`. For other expression systems, instantiate | ||
| with appropriate types. | ||
|
|
||
| A optional evaluation function can be provided in the `concreteEval` field for | ||
| each factory function to allow the partial evaluator to do constant propagation | ||
|
|
@@ -85,44 +89,74 @@ concrete/constants, this fails and it returns .none. | |
| (TODO) Use `.bvar`s in the body to correspond to the formals instead of using | ||
| `.fvar`s. | ||
| -/ | ||
| structure LFunc (T : LExprParams) where | ||
| name : T.Identifier | ||
| structure Func (IdentT : Type) (ExprT : Type) (TyT : Type) (MetadataT : Type) where | ||
| name : IdentT | ||
| typeArgs : List TyIdentifier := [] | ||
| isConstr : Bool := false --whether function is datatype constructor | ||
| inputs : @LMonoTySignature T.IDMeta | ||
| output : LMonoTy | ||
| body : Option (LExpr T.mono) := .none | ||
| inputs : ListMap IdentT TyT | ||
| output : TyT | ||
| body : Option ExprT := .none | ||
| -- (TODO): Add support for a fixed set of attributes (e.g., whether to inline | ||
| -- a function, etc.). | ||
| attr : Array String := #[] | ||
| -- The T.Metadata argument is the metadata that will be attached to the | ||
| -- The MetadataT argument is the metadata that will be attached to the | ||
| -- resulting expression of concreteEval if evaluation was successful. | ||
| concreteEval : Option (T.Metadata → List (LExpr T.mono) → Option (LExpr T.mono)) := .none | ||
| axioms : List (LExpr T.mono) := [] -- For axiomatic definitions | ||
| concreteEval : Option (MetadataT → List ExprT → Option ExprT) := .none | ||
| axioms : List ExprT := [] -- For axiomatic definitions | ||
|
|
||
| /-- | ||
| A Lambda factory function - instantiation of `Func` for Lambda expressions. | ||
|
|
||
| Universally quantified type identifiers, if any, appear before this signature and can | ||
| quantify over the type identifiers in it. | ||
| -/ | ||
| abbrev LFunc (T : LExprParams) := Func (T.Identifier) (LExpr T.mono) LMonoTy T.Metadata | ||
|
|
||
| /-- | ||
| Well-formedness properties of LFunc. These are split from LFunc because | ||
| otherwise it becomes impossible to create a 'temporary' LFunc object whose | ||
| A function declaration for use with `PureExpr` - instantiation of `Func` for | ||
| any expression system that implements the `PureExpr` interface. | ||
| -/ | ||
| abbrev PureFunc (P : Imperative.PureExpr) := Func P.Ident P.Expr P.Ty P.ExprMetadata | ||
|
|
||
| /-- | ||
| Helper constructor for LFunc to maintain backward compatibility. | ||
| -/ | ||
| def LFunc.mk {T : LExprParams} (name : T.Identifier) (typeArgs : List TyIdentifier := []) | ||
| (isConstr : Bool := false) (inputs : ListMap T.Identifier LMonoTy) (output : LMonoTy) | ||
| (body : Option (LExpr T.mono) := .none) (attr : Array String := #[]) | ||
| (concreteEval : Option (T.Metadata → List (LExpr T.mono) → Option (LExpr T.mono)) := .none) | ||
| (axioms : List (LExpr T.mono) := []) : LFunc T := | ||
| Func.mk name typeArgs isConstr inputs output body attr concreteEval axioms | ||
|
|
||
| /-- | ||
| Well-formedness properties of Func. These are split from Func because | ||
| otherwise it becomes impossible to create a 'temporary' Func object whose | ||
| wellformedness might not hold yet. | ||
| -/ | ||
| structure LFuncWF {T : LExprParams} (f : LFunc T) where | ||
| structure FuncWF {IdentT ExprT TyT MetadataT : Type} (f : Func IdentT ExprT TyT MetadataT) where | ||
| -- No args have same name. | ||
| arg_nodup: | ||
| List.Nodup (f.inputs.map (·.1.name)) | ||
| List.Nodup (f.inputs.map (·.1)) | ||
| -- concreteEval does not succeed if the length of args is incorrect. | ||
| concreteEval_argmatch: | ||
| ∀ fn md args res, f.concreteEval = .some fn | ||
| → fn md args = .some res | ||
| → args.length = f.inputs.length | ||
|
|
||
| /-- | ||
| Well-formedness properties of LFunc - extends FuncWF with Lambda-specific properties. | ||
| -/ | ||
| structure LFuncWF {T : LExprParams} (f : LFunc T) extends FuncWF f where | ||
| -- Free variables of body must be arguments. | ||
| body_freevars: | ||
| ∀ b freevars, f.body = .some b | ||
| → freevars = LExpr.freeVars b | ||
| → (∀ fv, fv ∈ freevars → | ||
| ∃ arg, List.Mem arg f.inputs ∧ fv.1.name = arg.1.name) | ||
| -- concreteEval does not succeed if the length of args is incorrect. | ||
| concreteEval_argmatch: | ||
| ∀ fn md args res, f.concreteEval = .some fn | ||
| → fn md args = .some res | ||
| → args.length = f.inputs.length | ||
|
|
||
| instance LFuncWF.arg_nodup_decidable {T : LExprParams} (f : LFunc T): | ||
| Decidable (List.Nodup (f.inputs.map (·.1.name))) := by | ||
| instance FuncWF.arg_nodup_decidable {IdentT ExprT TyT MetadataT : Type} [DecidableEq IdentT] | ||
| (f : Func IdentT ExprT TyT MetadataT): | ||
| Decidable (List.Nodup (f.inputs.map (·.1))) := by | ||
| apply List.nodupDecidable | ||
|
|
||
| instance LFuncWF.body_freevars_decidable {T : LExprParams} (f : LFunc T): | ||
|
|
@@ -151,24 +185,36 @@ instance LFuncWF.body_freevars_decidable {T : LExprParams} (f : LFunc T): | |
| | .none => by | ||
| apply isTrue; grind | ||
|
|
||
| -- LFuncWF.concreteEval_argmatch is not decidable. | ||
| -- FuncWF.concreteEval_argmatch and LFuncWF.concreteEval_argmatch are not decidable.-- FuncWF.body_freevars is commented out as it's expression-type specific | ||
| -- FuncWF.concreteEval_argmatch is not decidable. | ||
|
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. Repeated comment. Also, Why would |
||
|
|
||
| instance [Inhabited T.Metadata] [Inhabited T.IDMeta] : Inhabited (LFunc T) where | ||
| default := { name := Inhabited.default, inputs := [], output := LMonoTy.bool } | ||
|
|
||
| instance : ToFormat (LFunc T) where | ||
| instance {IdentT ExprT TyT MetadataT : Type} [ToFormat IdentT] [ToFormat ExprT] [ToFormat TyT] [Inhabited ExprT] : ToFormat (Func IdentT ExprT TyT MetadataT) where | ||
| format f := | ||
| let attr := if f.attr.isEmpty then f!"" else f!"@[{f.attr}]{Format.line}" | ||
| let typeArgs := if f.typeArgs.isEmpty | ||
| then f!"" | ||
| else f!"∀{f.typeArgs}." | ||
| let type := f!"{typeArgs} ({Signature.format f.inputs}) → {f.output}" | ||
| -- Format inputs recursively like Signature.format | ||
| let rec formatInputs (inputs : List (IdentT × TyT)) : Format := | ||
| match inputs with | ||
| | [] => f!"" | ||
| | [(k, v)] => f!"({k} : {v})" | ||
| | (k, v) :: rest => f!"({k} : {v}) " ++ formatInputs rest | ||
| let type := f!"{typeArgs} ({formatInputs f.inputs}) → {f.output}" | ||
| let sep := if f.body.isNone then f!";" else f!" :=" | ||
| let body := if f.body.isNone then f!"" else Std.Format.indentD f!"({f.body.get!})" | ||
| f!"{attr}\ | ||
| func {f.name} : {type}{sep}\ | ||
| {body}" | ||
|
|
||
| -- Provide explicit instance for LFunc to ensure proper resolution | ||
| -- Requires ToFormat for T.IDMeta (for identifiers in expressions) and T.Metadata (for Inhabited LExpr) | ||
| instance [ToFormat T.IDMeta] [Inhabited T.Metadata] : ToFormat (LFunc T) where | ||
| format := format | ||
|
|
||
| def LFunc.type [DecidableEq T.IDMeta] (f : (LFunc T)) : Except Format LTy := do | ||
| if !(decide f.inputs.keys.Nodup) then | ||
| .error f!"[{f.name}] Duplicates found in the formals!\ | ||
|
|
||
This file contains hidden or 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
This file contains hidden or 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
This file contains hidden or 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
This file contains hidden or 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
This file contains hidden or 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
This file contains hidden or 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
Oops, something went wrong.
Oops, something went wrong.
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.
Why doesn't this hold for general
Func? Is it because there is no generic notion of "variable in an expression"?