French Tax Code
French Tax Code
Abstract how to compute the final amount of income tax (IR, for impôt
In France, income tax is computed from taxpayers’ individ- sur le revenu) owed by each household.
ual returns, using an algorithm that is authored, designed As in many other tax systems around the world, this com-
arXiv:2011.07966v2 [cs.PL] 26 Nov 2020
and maintained by the French Public Finances Directorate putation is quite complex. France uses a bracket system (as
(DGFiP). This algorithm relies on a legacy custom language in, say, the US federal income tax), along with a myriad of tax
and compiler originally designed in 1990, which unlike French credits, deductions, optional rules, state-sponsored direct aid,
wine, did not age well with time. Owing to the shortcom- all of which are parameterized over the composition of the
ings of the input language and the technical limitations of household, that is, the number of children, their respective
the compiler, the algorithm is proving harder and harder ages, potential disabilities, and so on.
to maintain, relying on ad-hoc behaviors and workarounds Unlike, say, the United States, the French system relies
to implement the most recent changes in tax law. Compe- heavily on automation. During tax season, French taxpayers
tence loss and aging code also mean that the system does not log in to the online tax portal, which is managed by the state.
benefit from any modern compiler techniques that would There, taxpayers are presented with online forms, generally
increase confidence in the implementation. pre-filled. If applicable, taxpayers can adjust the forms, e.g.
We overhaul this infrastructure and present Mlang, an by entering extra deductions or credits. Once the taxpayer is
open-source compiler toolchain whose goal is to replace satisfied with the contents of the online form, they send in
the existing infrastructure. Mlang is based on a reverse- their return. Behind the scenes, the IR algorithm is run, and
engineered formalization of the DGFiP’s system, and has taking as input the contents of the forms, returns the final
been thoroughly validated against the private DGFiP test amount of tax owed. The taxpayer is then presented with
suite. As such, Mlang has a formal semantics; eliminates the result at tax-collection time.
previous hand-written workarounds in C; compiles to mod- Naturally, the ability to independently reproduce and thus
ern languages (Python); and enables a variety of instrumen- trust the IR computation performed by the DGFiP is crucial.
tations, providing deep insights about the essence of French First, taxpayers need to understand the result, as their own
income tax computation. The DGFiP is now officially transi- estimate may differ (explainability). Second, citizens may
tioning to Mlang for their production system. want to audit the algorithm, to ensure it faithfully imple-
ments the law (correctness). Third, a standalone, reusable
CCS Concepts: • Software and its engineering → Gen- implementation allows for a complete and precise simulation
eral programming languages; • Social and professional of the impacts of a tax reform, greatly improving existing
topics → History of programming languages. efforts [8, 17] (forecasting).
Keywords: legal expert system, compiler, tax code Unfortunately, we are currently far from a transparent,
open-source, reproducible computation. Following numer-
ACM Reference Format: ous requests (using a disposition similar to the United State’s
Denis Merigoux, Raphaël Monat, and Jonathan Protzenko. 2020. Freedom of Information Act), parts of the existing source
A Modern Compiler for the French Tax Code. In Proceedings of code were published. In doing so, the public learned that
Preprint. ACM, New York, NY, USA, 12 pages.
i) the existing infrastructure is made up of various parts
pieced together and that ii) key data required to accurately
1 Introduction reproduce IR computations was not shared with the public.
The French Tax Code is a body of legislation amounting to The current, legacy architecture of the IR tax system is
roughly 3,500 pages of text, defining the modalities of tax presented in Fig. 1. The bulk of the tax code is described as a
collection by the state. In particular, each new fiscal year, a set of “rules” authored in M, a custom, non Turing-complete
new edition of the Tax Code describes in natural language language. A total of 90,000 lines of M rules compile to 535,000
lines of C (including whitespace and comments) via a custom
∗ Equal contribution compiler. Rules are now mostly public [10]. Over time, the
expressive power of rules turned out to be too limited to
Preprint, Nov. 2020, Online
express a particular feature, known as liquidations multiples,
2020.
Preprint, Nov. 2020, Online Denis Merigoux, Raphaël Monat, and Jonathan Protzenko
For the rest of this paper, we abandon concrete syntax and all- ∐︀program̃︀ ::= ∐︀command̃︀ | ∐︀command̃︀ ; ∐︀program̃︀
caps variable names, in favor of a core calculus that faithfully ∐︀command̃︀ ::= if ∐︀expr̃︀ then ∐︀error̃︀
models M: 𝜇M. | ∐︀var̃︀ := ∐︀expr̃︀ | ∐︀var̃︀ [ X ; ∐︀float̃︀ ] := ∐︀expr̃︀
2.3 Syntax of 𝜇M
We describe the syntax of 𝜇M in Fig. 2. A program is a se- has been left blank) but may still be referred in other rules.
quence of commands (“rules”). Commands are either raise- Rather than introduce spurious variable assignments with
error-if, or assignments. We define two forms of assignment: undef, we remain faithful to the very loose nature of the M
one for scalars and the other for fixed-size arrays. The latter language and account for references to undefined variables.
is of the form a[X, n] := e, where X is bound in e (the in- Then, Γ ⊢ ∐︀program̃︀ ⇛ Γ ′ enforces well-formedness for
dex is always named X). Using Haskell’s list comprehension a whole program while returning an extended environment
syntax, this is to be understood as 𝑎 ∶= (︀𝑒⋃︀𝑋 ← (︀0..𝑛 − 1⌋︀⌋︀. Γ ′ . We take advantage of the fact that scalar and array as-
Expressions are a combination of variables (including the signments have different syntactic forms. M disallows as-
special index expression X), values, comparisons, logic and signing different types to the same variable; we rule this
arithmetic expressions, conditionals, calls to builtin func- out in T-Assign-*. A complete 𝜇M program is well-formed if
tions, or index accesses. Most functions exhibit standard ∅ ⊢ 𝑃 ⇛ _.
behavior on floating-point values, but M assumes the de-
fault IEEE-754 rounding mode, that is, rounding to nearest 2.5 Operational semantics of 𝜇M
and ties to even. The detailed behavior of each function is At this stage, seeing that there are neither unbounded loops
described in Fig. 6. nor user-defined (recursive) functions in the language, M is
Values can be undef, which arises in two situations: refer- obviously not Turing-complete. The language semantics are
ences to variables that have not been defined (i.e. for which nonetheless quite devious, owing to the undef value, which
the entry in the tax form has been left blank) and out of can be explicitly converted to a float via a + 0, as seen in
bounds array accesses. All other values are IEEE-754 double- earlier examples. We proceed to formalize them in Coq [29],
precision numbers, i.e. 64-bit floats. The earlier BOOLEAN type using the Flocq library [4]. This ensures we correctly ac-
(§2.1) is simply an alias for a float whose value is implicitly count for all cases related to the undef value, and guides the
0 or 1. There is no other kind of value, as a reference to an
implementation of Mlang (§3).
array variable is invalid. Function present discriminates the Expressions. The semantics of expressions is defined in
undef value from floats. Fig. 4. The memory environment, written Ω is a function
from variables to either scalar values (usually denoted 𝑣),
2.4 Typing 𝜇M or arrays (written (𝑣 0, . . . , 𝑣𝑛−1 )). A value absent from the
Types in 𝜇M are either scalar or array types. M does not offer environment evaluates to undef.
nested arrays. Therefore, typing is mostly about making sure The special array index variable X is evaluated as a normal
scalars and arrays are not mixed up. variable. Conditionals reduce normally, except when the
In Fig. 3, a first judgment Γ ⊢ 𝑒 defines expression well- guard is undef: in that case, the whole conditional evaluates
formedness. It rules out references to arrays, hence enforcing into undef. If an index evaluates to undef, the whole array
that expressions have type scalar and that no values of type access is undef. In the case of a negative out-of-bounds index
array can be produced. Furthermore, variables may have no access the result is 0; in the case of a positive out-of-bounds
assignment at all (if the underlying entry in the tax form index access the result is undef. Otherwise, the index is
Preprint, Nov. 2020, Online Denis Merigoux, Raphaël Monat, and Jonathan Protzenko
Figure 6. Function semantics. For context on round and truncate definitions, see §4.3
Call
Ω1 ⊢ M rules ⇛ Ω2 if f = call_m Ω3 (𝑌 ) = Ω1 (𝑌 ) if 𝑌 ∈⇑ 𝑋⃗
Δ, Ω1 ⊢ Δ(𝑓 ) ↝ Ω2 otherwise Ω3 (𝑌 ) = Ω2 (𝑌 ) if 𝑌 ∈ 𝑋⃗
Δ, Ω1 ⊢ 𝑋⃗ ← f() ↝ Ω3
Partition
Ω2 (𝑌 ) = undef if kind(𝑌 ) = 𝑘 Ω4 (𝑌 ) = Ω1 (𝑌 ) if kind(𝑌 ) = 𝑘 Delete
Δ, Ω2 ⊢ 𝑐 ↝ Ω3
Ω2 (𝑌 ) = Ω1 (𝑌 ) otherwise Ω4 (𝑌 ) = Ω3 (𝑌 ) otherwise Δ, Ω1 ⊢ v = undef ↝ Ω2
Δ, Ω1 ⊢ partition with k ∶ 𝑐 ↝ Ω4 Δ, Ω1 ⊢ del v ↝ Ω2
OCaml, with around 9,000 lines of code. The general archi- income tax computation is released. There are 214 inputs,
tecture is shown in Fig. 10. The M files and the M++ program and we chose 11 output variables. Basic accepts as inputs
are first parsed and transformed into intermediate represen- only the marital status and the salaries of each individual of
tations. These intermediate representations are inlined into the couple. The output is the income tax.
a single backend intermediate representation (BIR), consist-
ing of assignments and conditionals. Inlining is aware of
4.2 Optimizations
the semantic subtleties described in Fig. 9 and uses tempo-
rary variable assignments to save/restore the shared M/M++ In the 2018 tax code, the initial number of BIR instructions
scope. after inlining M
BIR code is then translated to the optimization intermedi- and M++ files together is 656,020. This essentially cor-
ate representation (OIR) in order to perform optimizations. responds to what the legacy compiler normally generates,
OIR is the control-flow-graph equivalent of BIR. since it performs no optimizations.
Additional assumptions. In M, a variable not defined in Thanks to its modern compiler architecture, Mlang can
the current memory environment evaluates to undef (rule easily perform numerous textbook optimizations, namely
D-Var-Undef, Fig. 4). This permissive behavior is fine for an dead code elimination, inlining and partial evaluation. This
interpreter which has a dynamic execution environment; allows greatly improving the quality of the generated code.
however, our goal is to generate efficient C and Python code The number of instructions after optimization is shown
that can be integrated into existing software. As such, declar- in Fig. 11. Without any assumption (All), the optimizations
ing every single one of the 27,113 shrink the generated C code to 15% of the unoptimized size
possible variables in C would be quite unsavory. (a factor of 6.5). With the most restrictive assumption file
We therefore devise a mechanism that allows stating ahead (Simplified), only 0.47% of the original instructions remain
of time which variables can be truly treated as inputs, and after optimization.
which are the outputs that we are interested in. Since these Definedness analysis. Due to the presence of undef, some
vary depending on the use-case, we choose to list these as- usual optimizations are not available. For example, optimiz-
sumptions in a separate file that can be provided alongside ing e * 0 into 0 is incorrect when e is undef, as undef * 0 =
with the M/M++ source code, rather than making this an in- undef. Similarly, e + 0 cannot be rewritten as e. Our partial
trinsic, immutable property set at variable-declaration time. evaluation is thus combined with a simple definedness anal-
Doing so increases the quality of the generated C or Python. ysis. The lattice of the analysis is shown in Fig. 12; we use
We call these assumption files; we have hand-written 5 of the standard sharp symbol of abstract interpretation [7] to
those. denote abstract elements. The transfer function absorb#
All is the empty file, i.e. no additional assumptions. This defined in Fig. 13 is used to compute the definedness in the
leaves 2459 input variables, and 10,411 output variables for case of the multiplication, the division and all operators in
the 2018 codebase. Selected outs enables all input variables, ∐︀boolop̃︀. The cast# transfer function is used for the addi-
but retains only 11 output variables. Tests corresponds to tion and the subtraction.
the inputs and outputs used in the test files used by the This definedness analysis enables finer-grained partial
DGFiP. Simplified corresponds to the simplified simulator evaluation rules, such as those presented in Fig. 14.
released each year by the DGFiP a few months before the full The optimizations for + 0 and * 0 are invalid in the pres-
ence of IEEE-754 special values (NaN, minus zero, infinities)
Preprint, Nov. 2020, Online Denis Merigoux, Raphaël Monat, and Jonathan Protzenko
assumptions.m_spec Python
5 Analyzing and Evaluating the Tax Code Scheme M compiler C compiler Bin. size Time
Due to the sheer size of the code and number of variables, Original DGFiP GCC -O0 7 Mo ∼ 1 ms
generating efficient code is somewhat delicate – we had the Original DGFiP GCC -O1 7 Mo ∼ 1 ms
pleasure of breaking both the Clang and Python parsers Local vars Mlang Clang -O0 33 Mo ∼ 2 ms
because of an exceedingly naïve translation. Thankfully, ow- Local vars Mlang Clang -O1 19 Mo ∼ 1 ms
ing to our flexible architecture for Mlang, we were able to Array Mlang Clang -O0 19 Mo ∼ 1 ms
quickly iterate and evaluate several design choices. Array Mlang Clang -O1 10 Mo ∼ 0.5 ms
We now show the benefits of a modern compiler infras-
tructure, and proceed to describe a variety of instrumen- Figure 16. Performance of the C code generated by various
tations, techniques and tweaking knobs that allowed us to compilation schemes for the M code. The time measured is the
gain insights on the the tax computation. By bringing the M time spent inside the main tax computation function for one fiscal
language into the 21st century, we not only greatly enhance household picked in the set of test cases. Size of the compiled binary
the quality of the generated code, but also unlock a host of is indicated. “Original” corresponds to the DGFiP’s legacy system.
techniques that significantly increase our confidence in the “Local vars” corresponds to Mlang’s C backend mapping each M
French tax computation. variable to a C local variable. “Array” corresponds to Mlang’s C
backend mapping M variables to an array of variables.
5.1 Performance of the generated code
We initially generated C code that would emit one local
variable per M variable. But with tens of thousands of local negatively or positively. We plan in the future to devise
variables, running the code required ulimit -s. Furthermore, a static analysis that could formally detect errors, such as
this naïve compilation technique resulted in code twice as comparisons that are always false, or numbers that may be
slow as with the legacy compiler (2ms instead of 1ms, with suspiciously close to zero (denormals).
-O0), which we attribute to constantly saving and restoring Fixed precision. Nevertheless, floating-point computa-
registers (spills). tions are notoriously hard to analyze and reason about, so
We analyzed the legacy code and found out that the DGFiP we set out to investigate replacing floats with integer val-
stored all of the M variables in a global array. We imple- ues. In our first experiment, we adopted big decimals, i.e.
mented the same technique and found out that with -O0, we a bignum for the integer part and a fixed amount of digits
were as fast as the legacy code. We attribute this improve- for the fractional part. Our test suite indicates that the inte-
ment to the fact that the array, which is a few dozen kB, ger part never exceeds 9999999999 (encodable in 37 bits); it
which fits in the L2 cache of most modern processors. This also indicates that with 40 bits of precision for the fractional
is a surprisingly fortuitous choice by the DGFiP. Compil- part, we get correct results. This means that a 128-bit integer
ing with -O1, we further halve the execution time and reach would be a viable alternative to a double, with the added
0.5ms (a 50% performance improvement over the legacy im- advantage that formal analysis tools would be able to deal
plementation). We attribute this gain to our ahead-of-time with it much better.
optimizations which significantly reduce the quantity of gen- Using rationals. Finally, we wondered if it was possible
erated C code. See Fig. 16 for full results. to completely work without floating-point and eliminate im-
precision altogether, taking low-level details such as round-
5.2 The cost of IEEE-754 ing mode and signed zeroes completely out of the picture.
Relying on IEEE-754 and its limited precision for something To that end, we encoded values as fractions where both
as crucial as the income tax of an entire nation naturally numerator and denominator are big integers. We observed
raises questions. Thanks to our new infrastructure, we were that both never exceed 2128 , meaning we could conceivably
able to instrument the generated code and gain numerous implement values as a struct with two 128-bit integers and a
insights. sign bit. We have yet to investigate the performance impact
Does precision matter? We tweaked our backend to use of this change.
the MPFR multiprecision library [13]. With 1024-bit floats,
all tests still pass, meaning that there is no loss of precision 5.3 Test-case generation
with the double-precision 64-bit format. The DGFiP test suite is painstakingly constructed by hand
Does rounding matter? We then instrumented the code by lawyers year after year. From this test suite, we picked
to measure the effect of the IEEE-754 rounding mode on the fi- the 476 cases that don’t raise any exceptions (see §2.1). The
nal result. Anything other than the default (rounding to near- DGFiP has no infrastructure to automatically generate cases
est, ties to even) generates incorrect results. The control-flow that would exercise new situations. As such, the test suite
remains roughly the same, but some comparisons against remains relatively limited in the variety of households it
0 do give out different results as the computation skews covers.
Preprint, Nov. 2020, Online Denis Merigoux, Raphaël Monat, and Jonathan Protzenko
Generating test cases is actually non-trivial: the search DGFiP Private (476 tests) Randomized (1267 tests)
Fuzzer-generated (358 tests)
Percentage of assignments
space is incredibly large, owing to the amount of variables,
but also deeply constrained, owing to the fact that most vari-
ables only admit a few possible values (§1), and are further 60%
constrained in relationship to other variables. 40%
We now set out to automatically generate fresh (valid) test 20%
cases for the tax computation, with two objectives: assert on 0%
a very large number of test cases that our code and the legacy 0 (uncovered) 1 2 or more
implementation compute the same result; and exhibit corner Number of distinct values assigned
interest for domain-specific languages encoding smart con- or Approximation of Fixpoints. In POPL. ACM, 238–252.
tracts [14, 16, 25, 30]. Regular private commercial contracts [8] Equipe Leximpact de L’Assemblée nationale. 2019. LexImpact. https:
have also been targeted for formalization [6, 28], as well //leximpact.an.fr/
[9] John Dewey. 1914. Logical method and law. Cornell LQ 10 (1914), 17.
as financial contracts [11, 22]. Concerning the public sec- [10] Direction Générale des Finances Publiques (DGFiP). 2019. Les règles
tor, the “rules as code” movement has been the object of an du moteur de calcul de l’impôt sur le revenu et de l’impôt sur la fortune
exhaustive OECD report [20]. immobilière. https://gitlab.adullact.net/dgfip/ir-calcul
Closer to the topic of this paper, the logical structure of the [11] Jean-Marc Eber. 2009. The Financial Crisis, a Lack of Contract Specifi-
US tax law has been extensively studied by Lawsky [18, 19], cation Tools: What Can Finance Learn from Programming Language
Design?.. In ESOP. 205–206.
pointing out the legal ambiguities in the text of the law that [12] D Fernández Duque, M González Bedmar, D Sousa, Joosten, J.J, and
need to be resolved using legal reasoning. She also claims G. Errezil Alberdi. 2019. To drive or not to drive: A formal analysis
that the tax law drafting style follows default logic [24], a of requirements (51) and (52) from Regulation (EU) 2016/799. In Per-
non-monotonic logic that is hard to encode in languages sonalidades jurídicas difusas y artificiales. TransJus Working Papers
with first-order logic (FOL). This could explain, as M is also Publication - Edición Especial, 159–171. http://diposit.ub.edu/dspace/
handle/2445/137759
based on FOL, the complexity of the DGFiP codebase. [13] Laurent Fousse, Guillaume Hanrot, Vincent Lefèvre, Patrick Pélissier,
As this complexity generates opacity around the way taxes and Paul Zimmermann. 2007. MPFR: A multiple-precision binary
are computed, another government agency set out to re- floating-point library with correct rounding. ACM Transactions on
implement the entire French socio-fiscal system in Python Mathematical Software (TOMS) 33, 2 (2007), 13–es.
[14] Xiao He, Bohan Qin, Yan Zhu, Xing Chen, and Yi Liu. 2018. Spesc: A
[27]. Even if this initiative was helpful and used as a compu-
specification language for smart contracts. In 2018 IEEE 42nd Annual
tation backend for various online simulators, the results it Computer Software and Applications Conference (COMPSAC), Vol. 1.
returns are not legally binding, unlike the results returned by IEEE, 132–137.
the DGFiP. Furthermore, this Python implementation does [15] Nils Holzenberger, Andrew Blair-Stanek, and Benjamin Van Durme.
not deal with all the corner cases of the law. To the extent of 2020. A Dataset for Statutory Reasoning in Tax Law Entailment and
our knowledge, our work is unprecedented in terms of size Question Answering. arXiv preprint arXiv:2005.05257 (2020).
[16] Tom Hvitved. 2011. Contract formalisation and modular implementation
and exhaustiveness of the portion of the law turned into a of domain-specific languages. Ph.D. Dissertation. Citeseer.
reusable and formalized software artifact. [17] Camille Landais, Thomas Piketty, and Emmanuel Saez. 2011. Pour
une révolution fiscale: Un impôt sur le revenu pour le 21 ème siècle.
6.2 Conclusion https://www.revolution-fiscale.fr/simuler/irpp/
[18] Sarah B. Lawsky. 2017. Formalizing the Code. Tax Law Review 70, 377
Thanks to modern compiler construction techniques, we
(2017).
have been able to lift up a legacy, secret codebase into a [19] Sarah B. Lawsky. 2018. A Logic for Statutes. Florida Tax Review (2018).
reusable, public artifact that can be distributed into virtually [20] James Mohun and Alex Roberts. 2020. Cracking the code: Rulemaking
any programming environment. The natural next step for for humans and machines. (2020).
the DGFiP is to consider taking more insight from program- [21] Jean-Michel Muller, Nicolas Brunie, Florent de Dinechin, Claude-Pierre
Jeannerod, Mioara Joldes, Vincent Lefèvre, Guillaume Melquiond,
ming languages research, and design a successor to M/M++
Nathalie Revol, and Serge Torres. 2018. Handbook of Floating-Point
that provides good tooling for translating the tax law into a Arithmetic (2nd Ed.). Springer. https://doi.org/10.1007/978-3-319-
correct and distributable implementation. 76526-6
[22] Grant Olney Passmore and Denis Ignatovich. 2017. Formal Verification
References of Financial Algorithms. In CADE. https://doi.org/10.1007/978-3-319-
63046-5_3
[1] Layman E Allen. 1956. Symbolic logic: A razor-edged tool for drafting [23] Marcos A Pertierra, Sarah Lawsky, Erik Hemberg, and Una-May
and interpreting legal documents. Yale LJ 66 (1956), 833. O’Reilly. 2017. Towards Formalizing Statute Law as Default Logic
[2] Layman E. Allen and C. Rudy Engholm. 1978. Normalized legal drafting through Automatic Semantic Parsing.. In ASAIL@ ICAIL.
and the query method. Journal of Legal Education 29, 4 (1978), 380–412. [24] R. Reiter. 1987. Readings in Nonmonotonic Reasoning. Morgan Kauf-
[3] Sylvie Boldo, Jacques-Henri Jourdan, Xavier Leroy, and Guillaume mann Publishers Inc., San Francisco, CA, USA, Chapter A Logic for De-
Melquiond. 2015. Verified Compilation of Floating-Point Computa- fault Reasoning, 68–93. http://dl.acm.org/citation.cfm?id=42641.42646
tions. J. Autom. Reason. 54, 2 (2015), 135–163. https://doi.org/10.1007/ [25] Vincenzo Scoca, Rafael Brundo Uriarte, and Rocco De Nicola. 2017.
s10817-014-9317-x Smart contract negotiation in cloud computing. In 2017 IEEE 10th
[4] Sylvie Boldo and Guillaume Melquiond. 2011. Flocq: A Unified Library International Conference on Cloud Computing (CLOUD). IEEE, 592–
for Proving Floating-Point Algorithms in Coq. In 20th IEEE Symposium 599.
on Computer Arithmetic, ARITH 2011, Tübingen, Germany, 25-27 July [26] M. J. Sergot, F. Sadri, R. A. Kowalski, F. Kriwaczek, P. Hammond, and
2011, Elisardo Antelo, David Hough, and Paolo Ienne (Eds.). IEEE H. T. Cory. 1986. The British Nationality Act As a Logic Program.
Computer Society, 243–252. https://doi.org/10.1109/ARITH.2011.40 Commun. ACM 29, 5 (May 1986), 370–386.
[5] Cristian Cadar, Daniel Dunbar, Dawson R Engler, et al. 2008. Klee: unas- [27] Sébastien Shulz. 2019. Free software to tackle the lack of transparency
sisted and automatic generation of high-coverage tests for complex in the social tax system. Sociology of a heterogeneous movement at
systems programs.. In OSDI, Vol. 8. 209–224. the margins of the state. Revue francaise de science politique 69, 5
[6] John J Camilleri. 2017. Contracts and Computation—Formal modelling (2019), 845–868.
and analysis for normative natural language. [28] SMU Centre for Computational Law. 2020. The L4 domain-specific
[7] Patrick Cousot and Radhia Cousot. 1977. Abstract Interpretation: A language. https://github.com/smucclaw/dsl
Unified Lattice Model for Static Analysis of Programs by Construction
Preprint, Nov. 2020, Online Denis Merigoux, Raphaël Monat, and Jonathan Protzenko
[29] The Coq Development Team. 2017. The Coq Proof Assistant Reference Verified Software: Theories, Tools, and Experiments. Springer, 229–247.
Manual, version 8.7. http://coq.inria.fr [31] Michal Zalewski. 2014. American fuzzy lop.
[30] Jakub Zakrzewski. 2018. Towards verification of Ethereum smart
contracts: a formalization of core of Solidity. In Working Conference on