diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d65c69da..b8222ed2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -38,7 +38,7 @@ and articles markers: ### Sub-heading (the more '#', the less important) -#### [Legislative atom] +#### Legislative atom ``` Please look at the code of other examples to see how to format things properly. @@ -53,19 +53,19 @@ to see if you've made any syntax errors. Once the text formatting is done, you can start to annotate each legislative atom (article, provision, etc.) with some Catala code. To open up a code section in Catala, simply use -~~~markdown +````markdown ```catala # In code sections, comments start with # scope Foo: ``` -~~~ +```` While all the code sections are equivalent in terms of execution, you can mark some as "metadata" so that they are printed differently on lawyer-facing documents. Here's how it works: -~~~markdown +````markdown > Begin metadata # > Début métadonnées en français ```catala @@ -77,7 +77,7 @@ declaration structure FooBar: ``` > End metadata # > Fin métadonnées en français -~~~ +```` Again, make sure to regularly check that your example is parsing correctly. The error message from the compiler should help you debug the syntax if need be. You can also live-test the programs you wrote by feeding them to the interpreter @@ -124,7 +124,7 @@ general-to-specifics statutes order. Therefore, there exists multiple versions of the Catala surface syntax, adapted to the language of the legislative text. Currently, Catala supports English and French legislative text via the -`--language=en`, `--language=fr` or `--language=pl` option. +`--language=en`, `--language=fr` or `--language=pl` option. Technically, support for new languages can be added via a new lexer. If you want to add a new language, you can start from diff --git a/Makefile b/Makefile index d1be5504..338b5982 100644 --- a/Makefile +++ b/Makefile @@ -115,7 +115,7 @@ vscode_en: ${CURDIR}/syntax_highlighting/en/setup_vscode.sh vscode: vscode_fr vscode_en ########################################## -# Examples-related rules +# Literate programming and examples ########################################## EXAMPLES_DIR=examples @@ -154,6 +154,81 @@ literate_polish_taxes: build literate_examples: literate_allocations_familiales literate_code_general_impots \ literate_us_tax_code literate_tutorial_en literate_tutoriel_fr literate_polish_taxes +########################################## +# French law library +########################################## + +#----------------------------------------- +# OCaml +#----------------------------------------- + +FRENCH_LAW_OCAML_LIB_DIR=french_law/ocaml + +$(FRENCH_LAW_OCAML_LIB_DIR)/law_source/allocations_familiales.ml: .FORCE + CATALA_OPTS="$(CATALA_OPTS) -O -t" $(MAKE) -C $(ALLOCATIONS_FAMILIALES_DIR) allocations_familiales.ml + cp -f $(ALLOCATIONS_FAMILIALES_DIR)/allocations_familiales.ml $@ + +$(FRENCH_LAW_OCAML_LIB_DIR)/law_source/unit_tests/tests_allocations_familiales.ml: .FORCE + CATALA_OPTS="$(CATALA_OPTS) -O -t" $(MAKE) -s -C $(ALLOCATIONS_FAMILIALES_DIR) tests/tests_allocations_familiales.ml + cp -f $(ALLOCATIONS_FAMILIALES_DIR)/tests/tests_allocations_familiales.ml $@ + +#> generate_french_law_library_ocaml : Generates the French law library OCaml sources from Catala +generate_french_law_library_ocaml:\ + $(FRENCH_LAW_OCAML_LIB_DIR)/law_source/allocations_familiales.ml \ + $(FRENCH_LAW_OCAML_LIB_DIR)/law_source/unit_tests/tests_allocations_familiales.ml + $(MAKE) format + +#> build_french_law_library_ocaml : Builds the OCaml French law library +build_french_law_library_ocaml: generate_french_law_library_ocaml format + dune build $(FRENCH_LAW_OCAML_LIB_DIR)/api.a + +run_french_law_library_benchmark_ocaml: generate_french_law_library_ocaml + dune exec --profile release $(FRENCH_LAW_OCAML_LIB_DIR)/bench.exe + +run_french_law_library_ocaml_tests: build_french_law_library_ocaml + dune exec $(FRENCH_LAW_OCAML_LIB_DIR)/law_source/unit_tests/run_tests.exe + + +#----------------------------------------- +# JS +#----------------------------------------- + +FRENCH_LAW_JS_LIB_DIR=french_law/js + +run_french_law_library_benchmark_js: build_french_law_library_js + $(MAKE) -C $(FRENCH_LAW_JS_LIB_DIR) bench + +#> build_french_law_library_js : Builds the JS version of the OCaml French law library +build_french_law_library_js: generate_french_law_library_ocaml format + dune build --profile release $(FRENCH_LAW_OCAML_LIB_DIR)/api_web.bc.js + cp -f $(ROOT_DIR)/_build/default/$(FRENCH_LAW_OCAML_LIB_DIR)/api_web.bc.js $(FRENCH_LAW_JS_LIB_DIR)/french_law.js + + +#----------------------------------------- +# Python +#----------------------------------------- + +FRENCH_LAW_PYTHON_LIB_DIR=french_law/python + +$(FRENCH_LAW_PYTHON_LIB_DIR)/src/allocations_familiales.py: .FORCE + CATALA_OPTS="$(CATALA_OPTS) -O -t" $(MAKE) -C $(ALLOCATIONS_FAMILIALES_DIR) allocations_familiales.py + cp -f $(ALLOCATIONS_FAMILIALES_DIR)/allocations_familiales.py $@ + +#> generate_french_law_library_python : Generates the French law library Python sources from Catala +generate_french_law_library_python:\ + $(FRENCH_LAW_PYTHON_LIB_DIR)/src/allocations_familiales.py + . $(FRENCH_LAW_PYTHON_LIB_DIR)/env/bin/activate ;\ + $(MAKE) -C $(FRENCH_LAW_PYTHON_LIB_DIR) format + +#> type_french_law_library_python : Types the French law library Python sources with mypy +type_french_law_library_python: generate_french_law_library_python + . $(FRENCH_LAW_PYTHON_LIB_DIR)/env/bin/activate ;\ + $(MAKE) -C $(FRENCH_LAW_PYTHON_LIB_DIR) type + +run_french_law_library_benchmark_python: type_french_law_library_python + . $(FRENCH_LAW_PYTHON_LIB_DIR)/env/bin/activate ;\ + $(MAKE) -C $(FRENCH_LAW_PYTHON_LIB_DIR) test + ########################################## # High-level test and benchmarks commands ########################################## @@ -182,65 +257,6 @@ bench_js: run_french_law_library_benchmark_js bench_python: run_french_law_library_benchmark_python -########################################## -# French law library -########################################## - -FRENCH_LAW_OCAML_LIB_DIR=french_law/ocaml -FRENCH_LAW_JS_LIB_DIR=french_law/js -FRENCH_LAW_PYTHON_LIB_DIR=french_law/python - -$(FRENCH_LAW_PYTHON_LIB_DIR)/src/allocations_familiales.py: .FORCE - CATALA_OPTS="$(CATALA_OPTS) -O -t" $(MAKE) -C $(ALLOCATIONS_FAMILIALES_DIR) allocations_familiales.py - cp -f $(ALLOCATIONS_FAMILIALES_DIR)/allocations_familiales.py $@ - -$(FRENCH_LAW_OCAML_LIB_DIR)/law_source/allocations_familiales.ml: .FORCE - CATALA_OPTS="$(CATALA_OPTS) -O -t" $(MAKE) -C $(ALLOCATIONS_FAMILIALES_DIR) allocations_familiales.ml - cp -f $(ALLOCATIONS_FAMILIALES_DIR)/allocations_familiales.ml $@ - -$(FRENCH_LAW_OCAML_LIB_DIR)/law_source/unit_tests/tests_allocations_familiales.ml: .FORCE - CATALA_OPTS="$(CATALA_OPTS) -O -t" $(MAKE) -s -C $(ALLOCATIONS_FAMILIALES_DIR) tests/tests_allocations_familiales.ml - cp -f $(ALLOCATIONS_FAMILIALES_DIR)/tests/tests_allocations_familiales.ml $@ - -#> generate_french_law_library_ocaml : Generates the French law library OCaml sources from Catala -generate_french_law_library_ocaml:\ - $(FRENCH_LAW_OCAML_LIB_DIR)/law_source/allocations_familiales.ml \ - $(FRENCH_LAW_OCAML_LIB_DIR)/law_source/unit_tests/tests_allocations_familiales.ml - $(MAKE) format - -#> build_french_law_library_ocaml : Builds the OCaml French law library -build_french_law_library_ocaml: generate_french_law_library_ocaml format - dune build $(FRENCH_LAW_OCAML_LIB_DIR)/api.a - -run_french_law_library_benchmark_ocaml: generate_french_law_library_ocaml - dune exec --profile release $(FRENCH_LAW_OCAML_LIB_DIR)/bench.exe - -run_french_law_library_ocaml_tests: build_french_law_library_ocaml - dune exec $(FRENCH_LAW_OCAML_LIB_DIR)/law_source/unit_tests/run_tests.exe - -run_french_law_library_benchmark_js: build_french_law_library_js - $(MAKE) -C $(FRENCH_LAW_JS_LIB_DIR) bench - -#> build_french_law_library_js : Builds the JS version of the OCaml French law library -build_french_law_library_js: generate_french_law_library_ocaml format - dune build --profile release $(FRENCH_LAW_OCAML_LIB_DIR)/api_web.bc.js - cp -f $(ROOT_DIR)/_build/default/$(FRENCH_LAW_OCAML_LIB_DIR)/api_web.bc.js $(FRENCH_LAW_JS_LIB_DIR)/french_law.js - -#> generate_french_law_library_python : Generates the French law library Python sources from Catala -generate_french_law_library_python:\ - $(FRENCH_LAW_PYTHON_LIB_DIR)/src/allocations_familiales.py - . $(FRENCH_LAW_PYTHON_LIB_DIR)/env/bin/activate ;\ - $(MAKE) -C $(FRENCH_LAW_PYTHON_LIB_DIR) format - -#> type_french_law_library_python : Types the French law library Python sources with mypy -type_french_law_library_python: generate_french_law_library_python - . $(FRENCH_LAW_PYTHON_LIB_DIR)/env/bin/activate ;\ - $(MAKE) -C $(FRENCH_LAW_PYTHON_LIB_DIR) type - -run_french_law_library_benchmark_python: type_french_law_library_python - . $(FRENCH_LAW_PYTHON_LIB_DIR)/env/bin/activate ;\ - $(MAKE) -C $(FRENCH_LAW_PYTHON_LIB_DIR) test - ########################################## # Website assets diff --git a/README.md b/README.md index 892d9c92..2dab63db 100644 --- a/README.md +++ b/README.md @@ -75,21 +75,30 @@ them, use ## Examples -See [the dedicated readme](examples/README.md). +To explore the different programs written in Catala, see +[the dedicated readme](examples/README.md). + +## API + +To know how to use the code generated by the Catala compiler in your favorite +programming language, head to the [readme of the French law library](french_law/README.md) ## Contributing -See [the dedicated readme](CONTRIBUTING.md). +To know how you can contribute to the project, see +[the dedicated readme](CONTRIBUTING.md). ## Test suite -See [the dedicated readme](tests/README.md). +To know how to run or improve the Catala reference test suite, +see [the dedicated readme](tests/README.md). ## Documentation ### Formal semantics -See [the dedicated readme](doc/formalization/README.md). +To audit the formal proof of the partial certification of the Catala compiler, +see [the dedicated readme](doc/formalization/README.md). ### Compiler documentation @@ -103,7 +112,9 @@ The documentation is also accessible [online](https://catala-lang.org/ocaml_docs ## License -The library is released under the [Apache license (version 2)](LICENSE.txt). +The compiler and all the code contained in this repository is released under +the [Apache license (version 2)](LICENSE.txt) unless another license is explicited +for a sub-directory. ## Limitations and disclaimer diff --git a/french_law/README.md b/french_law/README.md new file mode 100644 index 00000000..8f25feaf --- /dev/null +++ b/french_law/README.md @@ -0,0 +1,30 @@ +# French Law Libraries + +This folder presents a working example of how Catala could be distributed and +deployed inside existing applications. Each sub-folder is specialized for +a particular programming language, and features a ready-to-use library of +all the French public algorithms coded up using Catala so far. + +## General principles + +Let us say you want to deploy a Catala program inside an application written +in programming language X. The Catala compiler will translate the source +Catala program into X, yielding a new `.x` source code file. This `.x` file +will export functions corresponding to the scopes of the original Catala +program. You can then reuse those exported functions in your application written +in X. + +## OCaml + +To see how to deploy Catala programs as an OCaml library, see +[the dedicated readme](ocaml/README.md). + +## JS + +To see how to deploy Catala programs as a JS library, see +[the dedicated readme](js/README.md). + +## Python + +To see how to deploy Catala programs as a Python library, see +[the dedicated readme](Python/README.md). diff --git a/french_law/js/README.md b/french_law/js/README.md index c03e57f5..0be57469 100644 --- a/french_law/js/README.md +++ b/french_law/js/README.md @@ -1,10 +1,26 @@ -# The French Law Javascript Library +# Javascript French Law Library -This Javascript library contains some computations defined by French -legislative texts. The JS code is extracted from OCaml, which is itself -extracted from Catala code (https://catala-lang.org). +This folder contains a ready-to-use Javascript library featuring French public +algorithms coded up in Catala. -## Allocations familiales +## Generating the source files + +The JS code is extracted from OCaml using +[`js_of_ocaml`](https://ocsigen.org/js_of_ocaml/). See the +[dedicated README](../ocaml/README.md) of the OCaml library for more precisions +about the OCaml code. The wrapping between OCaml and JS is done by the +`api_web.ml` module. + +You can generate the `french_law.js` source JS module by invoking this command +from the root of the repository: + +``` +make build_french_law_library_js +``` + +## Available algorithms + +### Allocations familiales The function of the library is `computeAllocationsFamiliales`. This computation returns the amount of _allocations familiales_ for one household described diff --git a/french_law/ocaml/README.md b/french_law/ocaml/README.md new file mode 100644 index 00000000..a6161cdf --- /dev/null +++ b/french_law/ocaml/README.md @@ -0,0 +1,50 @@ +# OCaml French Law Library + +This folder contains a ready-to-use OCaml library featuring French public +algorithms coded up in Catala. + +## Organization + +### Law source + +The `law_source` folder contains the files generated by the Catala compiler. +These files are generated using the following rule from the top-level `Makefile` +of this repository: + +``` +make generate_french_law_library_ocaml +``` + +They can be compiled using + +``` +make build_french_law_library_ocaml +``` + +In particular, `law_source/unit_tests/run_tests.ml` provides an executable +that runs the unit tests coming from the source Catala examples, and that can +be launched with + +``` +make run_french_law_library_ocaml_tests +``` + +The `law_source` files rely on the Catala OCaml runtime, located in +`compiler/runtime.{ml, mli}`. This runtime defines the types of the values +manipulated by the Catala programs in OCaml and the operations available for them. + +### Wrappers + +Then, the `api.{ml, mli}` module provides a wrapper around the functions +exported in `law_source`. These wrappers mostly convert back and forth between +idiomatic OCaml types and the types expected by the Catala programs in OCaml. + +`api.web.ml` is used for the JS library (see the [dedicated README](../js/README.md)). + +Finally, `bench.ml` provides a simple benchmarking executable that runs the +computations of each algorithm a bunch of times with random inputs. You can run it +from the root of this repository with + +``` +make run_french_law_library_benchmark_ocaml +``` diff --git a/french_law/ocaml/law_source/unit_tests/run_tests.ml b/french_law/ocaml/law_source/unit_tests/run_tests.ml index 28aa04ed..136f6ec1 100644 --- a/french_law/ocaml/law_source/unit_tests/run_tests.ml +++ b/french_law/ocaml/law_source/unit_tests/run_tests.ml @@ -21,4 +21,6 @@ let _ = try_test "Allocations familiales #6" Tests_allocations_familiales.test6; try_test "Allocations familiales #7" Tests_allocations_familiales.test7; try_test "Allocations familiales #8" Tests_allocations_familiales.test8; + try_test "Allocations familiales #9" Tests_allocations_familiales.test9; + try_test "Allocations familiales #10" Tests_allocations_familiales.test10; exit (if !failure then -1 else 0) diff --git a/french_law/python/README.md b/french_law/python/README.md new file mode 100644 index 00000000..ef4bb940 --- /dev/null +++ b/french_law/python/README.md @@ -0,0 +1,43 @@ +# Python French Law Library + +This folder contains a ready-to-use Python library featuring French public +algorithms coded up in Catala. + +The Python version expected to run the Python code is above 3.6. For the commands +noted below to run, you are expected to setup a virtual Python environment with +`virtualenv` by running the `setup_env.sh` script. + +## Organization + +### Law source + +The `src/` folder contains the Python files generated by the Catala compiler. +To update them from the Catala sources, invoke this command from the root +of the repository: + +``` +make generate_french_law_library_python +``` + +The Python files generated by the Catala compiler expect the presence of the +`src/catala.py` file which contains the definitions of the values and operations +used by the generated code. + +All theses Python files feature type annotations which can be checked against +using + +``` +make make type_french_law_library_python +``` + +### Wrappers + +To use the algorithms in `src/`, you can take a look at the example provided in +`main.py`. It is very important to wrap all of the input parameters using +`src/catala.py` conversion functions. + +You can benchmark the computation using + +``` +make run_french_law_library_benchmark_python +```