<?xml version="1.0" encoding="UTF-8"?>
<TEI xml:space="preserve" xmlns="http://www.tei-c.org/ns/1.0" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://www.tei-c.org/ns/1.0 https://raw.githubusercontent.com/kermitt2/grobid/master/grobid-home/schemas/xsd/Grobid.xsd"
 xmlns:xlink="http://www.w3.org/1999/xlink">
	<teiHeader xml:lang="en">
		<fileDesc>
			<titleStmt>
				<title level="a" type="main">Semantics in Skel and Necro</title>
			</titleStmt>
			<publicationStmt>
				<publisher/>
				<availability status="unknown"><licence/></availability>
			</publicationStmt>
			<sourceDesc>
				<biblStruct>
					<analytic>
						<author>
							<persName><forename type="first">Louis</forename><surname>Noizet</surname></persName>
							<affiliation key="aff0">
								<orgName type="institution">Université de Rennes 1</orgName>
								<address>
									<settlement>Bretagne</settlement>
									<country key="FR">France</country>
								</address>
							</affiliation>
						</author>
						<author>
							<persName><forename type="first">Alan</forename><surname>Schmitt</surname></persName>
							<affiliation key="aff1">
								<orgName type="institution">INRIA</orgName>
								<address>
									<country key="FR">France</country>
								</address>
							</affiliation>
						</author>
						<title level="a" type="main">Semantics in Skel and Necro</title>
					</analytic>
					<monogr>
						<idno type="ISSN">1613-0073</idno>
					</monogr>
					<idno type="MD5">10D7096105523E1EFF2C82D18215E4CF</idno>
				</biblStruct>
			</sourceDesc>
		</fileDesc>
		<encodingDesc>
			<appInfo>
				<application version="0.7.2" ident="GROBID" when="2023-03-24T07:30+0000">
					<desc>GROBID - A machine learning software for extracting information from scholarly documents</desc>
					<ref target="https://github.com/kermitt2/grobid"/>
				</application>
			</appInfo>
		</encodingDesc>
		<profileDesc>
			<abstract>
<div xmlns="http://www.tei-c.org/ns/1.0"><p>We present Skel, a meta language designed to describe the semantics of programming languages, and Necro, a set of tools to manipulate said descriptions. We show how Skel, although minimal, can faithfully and formally capture informal specifications. We also show how we can use these descriptions to generate OCaml interpreters and Coq formalizations of the specified languages.</p></div>
			</abstract>
		</profileDesc>
	</teiHeader>
	<text xml:lang="en">
		<body>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="1.">Introduction</head><p>To formally prove properties of a programming language, or programs in that language, it is necessary to have a formal specification of its semantics. We expect the tool and the language used to describe this formalization to be executable, usable, and easily verifiable, that is, close to a paper-written specification.</p><p>Necro provides a language (Skel) and a set of tools to formalize and interpret the semantics of programming languages. Necro fulfills these requirements and more. First, Skel is designed to be light and its semantics simple. A light language facilitates maintainability and the development of tools. Second, Skel is powerful enough to express intricate semantical features, as proven by its use in an ongoing formalization of JavaScript's semantics <ref type="bibr" target="#b0">[1]</ref>. Third, a semantics described in Skel can be close to a previously written formulation, be it as inference rules or as an algorithmic specification. Finally, Necro provides a comprehensive and extensible set of tools to manipulate these semantics. For instance, to translate it into an interpreter (Necro ML, see Section 3.2), or to give a formalization in the Coq proof assistant (Necro Coq, see Section 3.3).</p><p>Skel is a statically strongly typed language. First introduced in <ref type="bibr" target="#b1">[2]</ref>, we present its redesign with a syntax close to ML. We also introduce support for polymorphism and higher order, enabling the use of monads in specifications <ref type="bibr" target="#b0">[1]</ref>.</p><p>Skel can be seen as a specification language or as a way to define inductive rules. Both approaches are useful, respectively when writing a semantics whose formalization is a set of algorithms, (e.g. ECMA-262 [3]), or when writing a semantics defined with inference rules (e.g. 𝜆-calculus). Skel can be used to describe arbitrary semantics, including ones with partiality and non-determinism.</p><p>Necro contains several tools to manipulate skeletal semantics (semantics written in Skel). First, Necro Lib offers basic operations (parsing, typing, printing, and simple transformations), in the form of a library to write programs that manipulate the AST describing a semantics. Second, Necro includes the tools Necro ML, Necro Coq, and Necro Debug, which use said library to generate respectively an OCaml interpreter, a Coq formalization, and a step-by-step debugger.</p><p>The contributions of this work are the Skel language, the accompanying tools, and many examples of semantics available online. <ref type="foot" target="#foot_0">1</ref>The paper is organized as follows. Section 2 introduces Skel. Section 3 presents the Necro ecosystem. Section 4 compares our work to existing approaches. Section 5 concludes the paper.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="2.">Skeletal Semantics</head></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="2.1.">Skel by Example</head><p>Let us describe how one specifies a semantics in Skel, using the small-step semantics of 𝜆calculus as example. A skeletal semantics is a list of declarations, either type declarations or term declarations, where each declaration can be unspecified or specified. When a type is unspecified, we only give its name. For instance, when writing the semantics of 𝜆-calculus, we might not want to specify how identifiers for variables are internally represented, so we declare type ident.</p><p>A specified type may be a variant type (i.e., an algebraic data type, defined by providing the list of its constructors together with their input type), a type alias using the := notation, or a record type (defined by listing its fields and their expected types). For instance, the type of 𝜆-terms would be defined as follows.</p><formula xml:id="formula_0">type term = | Var ident | Lam (ident, term) | App (term, term)</formula><p>In this example, (ident, term) is the product type with two components, the first one being of type ident, and the second of type term.</p><p>A record type is declared as type pair = ( left: int , right: int ) and an alias as type ident := string. Note that types are all implicitly mutually recursive, so the order in which they are declared does not matter.</p><p>We now turn to term declarations. An unspecified term declaration is simply its name and type. To declare a specified term, we also give its definition. An example of a term we might want to let unspecified is substitution, so we would declare val subst: ident → term → term → term.</p><p>An example of a specified term is the following. The branch . . . or . . . end construct is a Skel primitive to deal with non-deterministic choice, similar to McCarthy's ambiguous operator <ref type="bibr" target="#b2">[4]</ref>. There is no order in a branching, so any branch which yields a result can be chosen. Overlapping branches provide non-determinism, and non-exhaustive branches provide partiality. For instance the branch end at the end will never yield a result, so ss is partially defined.</p><p>The destructuring pattern matching let Lam (x, body) = t1 in ... asserts that t1 is a lambda-abstraction. If it is not, then the considered branch yields no result. If it is, then x and body will be assigned to the proper values.</p><p>The match . . . with . . . end construct is a pattern matching, similar to any other language's pattern matching. In particular, it is deterministic. Only the first (𝑝𝑎𝑡𝑡𝑒𝑟𝑛, 𝑠𝑘𝑒𝑙𝑒𝑡𝑜𝑛) pair for which the pattern corresponds with the matched value is taken.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="2.2.">Formalism</head><p>Figure <ref type="figure" target="#fig_0">1</ref> contains the syntax of Skel terms and skeletons. It does not include polymorphism, which will be described in Section 2.5. There are two types of expressions: terms and skeletons. Our syntax is close to Moggi's computational 𝜆-calculus <ref type="bibr" target="#b3">[5]</ref> and to Abstract Normal Forms <ref type="bibr" target="#b4">[6]</ref>: we separate what is intuitively an evaluated value to what is a computation. This makes the evaluation order unambiguous and the manipulation of skeletal semantics simpler.</p><p>A term is either a variable, a constructor applied to a term, a (possibly empty) tuple of terms, a 𝜆-abstraction, the access to a given field of a term, the access to a member of a tuple, a record of terms, or a term with reassignment of some fields. A skeleton is either the application of</p><formula xml:id="formula_1">Γ + 𝑥 ← 𝜏 ≜ Γ, 𝑥 : 𝜏 Γ + _ ← 𝜏 ≜ Γ Γ + 𝐶 𝑝 ← 𝜈 ≜ Γ + 𝑝 ← 𝜏 , where ctype(𝐶) = (𝜏, 𝜈) Γ + (𝑝 1 , . . . , 𝑝 𝑛 ) ← (𝜏 1 , . . . , 𝜏 𝑛 ) ≜ ((Γ + 𝑝 1 ← 𝜏 1 ) . . . ) + 𝑝 𝑛 ← 𝜏 𝑛 Γ + (𝑓 1 = 𝑝 1 , . . . , 𝑓 𝑛 = 𝑝 𝑛 ) ← 𝜈 ≜ ((Γ + 𝑝 1 ← 𝜏 1 ) . . . ) + 𝑝 𝑛 ← 𝜏 𝑛 ,</formula><p>where fields(𝜈) = {𝑓 </p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="2.3.">Typing</head><p>Skel is a strongly typed language with explicit type annotations. Every term declaration is given a type, as well as every pattern in a 𝜆-abstraction. Polymorphism, presented in Section 2.5, also uses explicitly specified type arguments. Specifying every type might seem tedious at first, but it helps to improve confidence on the correctness of the skeletal semantics. A future version of the typer will include an optional type-inference mechanism.</p><p>To give the typing rules for Skel, we first define ctype(𝐶), which returns the pair of the declared input type and output type for the constructor 𝐶 in its type declaration. For instance, we have ctype(Var) = (ident, term). Similarly, we define ftype(𝑓 ) to return (𝜏, 𝜈) where 𝜏 is the type of the field 𝑓 , and 𝜈 is the record type to which the field 𝑓 belongs. For instance, we have ftype(left) = (int, pair). Note that a field name may not belong to two different record types, and a constructor name may not be used twice, so these functions are well-defined. Finally, we write fields(𝜈) for the fields and types of record type 𝜈.</p><p>The typing rules for terms and skeletons are straightforward, we give them in Appendix A. They are respectively of the form Γ ⊢ 𝑡 𝑡 : 𝜏 and Γ ⊢ 𝑆 𝑆 : 𝜏 , where Γ is a typing environment (a partial function from variable names to types). To deal with pattern matching in 𝜆-abstractions and let-bindings, we use the partial function Γ + 𝑝 ← 𝜏 defined at the top of Figure <ref type="figure">2</ref>.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="2.4.">Concrete Interpretation</head><p>As such, Skel is a concrete syntax to describe a programming language. The meaning associated to a Skel description is called an interpretation. We present in this section a concrete interpreta-tion, which stands for the usual natural semantics of a language <ref type="bibr" target="#b5">[7]</ref>. One may also define an abstract interpretation, where unspecified types are given values in some abstract domain and where the results from branches are all collected. Such an interpretation is beyond the scope of this paper.</p><p>Every skeleton and term is interpreted as a value. Given sets of values 𝑉 𝜏 for each unspecified type 𝜏 , we build values for variant and product types in the expected way. For arrow types, we use closures for the specified functions, and we delay the evaluation of unspecified terms until we have all arguments. To this end, for each declaration val x : 𝜏 1 → . . . → 𝜏 n → 𝜏 , we assume given an arity 𝑛 = arity(𝑥) ∈ N and a relation 𝑥 ∈ 𝒫(𝑉</p><formula xml:id="formula_2">𝜏 1 × • • • × 𝑉 𝜏𝑛 × 𝑉 𝜏 ).</formula><p>The rules for the concrete interpretation are straighforward. They are given in Appendix B. They are of the form 𝐸, 𝑡 ⇓ 𝑡 𝑣 for terms and 𝐸, 𝑆 ⇓ 𝑆 𝑣 for skeletons, meaning that in the environment 𝐸 (partial function mapping variables to values), the term 𝑡 or the skeleton 𝑆 can evaluate to a value 𝑣.</p><p>A construct that is specific to Skel is the existential. To interpret the existential let p:𝜏 in sk, we take any value of type 𝜏 , and match p to this value, before evaluating the continuation in the extended environment. This pattern matching, also used for the let-in constructs and closures, is defined in Figure <ref type="figure">2</ref> as the partial function 𝐸 + 𝑝 ← 𝑣 that returns an extended environment.</p><p>The concrete interpretation is relational: a skeleton can be interpreted to 0, 1, or several values. A branching with no branch has no result, causing partiality. A branching with several branches can have several results, causing non-determinism. Pattern-matching can fail, causing partiality. Finally, non-terminating computations also cause partiality.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="2.5.">Polymorphism and Type Inference</head><p>Our type system allows for polymorphism, with explicit type annotations specified using angle brackets. Any declared and defined type can be polymorphic. Type annotations are explicitly given when constructing a term (e.g., Nil&lt;b&gt;) or when using a polymorphic term (e.g., map&lt;a,b&gt; f qa), but they can be locally inferred in patterns, so they are not specified in them (e.g., let Nil = l in . . . ).</p><p>The explicit typing is by design, as explicit type annotations reduce the risk of error. In the future, we will add an option to perform type inference. This option could also infer the type of the arguments in constructs of the form 𝜆p:𝜏 → sk.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="3.">The Necro Ecosystem</head><p>Necro is an ecosystem with several tools to perform different operations on skeletal semantics, as illustrated in Figure <ref type="figure" target="#fig_1">3</ref>.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="3.1.">Necro Lib</head><p>Necro Lib <ref type="bibr" target="#b6">[8]</ref> is an OCaml library file, necro.cma. It provides a parser and a typer, in order to transform a Skel file into a Skel AST. The AST is described in the file main/skeltypes.mli of the repository. It also contains a pretty-printer, which displays the AST in the format of a Skel file; a set of transformers, along with the tool Necro Trans that calls the transformers on an AST and prints the result; and a set of utility functions to manipulate the AST. The necro.cma file is the basis for Necro ML (Section 3.2) and Necro Coq (Section 3.3).</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="3.2.">Necro ML</head><p>Necro ML <ref type="bibr" target="#b7">[9]</ref> is a generator of OCaml interpreters. Given a skeletal semantics, it produces an OCaml functor. This functor expects as arguments an OCaml specification of all unspecified types and terms, it then provides an interpreter that can compute any given skeleton. Skel cannot be shallowly embedded in OCaml, since OCaml does not have an operator fitting the branching construct (pattern matching is deterministic in OCaml). So types and terms are shallowly embedded, but skeletons are deeply embedded. We use an interpretation monad, which specifies, amongst other things, how skeletons are represented, and how let ins, applications and branches are computed.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="3.2.1.">OCaml Interpreter</head><p>When Necro ML is executed on a skeletal semantics, it generates an OCaml file, which contains several modules, functors, and module types. To create an interpreter, one needs to instantiate them, in order to indicate how unspecified types and terms are interpreted, and which interpretation monad is chosen.</p><p>Working examples can be found in the test folder of Necro ML's repository.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="3.2.2.">Interpretation Monad</head><p>The interpretation monad is defined as follows, where terms are assumed to be pure while skeletons are monadic (of type 'a t). The fail operator takes a string as input which is an error message that should be raised, and the extract operator is a usability construct to extract a result from the monad, typically to display it.</p><formula xml:id="formula_3">module</formula><p>There are several proposed ways to instantiate this monad, and the user can also define their own. The standard identity monad, which is closest to a shallow embedding, tries each branch in turn. But it chooses the first branch that succeeds, with no ability to backtrack, which can be problematic in some cases. A more interesting one is the continuation monad, which keeps as a failure continuation the branches not taken, and can then backtrack if need be <ref type="bibr" target="#b8">[10]</ref>. Nevertheless, the continuation monad is not complete w.r.t the concrete interpretation, as it always executes the first branch first, and can therefore be caught in an infinite loop. The following function is an example thereof. To fix this issue, we propose another interpretation monad called BFS, which does one step in each branch, until it gets a result. The file containing all these monads and some others is available online. <ref type="foot" target="#foot_1">2</ref> Note that to change the interpretation monad, the user simply has to swap it at module instantiation, no code needs to be rewritten.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="3.3.">Necro Coq</head><p>Necro Coq <ref type="bibr" target="#b9">[11]</ref> is a tool to embed a given skeletal semantics into a Coq formalization. It can then be used to prove language properties or correctness of a given program.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="3.3.1.">Structure</head><p>Necro Coq uses a deep embedding of Skel. The embedding of Skel is defined in the file files/Skeleton.v, which is presented in Section 3.3.2. The command necrocoq file.sk provides a Coq file that contains the AST of the original skeletal semantics. To give meaning to the skeletons, we then provide a file that defines the concrete interpretation for skeletons and terms.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="3.3.2.">Skel's Embedding</head><p>The embedding is a straightforward deep embedding. It defines a number of variables, which are the data of a given skeletal semantics (its constructors, base types, . . . ), and provides the basic constructs (the definition of a type, a skeleton, . . . ).</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="3.3.3.">Values</head><p>The values that are the result of the evaluation of a term or skeleton are deeply embedded as well. The Coq type which supports values is defined with five constructors. Here are the first four. The cval_base constructor allows values of an unspecified type to be represented in Coq with any given type A. For instance, the value 1, in an unspecified type int, could be stored as cval_base Z 1. The next two constructors are straightforward. The fourth one is a closure constructor, to store 𝜆-abstractions. The three arguments of the constructor are the bound pattern, the skeleton to evaluate, and the current environment. The fifth constructor is used for unspecified functional terms, it will be presented below.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="3.3.4.">Interpretation</head><p>The file Concrete.v<ref type="foot" target="#foot_2">3</ref> provides the concrete interpretation for skeletons. It uses Coq's induction to define the relations interp_skel and interp_term, which relate respectively skeletons and terms in a given environment to their possible interpretations as a value. It mostly follows the semantics of Appendix B. For instance, this is the rule for a let in construct: The add_asn e p v e' proposition states that the environment 𝑒 can be extended into 𝑒 ′ by mapping 𝑝 to 𝑣, that is</p><formula xml:id="formula_4">𝑒 ′ = 𝑒 + 𝑝 ← 𝑣</formula><p>The file Concrete.v defines the interpretation using big-step evaluation, but we also provide a file Concrete_ss.v which does a small-step evaluation. An alternative is ConcreteRec.v, which defines interpretation from the bottom up. That is, instead of using Coq's induction, it only defines how to do one step, which doesn't use recursive calls, and then one may iterate this step. It is closest to the initial definition in <ref type="bibr" target="#b1">[2]</ref>. The purpose of this file is to be able to perform a strong induction on interp_skel in a simple way.</p><p>These interpretations are proven (in Coq) to be equivalent, so one can use indifferently one or the other, and one may even switch between several of them depending on what is more useful at the time. The big step definition is usually the easiest to use. The small step one allows to reason about non-terminating behaviors, and it provides a simple way to prove the subject reduction of Skel (see below). The iterative one allows, as we mentioned, to perform a strong induction. An instance where we need to use this one is to prove an induction property on the semantics of a lambda calculus. <ref type="foot" target="#foot_3">4</ref> As Skel is deeply embedded, one evaluation step in the language corresponds to several steps in Necro Coq. Because of this, the inductive interpretation is not convenient to prove that property, whereas this is much simpler using the iterative version with a strong induction on the height of the derivation tree.</p><p>As Skel is strongly typed, we also have a file WellFormed.v to check that a term or skeleton is well-formed, i.e., that it can be typed. We prove that the concrete interpretation respects the subject reduction property with regards to well-formedness. Since interpretations are all shown to be equivalent, it suffices to only prove it for Concrete_ss.v:</p><formula xml:id="formula_5">Theorem subject_reduction_skel:</formula><p>forall sk sk' ty, type_ext_skel sk ty -&gt; interp_skel_ss sk sk' -&gt; type_ext_skel sk' ty.</p><p>This translates roughly to:</p><formula xml:id="formula_6">𝑆 : 𝜏 𝑆 → 𝑆 ′ 𝑆 ′ : 𝜏</formula><p>where S and S' are extended skeletons.</p><p>With this proven, and since Concrete_ss.v and Concrete.v are equivalent, we have:</p><formula xml:id="formula_7">∅ ⊢ 𝑆 : 𝜏 𝑆 ⇓ 𝑆 𝑣 𝑣 ∈ 𝑉 𝜏</formula><p>Finally, interpretations in the form of abstract machines have been defined in <ref type="bibr" target="#b10">[12]</ref>. They reuse the deep embedding provided by Necro Coq and are proven correct in relation to the concrete interpretation.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="3.3.5.">Unspecified Functional Values</head><p>Since Skel allows to declare unspecified terms, we must be able to interpret them. The natural idea would be to ask for a cvalue for each given unspecified term. But for unspecified functions (like the addition), that would mean giving a closure, which is equivalent to specifying the function. We would lose Skel's power of partial specification. Instead, we ask for a relation that, given a list of cvalues as arguments, provides the result of the application of the term to the arguments. For instance, for the addition, it would be {([𝑥; 𝑦], 𝑥 + 𝑦) | 𝑥, 𝑦 ∈ N}.</p><p>There are operational and denotational approaches to represent this in Coq. We choose the operation approach as it does not need to evaluate ahead of time: it just waits to be applied to enough arguments before computing. We thus use the following constructor, which denotes an unspecified functional term that is not fully applied yet.</p><p>| cval_unspec: nat -&gt; unspec_value -&gt; list type -&gt; list cvalue -&gt; cvalue.</p><p>The first nat argument being n means that there are S n arguments missing. We add one, because there cannot be 0 argument missing, since if there is 0 argument missing, it is not a partial application. The list of types is the type annotation for polymorphic unspecified terms, the list of values is the list of arguments that have already been provided.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="3.3.6.">Applications and Usability</head><p>We have considered several applications of Necro Coq, some of them can be found in the test folder of the repository. For instance, we have proved the correctness of an IMP code that computes the factorial function (test/certif folder). Necro Coq has also been used to prove the equivalence between a small-step and a big-step semantics for a 𝜆-calculus extended with natural numbers (test/lambda folder). In addition, it has been used in <ref type="bibr" target="#b11">[13]</ref> to provide the a posteriori proof of an automatic generic transformation of a big step semantics into a small step semantics.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="4.">Related Work</head><p>We review existing approaches that are generic, in the sense that they can be used to describe and manipulate any semantics.</p><p>Our work is an extension of the work undertaken in <ref type="bibr" target="#b1">[2]</ref>. We significantly improve on this approach by having a more expressive language (with higher-order functions and polymorphism) and a set of tools to manipulate skeletal semantics. The Coq formalizations of <ref type="bibr" target="#b1">[2]</ref> were written by hand, they can now be automatically generated. Generation of OCaml code was also proposed in <ref type="bibr" target="#b12">[14]</ref>, but it was only available for the language of <ref type="bibr" target="#b1">[2]</ref>, which was less powerful than the current language. It also did not consider interpretation monads.</p><p>Regarding meta-languages to describe semantics, existing tools are much more complex than Skel. This is the case of Lem <ref type="bibr" target="#b13">[15]</ref> and Ott <ref type="bibr" target="#b14">[16]</ref>. The simplicity of Skel (the file skeltypes.mli describing Skel's AST is only 114 lines of specification) allows anyone to easily write a tool handling skeletal semantics. This is less immediate with Lem and Ott, as one has to deal with many additional features. For instance, Lem natively defines set comprehension, relations, and maps. Also, Coq generation is done as a shallow embedding, hence functions must be proven to terminate. In addition, shallow embedding of large semantics are not easily manipulated in Coq, due to the space complexity of the induction and inversion tactics.</p><p>The K framework <ref type="bibr" target="#b15">[17]</ref> also allows to formally define the semantics of a language and prove programs, and it is designed to be easy to use. It does not allow, however, to prove meta-theory properties of a language <ref type="foot" target="#foot_4">5</ref> , which is one of our future goals. Furthermore, there are no Coq backend for K at the present time, and since K is a large language, writing new backends is far from trivial.</p><p>Finally, another common way to describe a semantics is to implement it both in OCaml and in Coq, or other similar tools, either directly or through tools to transform them (Coq extraction to OCaml or coq-of-ocaml <ref type="bibr" target="#b16">[18]</ref> to go the other way). One may then execute the semantics using the OCaml version and prove properties using the Coq one. In this case, the Coq formalization is simpler to manipulate, but changing design choices (such as going from a shallow to a deep embedding) is very costly, as OCaml or Coq AST are not easy to manipulate.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="5.">Conclusion</head><p>Skel offers a way to specify semantics of programming languages, using a language light enough to be easily readable and maintainable, yet powerful enough to express many semantical features. We have focused on dynamic semantics, but one may also describe static semantics in Skel. The tools Necro provide, such as Necro ML, help in the process of writing a semantics. Necro Coq allows to manipulate and certify these semantics once written. They give the necessary framework to prove program correctness and language properties. Skel has been used to write the semantics of a set of basic languages such as IMP, but it has also been used to formalize more massive languages, such as WASM (unpublished), and an ongoing formalization of JavaScript <ref type="bibr" target="#b0">[1]</ref>. We plan to write a formalization of Python based on an existing precise description <ref type="bibr" target="#b17">[19]</ref>.</p><p>The Necro ecosystem includes other tools, such as Necro Debug, <ref type="foot" target="#foot_5">6</ref> which is a step-by-step execution of a semantics. An example execution can be found online. <ref type="foot" target="#foot_6">7</ref> . In addition, people can easily produce a new tool using Necro Lib.</p><p>Although not mentioned in this paper, Skel allows to split the definition of a semantics in several files, and to access them using an include construct. The OCaml generation tool can handle these multi-file semantics using modules, but at the moment this is not the case for Necro Coq. A future task is to implement this functionality using Coq modules. Once this has been done, the logical next step is to implement a standard library for Skel, defining basic types like lists, with properties on these types proven using Necro Coq. Initial work on this standard library can be found online. <ref type="foot" target="#foot_7">8</ref>Finally, Skel and Necro are currently being used to describe semantics style transformations, both at the object level <ref type="bibr" target="#b11">[13]</ref> and at the meta-language level <ref type="bibr" target="#b10">[12]</ref>. Work has also started to automatically derive control flow analyses from a language description. </p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head>A. Typing Rules for Skeletal Semantics</head><formula xml:id="formula_8">Γ(𝑥) = 𝜏 Γ ⊢ 𝑡 𝑥 : 𝜏 Var val x:𝜏 Γ ⊢ 𝑡 𝑥 : 𝜏 TermUnspec val x:𝜏 = t Γ ⊢ 𝑡 𝑥 : 𝜏 TermSpec Γ ⊢ 𝑡 𝑡 : 𝜏 ctype(C) = (𝜏, 𝜏 ′ ) Γ ⊢ 𝑡 C 𝑡 : 𝜏 ′ Const Γ ⊢ 𝑡 𝑡 1 : 𝜏 1 . . . Γ ⊢ 𝑡 𝑡 𝑛 : 𝜏 𝑛 Γ ⊢ 𝑡 (𝑡 1 , . . . , 𝑡 𝑛 ) : (𝜏 1 , . . . , 𝜏 𝑛 ) Tuple Γ + 𝑝 ← 𝜏 ⊢ 𝑆 𝑆 : 𝜏 ′ Γ ⊢ 𝑡 (𝜆𝑝 : 𝜏 → 𝑆) : 𝜏 → 𝜏 ′ Clos Γ ⊢ 𝑡 𝑡 : 𝜈 ftype(𝑓 ) = (𝜏, 𝜈) Γ ⊢ 𝑡 𝑡.𝑓 : 𝜏 FieldGet Γ ⊢ 𝑡 𝑡 : (𝜏 1 , . . . , 𝜏 𝑚 ) 1 ≤ 𝑖 ≤ 𝑚 Γ ⊢ 𝑡 𝑡.𝑖 : 𝜏 𝑖 TupleGet fields(𝜏 ) = {𝑓 1 : 𝜏 1 , . . . , 𝑓 𝑛 : 𝜏 𝑛 } Γ ⊢ 𝑡 𝑡 1 : 𝜏 1 . . . Γ ⊢ 𝑡 𝑡 𝑛 : 𝜏 𝑛 Γ ⊢ 𝑡 (𝑓 1 = 𝑡 1 , . . . , 𝑓 𝑛 = 𝑡 𝑛 ) : 𝜏 Rec Γ ⊢ 𝑡 𝑡 : 𝜏 ∀𝑖 ∈ 1; 𝑚 , Γ ⊢ 𝑡 𝑡 𝑖 : 𝜏 𝑖 ∀𝑖 ∈ 1; 𝑚 , ftype 𝑓 𝑖 = (𝜏 𝑖 , 𝜏 ) Γ ⊢ 𝑡 𝑡 ← (𝑓 1 = 𝑡 1 , . . . , 𝑓 𝑚 = 𝑡 𝑚 ) : 𝜏 FieldSet Γ ⊢ 𝑡 𝑡 : 𝜏 Γ ⊢ 𝑆 ret 𝑡 : 𝜏 Ret Γ ⊢ 𝑆 𝑆 1 : 𝜏 . . . Γ ⊢ 𝑆 𝑆 𝑛 : 𝜏 Γ ⊢ 𝑆 (𝑆 1 . . . 𝑆 𝑛 ) : 𝜏 Branch Γ ⊢ 𝑆 𝑆 : 𝜏 Γ + 𝑝 ← 𝜏 ⊢ 𝑆 𝑆 ′ : 𝜏 ′ Γ ⊢ 𝑆 let 𝑝 = 𝑆 in𝑆 ′ : 𝜏 ′ LetIn Γ + 𝑝 ← 𝜏 ⊢ 𝑆 𝑆 : 𝜏 ′ Γ ⊢ 𝑆 let 𝑝 : 𝜏 in 𝑆 : 𝜏 ′ Exist Γ ⊢ 𝑡 𝑡 : 𝜏 Γ + 𝑝 1 ← 𝜏 ⊢ 𝑆 𝑆 1 : 𝜈 . . . Γ + 𝑝 𝑛 ← 𝜏 ⊢ 𝑆 𝑆 𝑛 : 𝜈 Γ ⊢ 𝑆 match 𝑡 with|𝑝 1 → 𝑆 1 |. . . |𝑝 𝑛 → 𝑆 𝑛 : 𝜈 Match Γ ⊢ 𝑡 0 : 𝜏 1 → • • • → 𝜏 𝑛 → 𝜏 Γ ⊢ 𝑡 𝑡 1 : 𝜏 1 . . . Γ ⊢ 𝑡 𝑡 𝑛 : 𝜏 𝑛 Γ ⊢ 𝑆 (𝑡 0 𝑡 1 . . .</formula></div><figure xmlns="http://www.tei-c.org/ns/1.0" xml:id="fig_0"><head>Figure 1 :</head><label>1</label><figDesc>Figure 1: Syntax of Skel (without Polymorphism)</figDesc></figure>
<figure xmlns="http://www.tei-c.org/ns/1.0" xml:id="fig_1"><head>(Figure 3 :</head><label>3</label><figDesc>Figure 3: The Necro Ecosystem</figDesc></figure>
<figure xmlns="http://www.tei-c.org/ns/1.0" xml:id="fig_2"><head>module</head><label></label><figDesc>ContPoly = struct type 'b fcont = string -&gt; 'b type ('a,'b) cont = 'a -&gt; 'b fcont -&gt; 'b type 'a t = { cont: 'b. (('a,'b) cont -&gt; 'b fcont -&gt; 'b) } let ret (x: 'a) = { cont = fun k fcont -&gt; k x fcont } let bind (x: 'a t) (f: 'a -&gt; 'b t) : 'b t = { cont = fun k fcont -&gt; x.cont (fun v fcont' -&gt; (f v).cont k fcont') fcont } let fail s = { cont = fun k fcont -&gt; fconts } let rec branch l = { cont = fun k fcont -&gt; begin match l with | [] -&gt; fcont "No branch matches" | b :: bs -&gt; (b ()).cont k (fun _ -&gt; (branch bs).cont k fcont) end} let apply f x = f x let extract x = x.cont (fun a _ -&gt; a) (fun s -&gt; failwith s) end</figDesc></figure>
<figure xmlns="http://www.tei-c.org/ns/1.0" xml:id="fig_3"><head></head><label></label><figDesc>val loop (_:()): () = branch loop () or () end</figDesc></figure>
<figure xmlns="http://www.tei-c.org/ns/1.0" xml:id="fig_4"><head>Inductive</head><label></label><figDesc>cvalue : Type := | cval_base : forall A, A -&gt; cvalue | cval_constructor : constr -&gt; cvalue -&gt; cvalue | cval_tuple: list cvalue -&gt; cvalue | cval_closure: pattern -&gt; skeleton -&gt; list (string * cvalue) -&gt; cvalue.</figDesc></figure>
<figure xmlns="http://www.tei-c.org/ns/1.0" xml:id="fig_5"><head>Inductive</head><label></label><figDesc>interp_skel: env -&gt; skeleton -&gt; cvalue -&gt; Prop := | i_letin: forall e e' p s1 s2 v w, interp_skel e s1 v -&gt; add_asn e p v e' -&gt; interp_skel e' s2 w -&gt; interp_skel e (skel_letin p s1 s2) w</figDesc></figure>
<figure xmlns="http://www.tei-c.org/ns/1.0" type="table" xml:id="tab_0"><head></head><label></label><figDesc>1 : 𝜏 1 , . . . , 𝑓 𝑛 : 𝜏 𝑛 } 𝐸 + 𝑥 ← 𝑣 ≜ 𝐸, 𝑥 : 𝑣 𝐸 + _ ← 𝑣 ≜ 𝐸 𝐸 + 𝐶 𝑝 ← 𝐶 𝑣 ≜ 𝐸 + 𝑝 ← 𝑣 𝐸 + (𝑝 1 , . . . , 𝑝 𝑛 ) ← (𝑣 1 , . . . , 𝑣 𝑛 ) ≜ (𝐸 + 𝑝 1 ← 𝑣 1 ) . . . + 𝑝 𝑛 ← 𝑣 𝑛 𝐸 + (𝑓 1 = 𝑝 1 , . . . , 𝑓 𝑛 = 𝑝 𝑛 ) ← (𝑓 1 = 𝑣 1 , . . . , 𝑓 𝑛 = 𝑣 𝑛 ) ≜ (𝐸 + 𝑝 1 ← 𝑣 1 ) . . . + 𝑝 𝑛 ← 𝑣 𝑛</figDesc><table><row><cell>Figure 2: Pattern Matching of Types and Values</cell></row><row><cell>a term to other terms, a let-binding, an existential (see Section 2.4), a branching, a match, or</cell></row><row><cell>simply the return of a term. We sometimes omit ret in ret 𝑡. A pattern is either a variable, a</cell></row><row><cell>wildcard, a constructor applied to a pattern, a (possibly empty) tuple of patterns, or a record</cell></row><row><cell>pattern. Finally, a type is either a base type (defined by the user), an arrow type, or a (possibly</cell></row><row><cell>empty) tuple of types. Term and type declarations have already been described in Section 2.1</cell></row></table></figure>
<figure xmlns="http://www.tei-c.org/ns/1.0" type="table" xml:id="tab_2"><head>Concrete Interpretation of Skeletal Semantics First</head><label></label><figDesc>we defined rules to handle environments. We define the relation 𝑝 ̸ ↦ → 𝑣 which holds if 𝑝 cannot represent the value 𝑣, and the partial function 𝐸 + 𝑣 match(𝑝 1 , . . . , 𝑝 𝑛 ) as follows:𝑣 𝑖 0 ≤ 𝑖 ≤ 𝑛 (𝑝 1 , . . . , 𝑝 𝑛 ) ̸ ↦ → (𝑣 1 , . . . , 𝑣 𝑛 ) NoMatchTuple 𝑝 𝑖 ̸ ↦ → 𝑣 𝑖 0 ≤ 𝑖 ≤ 𝑚 ≤ 𝑛 (𝑓 1 = 𝑝 1 , . . . , 𝑓 𝑚 = 𝑝 𝑚 ) ̸ ↦ → (𝑓 1 = 𝑣 1 , . . . , 𝑓 𝑛 = 𝑣 𝑛 ) 𝑝 1 ← 𝑣 = 𝐸 ′ 𝐸 + 𝑣 match(𝑝 1 , . . . , 𝑝 𝑛 ) = (1, 𝐸 ′ ) 𝑣 𝐸 + 𝑣 match(𝑝 2 , . . . , 𝑝 𝑛 ) = (𝑖, 𝐸 ′ ) 𝐸 + 𝑣 match(𝑝 1 , . . . , 𝑝 𝑛 ) = (𝑖 + 1, 𝐸 ′ ) GetMatchNextNow we define the rules for concrete interpretation:𝐸(𝑥) = 𝑣 𝐸, 𝑥 ⇓ 𝑡 𝑣 𝐸, 𝑥 ⇓ 𝑡 ⌈𝑥, ()⌉ 𝑡 𝑣 𝐸, (C 𝑡) ⇓ 𝑡 C 𝑣 Const 𝐸, 𝑡 1 ⇓ 𝑡 𝑣 1 . . . 𝐸,𝑡 𝑛 ⇓ 𝑡 𝑣 𝑛 𝐸, (𝑡 1 , . . . , 𝑡 𝑛 ) ⇓ 𝑡 (𝑣 1 , . . . , 𝑣 𝑛 ) Tuple 𝐸, (𝜆𝑝 : 𝜏 → 𝑆) ⇓ 𝑡 ⟨𝑝, 𝐸, 𝑆⟩ Clos 𝐸, 𝑡 ⇓ 𝑡 (𝑓 1 = 𝑣 1 , . . . , 𝑓 𝑛 = 𝑣 𝑛 ) 𝐸, 𝑡.𝑓 𝑖 ⇓ 𝑡 𝑣 𝑖 FieldGet 𝐸, 𝑡 ⇓ 𝑡 (𝑣 1 , . . . , 𝑣 𝑚 ) 1 ≤ 𝑖 ≤ 𝑚 𝐸, 𝑡.𝑖 ⇓ 𝑡 𝑣 𝑖 TupleGet 𝐸, 𝑡 1 ⇓ 𝑡 𝑣 1 . . . 𝐸, 𝑡 𝑛 ⇓ 𝑡 𝑣 𝑛 𝐸, (𝑓 1 = 𝑡 1 , . . . , 𝑓 𝑛 = 𝑡 𝑛 ) ⇓ 𝑡 (𝑓 1 = 𝑣 𝑖 , . . . , 𝑓 𝑛= 𝑣 𝑛 ) 𝑡 (𝑓 1 = 𝑣 1 , . . . , 𝑓 𝑛 = 𝑣 𝑛 ) ∀𝑖 ∈ 1; 𝑚 , 𝐸, 𝑡 𝑖 ⇓ 𝑡 𝑤 𝑗 𝑖 ∀𝑖 ∈ 1; 𝑛 ∖ {𝑗 1 , . . . , 𝑗 𝑚 }, 𝑤 𝑖 = 𝑣 𝑖 𝐸, 𝑡 ← (𝑓 𝑗 1 = 𝑡 1 , . . . , 𝑓 𝑗𝑚 = 𝑡 𝑚 ) ⇓ 𝑡 (𝑓 1 = 𝑤 1 , . . . , 𝑓 𝑛 = 𝑤 𝑛 ) 𝑡 𝑣 𝐸 + 𝑣 match 𝑝 1 . . . 𝑝 𝑛 = (𝑖, 𝐸 ′ ) 𝐸 ′ ,𝑆 𝑖 ⇓ 𝑆 𝑤 𝐸, match 𝑡 with|𝑝 1 → 𝑆 1 | . . . |𝑝 𝑛 → 𝑆 𝑛 end ⇓ 𝑆 𝑤 Match 𝐸, 𝑡 0 ⇓ 𝑡 𝑓 𝐸, 𝑡 1 ⇓ 𝑡 𝑣 1 . . . 𝐸, 𝑡 𝑛 ⇓ 𝑡 𝑣 𝑛 𝑓 𝑣 1 . . . 𝑣 𝑛 ⇓ app 𝑤 𝐸, (𝑡 0 𝑡 1 . . . 𝑡 𝑛 ) ⇓ 𝑆 𝑤 𝑝 ← 𝑣 1 , 𝑆 ⇓ 𝑆 𝑔 𝑔 𝑣 2 . . . 𝑣 𝑛 ⇓ app 𝑤 ⟨𝑝, 𝐸, 𝑆⟩ 𝑣 1 . . . 𝑣 𝑛 ⇓ app 𝑤 (𝑣 1 , . . . , 𝑣 𝑚 )⌉ 𝑣 𝑚+1 . . . 𝑣 𝑛 ⇓ app ⌈𝑥, (𝑣 1 , . . . , 𝑣 𝑛 )⌉ 𝑚 ≤ 𝑛 𝑥 (𝑣 1 , . . . , 𝑣 𝑚 , 𝑔) 𝑔 𝑣 𝑚+1 . . . 𝑣 𝑛 ⇓ app 𝑤 ⌈𝑥, (𝑣 1 , . . . , 𝑣 𝑚 )⌉ 𝑣 𝑚+1 . . . 𝑣 𝑛 ⇓ app 𝑤</figDesc><table><row><cell></cell><cell>val x : 𝜏</cell><cell>arity(𝑥) = 0</cell><cell>𝑥 (𝑣)</cell></row><row><cell cols="2">Var</cell><cell></cell><cell cols="2">TermUnspecZero</cell></row><row><cell></cell><cell cols="2">𝐸, 𝑥 ⇓ 𝑡 𝑣</cell><cell></cell></row><row><cell>val x : 𝜏</cell><cell>arity(𝑥) &gt; 0</cell><cell cols="2">val x:𝜏 = t</cell><cell>𝜖, 𝑡 ⇓ 𝑡 𝑣</cell></row><row><cell>𝑝 ̸ ↦ → 𝑣</cell><cell cols="2">TermUnspecSucc</cell><cell>𝐸, 𝑥 ⇓ 𝑡 𝑣</cell></row><row><cell cols="2">𝐶𝑝 ̸ ↦ → 𝐶𝑣</cell><cell></cell><cell></cell></row><row><cell></cell><cell></cell><cell></cell><cell></cell><cell>AppClos</cell></row><row><cell></cell><cell>arity(𝑥) &gt; 𝑛</cell><cell></cell><cell></cell></row><row><cell cols="5">⌈𝑥, AppUnspecNext</cell></row><row><cell cols="5">arity(𝑥) = AppUnspecCont</cell></row></table><note>𝑡 𝑛 ) : 𝜏 App B. NoMatchSameConstr 𝐶 ̸ = 𝐶 ′ 𝐶𝑝 ̸ ↦ → 𝐶 ′ 𝑣 NoMatchDiffConstr 𝑝 𝑖 ̸ ↦ → NoMatchRecord 𝐸 + GetMatchFirst 𝑝 1 ̸ ↦ → TermSpec 𝐸, 𝑡 ⇓ Rec 𝐸, 𝑡 ⇓ FieldSet 𝐸, 𝑡 ⇓ 𝑡 𝑣 𝐸, ret 𝑡 ⇓ 𝑆 𝑣 Ret 𝐸, 𝑆 𝑖 ⇓ 𝑆 𝑣 1 ≤ 𝑖 ≤ 𝑛 𝐸,(𝑆 1 . . . 𝑆 𝑛 ) ⇓ 𝑆 𝑣 Branch 𝐸, 𝑆 ⇓ 𝑆 𝑣 𝐸 + 𝑝 ← 𝑣, 𝑆 ′ ⇓ 𝑆 𝑤 𝐸, let 𝑝 = 𝑆 in 𝑆 ′ ⇓ 𝑆 𝑤 LetIn 𝑣 ∈ 𝑉 𝜏 𝐸 + 𝑝 ← 𝑣, 𝑆 ⇓ 𝑆 𝑤 𝐸, let 𝑝 : 𝜏 in 𝑆 ⇓ 𝑆 𝑤 Exist 𝐸, 𝑡 ⇓ App 𝑣 ⇓ app 𝑣 AppZero 𝐸 +</note></figure>
			<note xmlns="http://www.tei-c.org/ns/1.0" place="foot" n="1" xml:id="foot_0">https://gitlab.inria.fr/skeletons/necro-test</note>
			<note xmlns="http://www.tei-c.org/ns/1.0" place="foot" n="2" xml:id="foot_1">https://gitlab.inria.fr/skeletons/necro-ml/-/blob/master/necromonads.ml</note>
			<note xmlns="http://www.tei-c.org/ns/1.0" place="foot" n="3" xml:id="foot_2">https://gitlab.inria.fr/skeletons/necro-coq/-/blob/master/files/Concrete.v</note>
			<note xmlns="http://www.tei-c.org/ns/1.0" place="foot" n="4" xml:id="foot_3">https://gitlab.inria.fr/skeletons/necro-coq/-/blob/master/test/lambda/EvalInd.v#L55</note>
			<note xmlns="http://www.tei-c.org/ns/1.0" place="foot" n="5" xml:id="foot_4">https://sympa.inria.fr/sympa/arc/coq-club/2020-02/msg00066.html</note>
			<note xmlns="http://www.tei-c.org/ns/1.0" place="foot" n="6" xml:id="foot_5">https://gitlab.inria.fr/skeletons/necro-debug</note>
			<note xmlns="http://www.tei-c.org/ns/1.0" place="foot" n="7" xml:id="foot_6">https://skeletons.inria.fr/debugger/index_while.html</note>
			<note xmlns="http://www.tei-c.org/ns/1.0" place="foot" n="8" xml:id="foot_7">https://gitlab.inria.fr/skeletons/necro/-/tree/master/examples/necro_in_necro</note>
		</body>
		<back>
			<div type="references">

				<listBibl>

<biblStruct xml:id="b0">
	<analytic>
		<title level="a" type="main">Jskel: Towards a formalization of javascript&apos;s semantics</title>
		<author>
			<persName><forename type="first">A</forename><surname>Khayam</surname></persName>
		</author>
		<author>
			<persName><forename type="first">L</forename><surname>Noizet</surname></persName>
		</author>
		<author>
			<persName><forename type="first">A</forename><surname>Schmitt</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="m">JLFA 2021 -Journées Francophones des Langages Applicatifs</title>
				<imprint>
			<date type="published" when="2021">2021</date>
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b1">
	<analytic>
		<title level="a" type="main">Skeletal Semantics and their Interpretations</title>
		<author>
			<persName><forename type="first">M</forename><surname>Bodin</surname></persName>
		</author>
		<author>
			<persName><forename type="first">P</forename><surname>Gardner</surname></persName>
		</author>
		<author>
			<persName><forename type="first">T</forename><surname>Jensen</surname></persName>
		</author>
		<author>
			<persName><forename type="first">A</forename><surname>Schmitt</surname></persName>
		</author>
		<idno type="DOI">10.1145/3290357</idno>
		<ptr target="https://hal.inria.fr/hal-01881863.doi:10.1145/3290357" />
	</analytic>
	<monogr>
		<title level="m">Proceedings of the ACM on Programming Languages</title>
				<meeting>the ACM on Programming Languages</meeting>
		<imprint>
			<date type="published" when="2019">2019</date>
			<biblScope unit="volume">44</biblScope>
			<biblScope unit="page" from="1" to="31" />
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b2">
	<analytic>
		<title level="a" type="main">A basis for a mathematical theory of computation</title>
		<author>
			<persName><forename type="first">J</forename><surname>Mccarthy</surname></persName>
		</author>
		<idno type="DOI">10.1016/S0049-237X(09)70099-0</idno>
		<ptr target="https://doi.org/10.1016/S0049-237X(09)70099-0" />
	</analytic>
	<monogr>
		<title level="m">Studies in Logic and the Foundations of Mathematics</title>
				<editor>
			<persName><forename type="first">P</forename><surname>Braffort</surname></persName>
		</editor>
		<editor>
			<persName><forename type="first">D</forename><surname>Hirschberg</surname></persName>
		</editor>
		<imprint>
			<publisher>Elsevier</publisher>
			<date type="published" when="1959">1959</date>
			<biblScope unit="volume">26</biblScope>
			<biblScope unit="page" from="33" to="70" />
		</imprint>
	</monogr>
	<note>Computer Programming and Formal Systems</note>
</biblStruct>

<biblStruct xml:id="b3">
	<analytic>
		<title level="a" type="main">Computational lambda-calculus and monads</title>
		<author>
			<persName><forename type="first">E</forename><surname>Moggi</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="m">Proceedings. Fourth Annual Symposium on Logic in Computer Science</title>
				<meeting>Fourth Annual Symposium on Logic in Computer Science</meeting>
		<imprint>
			<date type="published" when="1988">1988</date>
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b4">
	<analytic>
		<title level="a" type="main">Reasoning about programs in continuation-passing style</title>
		<author>
			<persName><forename type="first">A</forename><surname>Sabry</surname></persName>
		</author>
		<author>
			<persName><forename type="first">M</forename><surname>Felleisen</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="m">LISP AND SYMBOLIC COMPUTATION</title>
				<imprint>
			<date type="published" when="1993">1993</date>
			<biblScope unit="page" from="288" to="298" />
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b5">
	<analytic>
		<title level="a" type="main">Natural semantics</title>
		<author>
			<persName><forename type="first">G</forename><surname>Kahn</surname></persName>
		</author>
		<idno type="DOI">10.1007/BFb0039592</idno>
		<ptr target="https://doi.org/10.1007/BFb0039592.doi:10.1007/BFb0039592" />
	</analytic>
	<monogr>
		<title level="m">STACS 87, 4th Annual Symposium on Theoretical Aspects of Computer Science</title>
		<title level="s">Lecture Notes in Computer Science</title>
		<editor>
			<persName><forename type="first">F</forename><surname>Brandenburg</surname></persName>
		</editor>
		<editor>
			<persName><forename type="first">G</forename><surname>Vidal-Naquet</surname></persName>
		</editor>
		<editor>
			<persName><forename type="first">M</forename><surname>Wirsing</surname></persName>
		</editor>
		<meeting><address><addrLine>Passau, Germany</addrLine></address></meeting>
		<imprint>
			<publisher>Springer</publisher>
			<date type="published" when="1987">February 19-21, 1987. 1987</date>
			<biblScope unit="volume">247</biblScope>
			<biblScope unit="page" from="22" to="39" />
		</imprint>
	</monogr>
	<note>Proceedings</note>
</biblStruct>

<biblStruct xml:id="b6">
	<monogr>
		<author>
			<persName><forename type="first">L</forename><surname>Noizet</surname></persName>
		</author>
		<ptr target="https://gitlab.inria.fr/skeletons/necro" />
		<title level="m">Necro Library</title>
				<imprint/>
	</monogr>
</biblStruct>

<biblStruct xml:id="b7">
	<monogr>
		<author>
			<persName><forename type="first">E</forename><forename type="middle">C</forename><surname>Martin Bodin</surname></persName>
		</author>
		<author>
			<persName><forename type="first">Nathanaëlle</forename><surname>Courant</surname></persName>
		</author>
		<author>
			<persName><forename type="first">L</forename><surname>Noizet</surname></persName>
		</author>
		<ptr target="https://gitlab.inria.fr/skeletons/necro-ml" />
		<title level="m">Necro Ocaml Generator</title>
				<imprint/>
	</monogr>
</biblStruct>

<biblStruct xml:id="b8">
	<analytic>
		<title level="a" type="main">Abstracting control</title>
		<author>
			<persName><forename type="first">O</forename><surname>Danvy</surname></persName>
		</author>
		<author>
			<persName><forename type="first">A</forename><surname>Filinski</surname></persName>
		</author>
		<idno type="DOI">10.1145/91556.91622</idno>
		<ptr target="https://doi.org/10.1145/91556.91622.doi:10.1145/91556.91622" />
	</analytic>
	<monogr>
		<title level="m">Proceedings of the 1990 ACM Conference on LISP and Functional Programming, LFP &apos;90</title>
				<meeting>the 1990 ACM Conference on LISP and Functional Programming, LFP &apos;90<address><addrLine>New York, NY, USA</addrLine></address></meeting>
		<imprint>
			<publisher>Association for Computing Machinery</publisher>
			<date type="published" when="1990">1990</date>
			<biblScope unit="page" from="151" to="160" />
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b9">
	<monogr>
		<author>
			<persName><forename type="first">L</forename><surname>Noizet</surname></persName>
		</author>
		<ptr target="https://gitlab.inria.fr/skeletons/necro-coq" />
		<title level="m">Necro Gallina Generator</title>
				<imprint/>
	</monogr>
</biblStruct>

<biblStruct xml:id="b10">
	<analytic>
		<title level="a" type="main">Certified Abstract Machines for Skeletal Semantics</title>
		<author>
			<persName><forename type="first">G</forename><surname>Ambal</surname></persName>
		</author>
		<author>
			<persName><forename type="first">S</forename><surname>Lenglet</surname></persName>
		</author>
		<author>
			<persName><forename type="first">A</forename><surname>Schmitt</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="m">Certified Programs and Proofs</title>
				<meeting><address><addrLine>Philadelphia, United States</addrLine></address></meeting>
		<imprint>
			<date type="published" when="2022">2022</date>
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b11">
	<monogr>
		<title level="m" type="main">Automatic Transformation of a Big-Step Skeletal Semantics into Small-Step</title>
		<author>
			<persName><forename type="first">G</forename><surname>Ambal</surname></persName>
		</author>
		<author>
			<persName><forename type="first">A</forename><surname>Schmitt</surname></persName>
		</author>
		<author>
			<persName><forename type="first">S</forename><surname>Lenglet</surname></persName>
		</author>
		<idno>RR-9363</idno>
		<ptr target="https://hal.inria.fr/hal-02946930" />
		<imprint>
			<date type="published" when="2020">2020</date>
		</imprint>
		<respStmt>
			<orgName>Inria Rennes -Bretagne Atlantique</orgName>
		</respStmt>
	</monogr>
	<note type="report_type">Research Report</note>
</biblStruct>

<biblStruct xml:id="b12">
	<analytic>
		<title level="a" type="main">Necro: Animating Skeletons</title>
		<author>
			<persName><forename type="first">N</forename><surname>Courant</surname></persName>
		</author>
		<author>
			<persName><forename type="first">E</forename><surname>Crance</surname></persName>
		</author>
		<author>
			<persName><forename type="first">A</forename><surname>Schmitt</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="m">ML 2019</title>
				<meeting><address><addrLine>Berlin, Germany</addrLine></address></meeting>
		<imprint>
			<date type="published" when="2019">2019</date>
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b13">
	<analytic>
		<title level="a" type="main">Lem: Reusable engineering of real-world semantics</title>
		<author>
			<persName><forename type="first">D</forename><surname>Mulligan</surname></persName>
		</author>
		<author>
			<persName><forename type="first">S</forename><surname>Owens</surname></persName>
		</author>
		<author>
			<persName><forename type="first">K</forename><surname>Gray</surname></persName>
		</author>
		<author>
			<persName><forename type="first">T</forename><surname>Ridge</surname></persName>
		</author>
		<author>
			<persName><forename type="first">P</forename><surname>Sewell</surname></persName>
		</author>
		<idno type="DOI">10.1145/2628136.2628143</idno>
	</analytic>
	<monogr>
		<title level="j">ACM SIGPLAN Notices</title>
		<imprint>
			<biblScope unit="volume">49</biblScope>
			<date type="published" when="2014">2014</date>
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b14">
	<analytic>
		<title level="a" type="main">Ott: Effective tool support for the working semanticist</title>
		<author>
			<persName><forename type="first">P</forename><surname>Sewell</surname></persName>
		</author>
		<author>
			<persName><forename type="first">F</forename><surname>Zappa</surname></persName>
		</author>
		<author>
			<persName><forename type="first">S</forename><surname>Nardelli</surname></persName>
		</author>
		<author>
			<persName><forename type="first">G</forename><surname>Owens</surname></persName>
		</author>
		<author>
			<persName><forename type="first">T</forename><surname>Peskine</surname></persName>
		</author>
		<author>
			<persName><forename type="first">S</forename><surname>Ridge</surname></persName>
		</author>
		<author>
			<persName><forename type="first">R</forename><surname>Sarkar</surname></persName>
		</author>
		<author>
			<persName><surname>Strnisa</surname></persName>
		</author>
		<idno type="DOI">10.1017/S0956796809990293</idno>
	</analytic>
	<monogr>
		<title level="j">J. Funct. Program</title>
		<imprint>
			<biblScope unit="volume">20</biblScope>
			<biblScope unit="page" from="71" to="122" />
			<date type="published" when="2010">2010</date>
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b15">
	<monogr>
		<title level="m" type="main">IsaK: A Complete Semantics of K</title>
		<author>
			<persName><forename type="first">L</forename><surname>Li</surname></persName>
		</author>
		<author>
			<persName><forename type="first">E</forename><forename type="middle">L</forename><surname>Gunter</surname></persName>
		</author>
		<imprint>
			<date type="published" when="2018">2018</date>
		</imprint>
		<respStmt>
			<orgName>Computer Science, Univ. of Illinois Urbana-Champaign</orgName>
		</respStmt>
	</monogr>
	<note type="report_type">Technical Report</note>
</biblStruct>

<biblStruct xml:id="b16">
	<monogr>
		<author>
			<persName><forename type="first">N</forename><surname>Labs</surname></persName>
		</author>
		<ptr target="https://clarus.github.io/coq-of-ocaml" />
		<title level="m">coq-of-ocaml</title>
				<imprint/>
	</monogr>
</biblStruct>

<biblStruct xml:id="b17">
	<monogr>
		<title level="m" type="main">Static Type and Value Analysis by Abstract Interpretation of Python Programs with Native C Libraries</title>
		<author>
			<persName><forename type="first">R</forename><surname>Monat</surname></persName>
		</author>
		<imprint>
			<date type="published" when="2021">2021</date>
		</imprint>
		<respStmt>
			<orgName>Sorbonne Université</orgName>
		</respStmt>
	</monogr>
	<note type="report_type">Ph.D. thesis</note>
</biblStruct>

				</listBibl>
			</div>
		</back>
	</text>
</TEI>
