Skip to content
This repository has been archived by the owner on Oct 28, 2022. It is now read-only.

First Order Uncurrying Analysis #79

Open
wants to merge 30 commits into
base: master
Choose a base branch
from
Open

First Order Uncurrying Analysis #79

wants to merge 30 commits into from

Conversation

tramhnt99
Copy link
Contributor

Issue link: #24

Copy link
Contributor

@vaivaswatha vaivaswatha left a comment

Choose a reason for hiding this comment

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

Tram, thank you for this PR and apologies for the delayed review. I have a bunch of minor comments. Overall the approach seems fine to me, but I want to do another pass over this to be sure that we haven't missed out anything.

(* The following analysis finds function candidates for Uncurrying.
Candidates must fulfill the following criteria to be uncurried:
* Have an arity of >= 2
* Are never partiall applied
Copy link
Contributor

Choose a reason for hiding this comment

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

typo: partially

~compare:(fun a a' -> Identifier.compare (fst a) (fst a'))
pl

(* Find is expressions is a Fun expr
Copy link
Contributor

Choose a reason for hiding this comment

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

Find is expressions if e is a Fun expr

If a `Fun` expression's immediate subexpression is not `Fun`,
arity of the expression is 1. Otherwise, if the subexpression
if `Fun`, then the arity is one more then the immediate `Fun`
expression.
Copy link
Contributor

Choose a reason for hiding this comment

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

expression's arity.

*)
let find_function_arity (e, annot) =
let rec iter_funcs (e', _) acc =
let res =
Copy link
Contributor

Choose a reason for hiding this comment

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

let res = ...

in
res

can be replaced by just the inner expression.

(* if a pair (f,0) exists, f already won't be considered for uncurrying
(f,0) indicates that the function was used as a higher order function
*)
let is_to_uncur =
Copy link
Contributor

Choose a reason for hiding this comment

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

is_to_uncur can_uncurry

(* Environment @ienv contains functions within scope that HAVE been uncurried
and their uncurried types *)
(* Function to uncurry Func expressions (wrapped in GasExpr) *)
let rec uncurry_func_epxr newname ienv fe =
Copy link
Contributor

Choose a reason for hiding this comment

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

*expr

"Uncurry: internal error: uncurry_func_epxr has no Gas rapped \
around Fun."
in
let fun_rep' =
Copy link
Contributor

Choose a reason for hiding this comment

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

This is doing the same thing as let new_rep = ..., maybe you can have a small function that can be called at both places.

* translate_expr does not return an environment because the scope of
newly defined functions in expr ends there
*)
(* If functions that are NOT uncurried, their App will be transformed apply arguments
Copy link
Contributor

Choose a reason for hiding this comment

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

Translate functions and their applications into the uncurried syntax. For functions that are uncurried (i.e., sequence of nested functions which are rewritten into a single function with multiple arguments), their applications will have multiple arguments too. For functions which aren't uncurried, they application will be transformed to apply single arguments in separate steps, because the AST must still follow uncurried semantics.

( UCS.GasExpr (StaticCost static_gas, (UCS.Fun (params', body'), fun_rep')),
new_rep' )

(* Note:
Copy link
Contributor

Choose a reason for hiding this comment

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

This Note can go along with Note after the function description.

| App (a, l) ->
let a' = translate_var a in
(* If the function was uncurried *)
if Identifier.is_mem_id a' (fst @@ List.unzip ienv) then
Copy link
Contributor

Choose a reason for hiding this comment

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

This involves two traversals over the list. It's simpler to just search for 'a in the zipped list by using List.mem directly

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants