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

Infer types of functions values based on names #400

Merged

Conversation

saulshanabrook
Copy link
Member

Previously, the type inference for creating function values with (unstable-fn <name> [<partial arg>]*) did not use the name. It would only use the context within which the function was created to infer the type of the function.

This works fine if you only have one function sort defined or if always can infer it based on its calling location. However, I was noticing in my usages of unstable-fn I would often be passing another function reference as a partial arg. This means it would be hard for the type checker to figure out what type to use for these, so it would just give up and fail.

In this PR, I extend the type inference for functions to use the string name. If it is a literal value that shows up during type checking and we can find it in the function table, we use this to help infer what the types are. We can then narrow down both the partial arg types and also make sure that the output and inputs to the function are the same as those of the UnstableFn sort. If not, then we know that this constructor won't match.

The main change I had to do to implement this was to pass the TypeInfo into the accept method of TypeConstraints, so that we could lookup the function name.

I also had to add a new ImpossibleConstraint error for when a function is constructed with a string that doesn't match the function sort.

@saulshanabrook saulshanabrook requested a review from a team as a code owner July 28, 2024 15:38
@saulshanabrook saulshanabrook requested review from ajpal and yihozhang and removed request for a team and ajpal July 28, 2024 15:38
Copy link
Collaborator

@yihozhang yihozhang left a comment

Choose a reason for hiding this comment

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

Looks great!

);
// If first arg is a literal string and we know the name of the function and can use that to know what
// types to expect
if let AtomTerm::Literal(_, Literal::String(ref name)) = arguments[0] {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Are there cases where the first argument is not a string? Like can you write programs like

(relation fns (String))
(fns "+")
(fns "-")
(fns "*")
(fns "/")
(rule ((fns op) (= v (unstable-app (unstable-fn op) 1 2))) ((extract v)))

I think it is not unfair to disallow programs like this and enforce the first argument to be a string literal.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Also, if the function is a primitive, it seems we cannot do much here, which is a pity.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah I kept support for when the first argument is not a string... I don't think it's important but it felt easier to keep supporting it then disallow it. And you can still get some type checking with it, just not based on the name.

And yes you are right, we don't support type checking with primitives... we could hard code those or try something more creative but I don't think it's necessary at the moment. I personally never refer to primitives functions directly like that and if you do, again, it is still supported just won't infer based on the name.

@saulshanabrook saulshanabrook merged commit d4accf6 into egraphs-good:main Jul 31, 2024
3 checks passed
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.

2 participants