Commit Graph

709 Commits

Author SHA1 Message Date
Louis Gesbert
41d6d3cbe9 Make scopes directly callable
Quite a few changes are included here, some of which have some extra
implications visible in the language:

- adds the `Scope of { -- input_v: value; ... }` construct in the language

- handle it down the pipeline:
  * `ScopeCall` in the surface AST
  * `EScopeCall` in desugared and scopelang
  * expressions are now traversed to detect dependencies between scopes
  * transformed into a normal function call in dcalc

- defining a scope now implicitely defines a structure with the same name, with
  the output variables of the scope defined as fields. This allows us to type
  the return value from a scope call and access its fields easily.
  * the implications are mostly in surface/name_resolution.ml code-wise
  * the `Scope_out` struct that was defined in scope_to_dcalc is no longer
    needed/used and the fields are no longer renamed (changes some outputs; the
    explicit suffix for variables with multiple states is ignored as well)
  * one benefit is that disambiguation works just like for structures when there
    are conflicts on field names
  * however, it's now a conflict if a scope and a structure have the same
    name (side-note: issues with conflicting enum / struct names or scope
    variables / subscope names were silent and are now properly reported)

- you can consequently use scope names as types for variables as well. Writing
  literals is not allowed though, they can only be obtained by calling the
  scope.

Remaining TODOs:

- context variables are not handled properly at the moment

- error handling on invalid calls

- tests show a small error message regression; lots of examples will need
  tweaking to avoid scope/struct name or struct fields / output variable
  conflicts

- add a `->` syntax to make struct field access distinct from scope output var
  access, enforced with typing. This is expected to reduce confusion of users
  and add a little typing precision.

- document the new syntax & implications (tutorial, cheat-sheet)

- a consequence of the changes is that subscope variables also can now be typed.
  A possible future evolution / simplification would be to rewrite subscopes as
  explicit scope calls early in the pipeline. That could also allow to manipulate
  them as expressions (bind them in let-ins, return them...)
2022-10-21 17:17:26 +02:00
Louis Gesbert
7267543ca1 Rename Expr.Box.inj to Expr.Box.lift
it is more consistent with the naming of functions in Bindlib.
2022-10-21 15:35:49 +02:00
Louis Gesbert
f9f834e30a Add a helper to fold on expressions 2022-10-21 15:35:49 +02:00
Louis Gesbert
f103fb1ea5 Typing: be strict about no TAny remaining
Ideally we could replace `TAny` by an option on the whole type, and have untyped
/ partially typed / fully typed terms.
2022-10-21 15:26:16 +02:00
Louis Gesbert
19d0c35961 Printer: less verbose variables printing
Pass along a bindlib context to allow the variable names to be altered only when
disambiguation is needed. Partial fix to #240 (doesn't affect the backends, only
the printer for the intermediate ASTs).

This also has the benefit of making the output of the tests much more stable.
2022-10-19 14:40:58 +02:00
Louis Gesbert
f9de650d62 Magic * 2022-10-07 18:01:04 +02:00
Louis Gesbert
7bcafa4ead Fix bug in bindlib use
This is a workaround (but corresponds to what was executed before) and means
that we re-explore all exprs to look for free variables.

The proper fix will be to store boxed_exprs inside scopes instead.
2022-10-07 18:00:59 +02:00
Louis Gesbert
e925ec1795 Swap boxing and annotations in expressions
This was the only reasonable solution I found to the issue raised
[here](https://github.com/CatalaLang/catala/pull/334#discussion_r987175884).

This was a pretty tedious rewrite, but it should now ensure we are doing things
correctly. As a bonus, the "smart" expression constructors are now used
everywhere to build expressions (so another refactoring like this one should be
much easier) and this makes the code overall feel more
straightforward (`Bindlib.box_apply` or `let+` no longer need to be visible!)

---

Basically, we were using values of type `gexpr box = naked_gexpr marked box`
throughout when (re-)building expressions. This was done 99% of the time by
using `Bindlib.box_apply add_mark naked_e` right after building `naked_e`. In
lots of places, we needed to recover the annotation of this expression later on,
typically to build its parent term (to inherit the position, or build the type).

Since it wasn't always possible to wrap these uses within `box_apply` (esp. as
bindlib boxes aren't a monad), here and there we had to call `Bindlib.unbox`,
just to recover the position or type. This had the very unpleasant effect of
forcing the resolution of the whole box (including applying any stored closures)
to reach the top-level annotation which isn't even dependant on specific
variable bindings. Then, generally, throwing away the result.

Therefore, the change proposed here transforms
- `naked_gexpr marked Bindlib.box` into
- `naked_gexpr Bindlib.box marked` (aliased to `boxed_gexpr` or `gexpr boxed` for
convenience)

This means only
1. not fitting the mark into the box right away when building, and
2. accessing the top-level mark directly without unboxing

The functions for building terms from module `Shared_ast.Expr` could be changed
easily. But then they needed to be consistently used throughout, without
manually building terms through `Bindlib.apply_box` -- which covers most of the
changes in this patch.

`Expr.Box.inj` is provided to swap back to a box, before binding for example.

Additionally, this gives a 40% speedup on `make -C examples pass_all_tests`,
which hints at the amount of unnecessary work we were doing --'
2022-10-07 18:00:23 +02:00
Louis Gesbert
6c8a9f830c Compute the Dcalc stage when running catala Typecheck
it has some important resolution/sanity checks
2022-10-07 17:41:27 +02:00
Louis Gesbert
14f1ebfd0a Reformat 2022-10-04 14:50:37 +02:00
Louis Gesbert
ea114bada2 Fix one more typing mismatch 2022-10-04 14:50:37 +02:00
Louis Gesbert
920b3679df Some more fixes for remaining invalid typing 2022-10-04 14:50:37 +02:00
Louis Gesbert
5da55f1605 Fix some remaining invalid type annots 2022-10-04 14:50:37 +02:00
Louis Gesbert
5bb694c7b8 scope_to_dcalc: fix propagating wrong types
fill with TAny when building non-trivial things instead (in particular the
toplevel scope structure)
2022-10-04 14:50:37 +02:00
Louis Gesbert
0fdefacf7c Add marks to scopelang Call 2022-10-04 14:50:37 +02:00
Louis Gesbert
749810625f Activate double typing 2022-10-04 14:50:37 +02:00
Louis Gesbert
41315dc650 Scopelang: add toplevel mark for convenience
it allows to discriminate typed and non-typed ASTs
2022-10-04 14:50:37 +02:00
Louis Gesbert
9349fb918d Scope: fix getting external body mark 2022-10-04 14:50:37 +02:00
Louis Gesbert
742c4acb3e Expr.make_app: fix assertion to allow for TAny values 2022-10-04 14:50:37 +02:00
Louis Gesbert
e17baac840 Printer: add debug version that doesn't require a context
very handy sometimes...
2022-10-04 14:50:37 +02:00
Louis Gesbert
fd3219a34e Catala driver: re-run the typer after dcalc compilation 2022-10-04 14:50:37 +02:00
Louis Gesbert
0dbc4c8c35 Separate type ordering from scopelang->dcalc transformation
it's now done explicitely from the driver, which allows to do it before typing
and is more consistent; the information was already forwarded to the later
compilation stages separately from the program AST anyway.
2022-10-04 14:50:37 +02:00
Louis Gesbert
ff76d0498f Make the typer use (and check) already existing annotations, if any 2022-10-04 14:50:37 +02:00
Louis Gesbert
76d1c1cc93 Dcalc.Optimization should reasonably preserve types
since it only does reductions while preserving marks. The patch is mostly a
renaming from `pos` to `mark`
2022-10-04 14:50:37 +02:00
Louis Gesbert
4d8bc20fcd Test new typing 2022-10-04 14:50:37 +02:00
Louis Gesbert
3b4b070aaa Fix typing 2022-10-04 14:50:37 +02:00
Louis Gesbert
2955ef3235 Implement typing at the scopelang level 2022-10-04 14:50:37 +02:00
Louis Gesbert
9f7a0f6078 Fix naming error in interface
Hmm I used too much `sed` and overlooked this one
(patch looks big because of reformatting, but it's mostly just `naked_expr`→`expr`)
2022-10-04 14:50:37 +02:00
Louis Gesbert
05f4bb3537 Typing: simplify interface, split code in smaller functions 2022-10-04 14:50:37 +02:00
Louis Gesbert
51f79af13e Generalise the types to allow scopelang ASTs to be typed 2022-10-04 14:50:37 +02:00
Louis Gesbert
0ad51b7aec Unify outermost types first in Typing.top_down
It doesn't actually change the error output much, but is more sound, and allowed
to fix a few quirks in the code.
2022-10-04 14:50:37 +02:00
Louis Gesbert
a8816eb9e4 Fix parser message that didn't make sense to me
I had the message appear after a `integer_to_decimal` not followed by `of`, but
might it happen in other cases ?
2022-10-04 14:50:37 +02:00
Louis Gesbert
af9f497ffb Implement typing of desugared/scopelang and lcalc terms
Note that this is incomplete in the case of desugared/scopelang because we only
have typing for expressions yet, and the scope/program structure is different.

The code allows passing an environment of types for scope/subscope variables in
order to resolve `ELocation` terms, but that's unused until we implement
scopelang typing at the scope level.
2022-10-04 14:50:37 +02:00
Louis Gesbert
b37a6c3703 Generalise the typer
This moves dcalc/typing.ml to shared_ast, and generalises the input type, but
without yet implementing the extra cases (these are all `assert false`): it's
just a first step.
2022-10-04 14:50:37 +02:00
Louis Gesbert
0bb9cce341 Simplify a few mark operations 2022-10-04 14:50:37 +02:00
Louis Gesbert
d93b699a4c Forward types in the Expr.make_* constructors
Also add some safeguards against bad propagation of types (e.g. checking the
arrow type of functions upon application); partly disabled at the moment since
they don't pass yet but that'll be further work.
2022-10-04 14:50:37 +02:00
Louis Gesbert
a41de29293 Improve typing error message on <any> array
- don't print variable id on type variables, there should be no ambiguity
- print "array" as "collection" to match the language
- print just "collection" for "'a collection", which makes sense english-wise
2022-09-26 14:29:15 +02:00
Louis Gesbert
c18de3b980 Tweak the order in which typing is done 2022-09-26 14:11:25 +02:00
Louis Gesbert
76569bb1af Fix position on type error concerning sub-scope variable 2022-09-26 14:11:25 +02:00
Louis Gesbert
498429e4b7 Fix type-checking error getting delayed
The issue was coming from Bindlib: it stores variable bindings as closures, so
`Bindlib.box_apply f bx` actually delays the application of `f` until the term
is substituted or unboxed (likely long after we are out of the `try..with`
block).

The proposed fix is to make sure we run the wrapper outside of bindlib
applications, on explicitely unboxed terms.
2022-09-26 14:11:25 +02:00
Louis Gesbert
8bf6b5b821 Type arrow return types first 2022-09-26 14:11:25 +02:00
Louis Gesbert
2c3be946ec Keep type positions on the right-hand side upon unification of types
This should result in more predictable error messages. Right-hand is arbitrary,
but has been found empirically to give better results.
2022-09-26 14:11:25 +02:00
Denis Merigoux
f1d0831d86
LégiFrance<->Catala connector (#329) 2022-09-19 11:14:21 +02:00
Aymeric Fromherz
7f07274c1f Ignore unfound (i.e., internal) variables during Z3 model printing 2022-09-13 15:54:26 +02:00
Aymeric Fromherz
fee64d6f6f format 2022-09-13 10:37:30 +02:00
Aymeric Fromherz
b7854eb6f3 Z3Backend: Use type information inside AST node for match translation 2022-09-13 10:33:02 +02:00
Aymeric Fromherz
ea13981c5d Match annotation type in io.mli and in Z3 backend 2022-09-12 18:10:02 +02:00
Aymeric Fromherz
0592cdab2a Z3encoding: Use auxiliary variable for encoding type-generic EMatch 2022-09-12 17:52:55 +02:00
Denis Merigoux
8445174a5b
Improvements to expiration checking 2022-09-07 17:14:22 +02:00
Denis Merigoux
d7e219b0dd
Correct test output for proof mode 2022-09-06 14:10:32 +02:00