IMP with exceptions over decorated logic

In this paper, we separately design the decorated logic with respect to the state and the exception effects. Then, we combine two logics to be able to establish small-step semantics of IMP imperative language with exceptional abilities, in a decorated setting. We implement the decorated framework in Coq and certify program equivalence proofs written in that context.


Introduction
In mostly used imperative programming languages (such as C/C++ and Java), computational effects do exist.With no doubt, they bring an ease and flexibility to the coding process.However, the problem becomes explicit when to prove the properties of programs involving effects.The major difficulty in such kind of a reasoning is the mismatch between the syntax of operations with effects and their interpretation.Typically, a piece of program with arguments in X that returns a value in Y is not interpreted as a function from X to Y due to the effects.The best-known algebraic approach to the problem was initiated by Moggi and implemented in Haskell.There, the main focus is to interpret programs with effects through the monads: the interpretation looks like a function from X to T (Y ) where T is a monad.This approach has been extended to Lawvere theories and algebraic handlers [10,11] while there are some others relying on effect systems [8,12] or Hoare Logic [13].In [6] Duval et al. proposes yet another approach where algebraic theories and effect systems are mixed by adding decorations to the terms and equations keeping their interpretations close to syntax in reasoning with effects.In this paper, we first introduce smallstep semantics for IMP with exceptional abilities (IMP+Exc).This follows the same approach given in [7].Then, Duval's decorated logic has been designed for the state and the exception effects, first separately then combined.The combination here means "merging" the behind logics.Next, we establish smallstep semantics of IMP+Exc over the combined decorated settings.There, we are able to cope with termination-guaranteed programs.We illustrate the program equivalence proofs within that context and certify proofs with the Coq Proof Assistant.

IMP with exceptional abilities
IMP is a standard imperative programming language.It natively provides global variables of type integer, standard integer arithmetic and boolean expressions enriched with a set of commands that is made of do-nothing, assignment, sequence, conditionals and looping operations.Below, we detail the syntax where n represents a constant integer term while x is an integer global variable.Note also that abbreviations aexp and bexp respectively denote arithmetic and boolean expressions as well as cmd stands for commands.
aexp: a 1 a 2 ::  Neither arithmetic nor boolean expressions are allowed to modify the state: they are either pure or read-only.Indeed, small-step semantics for expressions is a total function of the form: exp × s → exp.It constitutes a new expression out of an input expression and the current state.We recursively define it as follows: n (s) = n x (s) = α(x) exp 1 op exp 2 (s) = exp 1 (s) op exp 2 (s) Figure 2: Small-step semantics for expressions where op stands for natural semantics of any syntactically well-defined arithmetic or boolean operation.For instance, no matter the current state s, the expression 5 + 4 (s) will evaluate into 9.Note that constant terms are pure.The small-step semantics of commands is also a total function defined by the judgment s × c s ′ × c ′ .That is to say, in the state s, execution of the command c will change the state into s ′ and it remains to execute c ′ .Details can be found in Fig. 3.It remains to note that a command c at some state s terminates if there exists a state s ′ such that s, c s ′ , SKIP after a finite number of execution steps.Else if such a state s ′ does not exist, the command c runs forever.Mind also that there is no run-time error since any command apart from SKIP is allowed to execute at any state s.SKIP alone is used to indicate the final step of some command set.

Adding exceptional abilities
Providing exceptional abilities to the standard IMP language is about enriching the command set with throw and TRY/CATCH blocks.In addition to the ones in Fig. 1, we also consider following commands: Exceptional commands are pure with respect to the state effect: they neither use nor modify the program state.However, they introduce another sort of computational effect: the exception.In prior, we stated that the command SKIP alone indicates the termination of a program.Now, we extend this by stating: throw exc is also an end but an exceptional end.
Recall that the new language is abbreviated as "IMP+Exc" and the idea is to certify equivalences between programs written in that language.To this extend, Section 3 and Section 4 respectively study decorated logics for the state and the exception which are combined in Section 5. Finally in Section 6, we translate IMP+Exc semantics into decorated settings enriched with an implementation in Coq.There, we give a bunch of examples of equivalent code blocks with certified equivalence proofs.One of the main examples involves a program with an infinite loop inside the try block in which an exception is thrown.As soon as the exceptional case is met, the program terminates the loop, recovers the exception and continues with an ordinary execution.We will prove that such a program has both result and effect equivalence with another one (just made of assignments) up to the state and the exception.

Decorated Logic for the state
Even though it is not syntactically mentioned, the usage/modification of the memory state is allowed in imperative languages.For instance, a C function may look up the value of a variable as well as another can modify it.That is an ease in coding but in order to prove correctness of programs with such abilities, one has to revert an explicit usage/manipulation of the state.Therefore, any access to the state is treated as a computational effect: a syntactical term f : X → Y is not interpreted as f : X → Y unless it is pure.Indeed, a term which reads the program state has instead the interpretation: f : X × S → Y while another term which updates the state is interpreted as: f : X ×S → Y ×S where '×' is the product operator and S is the set of possible states.In [4], we proposed a formal system to prove program properties involving the state, while keeping the memory accesses and manipulations implicit.As in [1], decorated logics for states are obtained from equational logics by classifying terms and equations.Terms are classified as pure terms, accessors or modifiers, which is expressed by adding a decoration or superscript, respectively (0), ( 1) and ( 2): the decoration of a term (or an equation) characterizes the way it may interact with the state.The decoration (0) is reserved for pure terms, while (1) is for read-only (accessor) and ( 2) is for read-write (modifier) terms.Equations are classified as strong or weak equations, denoted respectively by the symbols ≡ and ∼.Weak equation relates only the returned values, while strong equation relates both values and the state effect.Let us start with the descriptions of main features: syntax and rules.

Syntax and rules
Each type is interpreted as a set.In Fig. 6, 1 is the set of singleton while V i is the set of values that can be stored in any location i.Terms represent functions; they are closed under composition and "pairs", π 1 and π 2 represent the canonical projections with X : X → 1 being the canonical empty pair for each type X.The basic interface functions are lookup i : 1 → V i and update i : Fundamentally, lookup reads the value stored in a given location while update stands to modify it.As mentioned, decorations are used to express the state interaction of a given term.In particular, id (0) , π and (0) are pure.lookup (1) is an accessor while update (2) is a modifier.The usage of decorations provides a new schema where term signatures are constructed without any occurrence of the state set.So that signatures are kept close to syntax.In addition, decorations give us the flexibility to cope with several interpretations of the state: any proof in decorated settings is valid for different state interpretations.

Syntax :
Types: t The intended model is built with respect to the set of states, denoted S, which never appears in the syntax.A pure term p (0) : X → Y is interpreted as a function p : X → Y , an accessor a (1) : X → Y as a function a : X × S → Y and a modifier m (2) : X → Y as a function m : X × S → Y × S. Obviously, pure terms can be seen as accessors and accessors as modifiers on demand.For instance, this allows term compositions to be directly done without recalling the Kleisli composition.The complete characterization is given in [1].
2 : 1 , f 2 : X → 1 lookup i (1) • f (2) As stated in Fig. 7, given syntax is enriched with a set of rules with a special focus on decorations.Strong equations form a congruence while weak equations do not: the replacement rule holds only when the replaced term is pure.The fundamental equations for states are provided by the rules (ax 1 ) and (ax 2 ).With (ax 1 ), we have lookup i (1) • update i (2) ∼ id V (0) .This means that updating the location i with a value v and then observing the value of the location does return v. Clearly this is only a weak equation: its right-hand side does not modify the state while its left-hand side usually does.With (ax 2 ), lookup i (1) • update j (2) ∼ lookup i (1) • V (0) , we assume that updating the location j with a value v and then reading the content of location i would return the same result with first forgetting the value v then observing the content of location i.They definitely have different effects on the state.Mind also that this assumption is valid when i = j.There is an obvious conversion from strong to weak equations (≡-to-∼), any term f : X → 1 with no result returned (void) is said to have an evident result equivalence with the canonical empty pair X by (unit ∼ ).In addition strong and weak equations coincide on accessors by rule (eq 1 ).Two modifiers f : X → Y modify the state in the same way if and only if where Y : Y → 1 throws out the returned value.Then weak and strong equations are related by the property that by rule (eq 2 ).For each location i, this can be expressed as a pair of weak equations by rule (eq 3 ).With (pair 1 ) and (pair 2 ) categorical pairs are characterized: the pair structure f 1 , f 2 cannot be used while both f 1 and f 2 are modifiers, since it would lead to a conflict on the returned result.However, it can be used when only f 1 is an accessor.By (pair 1 ), we state that f 1 , f 2 (2) has only result equivalence with f    The constructor tpure takes a Coq side (pure) function and drops it into the decorated environment.So that pure terms as id, π 1 , π 2 and are covered within the scope of tpure.
, is ro f1 → pi1 o pair f1 f2 ∼ f1 where "x == y" := (strong x y) and "x ∼ y" := (weak x y).One can simply derive the reflexivity property up to weak equality: given f ≡ f, it suffices to convert strong equality into weak by (≡-to-∼).Now; we can form the primitive properties of the state structure as in [10] but this time with decorations.

Decorated Logic for the exception
Exception handling is provided by most modern programming languages.It allows to deal with anomalous or exceptional events which require special processing.That brings a flexibility to the coding but in order to prove the correctness of such programs one has to revert an explicit interaction with exceptions.
Therefore, any interaction with exceptional cases is treated as a new sort of computational effect: a term f : X → Y is not interpreted as a function f : X → Y unless it is pure.Indeed, a term which may raise an exception is instead interpreted as a function f : X → Y + E and similarly, a term which may catch an exception is interpreted as a function f : X + E → Y + E where '+' is disjoint union operator and E is the set of exceptions.Moreover, it has been shown in [2] that the core part of this proof system is dual to one for the state which is explained in Section 3. As in [3], decorated logics for exception are obtained from equational logics by classifying terms and equations.Terms are classified as pure terms, propagators or catchers, which is expressed by adding a decoration or superscript, respectively (0), ( 1) and ( 2): the decoration of a term (or an equation) characterizes the way it may cope with exceptional cases.The decoration (0) is reserved for terms which are pure, while ( 1) is for throwers and ( 2) is for catchers.Equations are classified as strong or weak equations, denoted respectively by the symbols ≡ and ∼.Weak equation relates the ordinary cases in programs, while strong equations relates both ordinary and exceptional cases.
Let us describe the main features of the logic: syntax and rules.

Syntax and rules
The full syntax is declared in Fig. 13 where 0 is the empty type while V e represents the set of values which can be used as arguments for the exceptions with name e. Terms represent functions; they are closed under composition and "copairs" (or case distinction), inl and inr represent the canonical inclusions into a coproduct (or disjoint union).The basic functions for dealing with exceptions are tag e : V e → 0 and untag e : 0 → V e .A fundamental feature of the mechanism of exceptions is the distinction between ordinary (or non-exceptional ) values and exceptions.While tag e encapsulates its argument (which is an ordinary value) into an exception, untag e is applied to an exception for recovering this argument.The usual throw and try/catch constructions are built from the more basic tag e and untag e operations [3].The term downcast takes an input term f and behaves exactly as f on ordinary arguments, if the argument is exceptional then it enforces f to propagate it (in case f might catch it).As mentioned, we use decorations on terms for expressing how they interact with the exceptions.In particular, id (0) , inl (0) , inr (0) and [ ] (0) are pure.Clearly tag e (1) and downcast (1) are throwers while untag e (2) is a catcher.A thrower may throw exceptions and must propagate any given exception, while a catcher may recover from exceptions.Using decorations provides a new schema where term signatures are constructed without any occurrence of a "type of exceptions".Thus, signatures are kept close to the syntax.In addition, decorating terms gives us the flexibility to cope with more than one interpretation of the exceptions.This means that with such an approach, any proof in decorated logic is valid for different implementations of the exceptions.
Syntax : Types: t Equations: e Figure 13: Syntax for the exception The intended model is built with respect to the set of exceptions, denoted E, which never appears in the syntax.It interprets each type X as a set X, each pure term u (0) : X → Y as a function u : X → Y , each propagator a (1) : X → Y as a function a : X → Y + E and each catcher f (2) : X → Y as a function f : X + E → Y + E. The complete characterization is given in [3].

Rules:
(equiv ≡ ), (subs ≡ ), (repl ≡ ) for all decorations (equiv ∼ ), (repl ∼ ) for all decorations, (subs ∼ ) only when substituted term is pure for each pair of exception names (e 2 : Y → X f 1 , f 2 • tag e (1)   As stated in Fig. 14, a set of rules enriches the syntax with a special focus on decorations.Strong equations form a congruence while weak equations do not: the replacement rule holds only when the replaced term is pure.Since, (downcast f) and f behave the same on ordinary arguments, they are weakly equal ensured by the rule (donwcast ∼ ).The fundamental equations for states are provided by the rules (eax 1 ) and (eax 2 ).With (ax 1 ), we have untag e (2) • tag e (1) ∼ id V (0) .This means that encapsulating the argument with an exception of name e followed by an immediate recovery would be equivalent to "doing nothing" with respect to the ordinary values.Clearly this is only a weak equation: its right-hand side has no exceptional case while its left-hand has.With (eax 2 ), untag e 1 (2) • tag e 2 (1) ∼ [ ] V • tag e 2 (1) , we assume on the left that encapsulating an argument with an exception of name e 2 and then recovering from a different exception of name e 1 would just lead e 2 to be propagated.Whilst on the right, the argument is encapsulated with e 2 with no recovery attempt afterwards.Thus, they behave different on exceptional values but the same on ordinary ones: the equality in between is weak.There is an obvious conversion from strong to weak equations (≡-to-∼), any term f : 0 → X with no input parameter is said to have an equivalence on ordinary values with the canonical empty copair [ ] X by (empty ∼ ).In addition strong and weak equations coincide on propagators by rule (eeq 1 ).Two catchers f : X → Y have the same effect up to the exceptional values if and only if Then weak and strong equations are related by the property that by rule (eeq 2 ).For each exception name e, this can be expressed as a pair of weak equations f 1 ∼ f 2 and • tag e, ensured by the rule (eeq 3 ).With (copair 1 ) and (copair 2 ) categorical copairs are characterized: the copair structure [f 1 | f 2 ] cannot be used while both f 1 and f 2 are catchers, since it would lead to a conflict when the argument is an exception.However, it can be used when only f 1 is a propagator.With (copair 1 ), we state that ordinary arguments are treated by [f 1 | f 2 ] (2) as they would be by f

Decorated logic for the exception in Coq
Coq implementation follows the same approach with the one for the state.We represent the set of exception names by a Coq parameter EName: Type, we assume an arrow type Val : EName → Type which is the set of parameters for each exception name.Then, we inductively define terms and assign decorations: Parameter EName: Type.Parameter EVal: EName → Type.

Figure 15: Exception names and values in Coq
We use keywords pure, propagator and thrower instead of (0), ( 1) and (2).The functions inl and inr indicate coprojections.In addition, [ ] is called empty.ttrue and ffalse correspond to boolean true and false.The operation throw e is just taging an exception of name e followed by [ ] X which is used to bridge the execution to the next command.Within the scope of the intended model, it is used to include 0 into 0 + X.To build (TRY f CATCH e g), we use copairs to have case distinction: (1) either the term f does not throw an exception so that the term g is never triggered.That corresponds to the id Y case of the copair.(2) or else, the code f throws an exception then through untag e, the exception would be recovered (if pattern matching is fine with exception names) and execution continues with the term g.The whole TRY − CATCH block is either pure (in case no exceptional case has been met) or a thrower/propagator (in case, the thrown exception by f has not been caught or a previously thrown exception has been propagated).This is ensured the rule (downcast ∼ ).Now; we get the rules in Coq: Reserved Notation "x == y" (at level 80).
Reserved Notation "x ∼ y" (at level 80).Definition pure id X Y (x y: term X Y) := is pure x ∧ x = y.

Combination: the state & the exception
In order to formally cope with both the state and the exception effects in the same program, one needs to combine the related formal models.For instance in Haskell, effects are modeled by monads and combination is done through monad transformers.However, here we just merge the related decorated logics.Let us start with explanation of the syntax: Equations: e Types and terms are simply unionized.The decorations are paired off to cover all possible combinations: left component is given up to the state while right is to the exception.I.e., f (1,2) says that f is an accessor with respect to the state and catcher to the exception.The hierarchies among decorations are preserved: . Obviously, we have all possible combinations of equalities with preserved hierarchies: (≡≡-to-≡∼) f ≡≡g f ≡∼g , (≡≡-to-∼≡) f ≡≡g f ∼≡g and f ≡≡ g only when d1, d2, d3, d4 ≤ 1.Here we form the combined rules: 1. ≡≡ relates the properties that are strongly equal both up to the state and the exception: (eq 1 ) is now with f , (eq 2 ) and (eq 3 ) with f and (pair 2 ) with f . In addition, (eeq 1 ) with f , (eeq 2 ) and (eeq 3 ) with f and (copair 2 ) with f 2. ∼≡ relates the properties that are weakly equal up to the state: (unit ∼ ) is now with f (2,2) , (ax 1 ) and (ax 2 ) with lookup (1,0) , update (2,0) and (pair 1 ) with f . ≡∼ relates the properties that are weakly equal up to the exception: (empty ∼ ) is with f (2,2) , (downcast ∼ ) with f (2,2) , (eax 1 ) and (eax 2 ) with tag (0,1) , untag (0,2) and (copair 1 ) with f . ∼∼ relates nothing but the conversions: ∼≡ and ≡∼ can be seen as ∼∼.

IMP+Exc over decorated logic
Finally, it comes to translate the semantics detailed in Section 2 into the combined decorated settings.Given that IMP only provides the integer data type, the values that can be stored in any location i are just integers.So that any occurrence of (Val i) in term signatures is replaced by Z. Here, we start with expressions and recursively define the translator function dExp.It mainly takes an expression and outputs a decorated term of type term Z unit or term B unit depending on the input expression type.Below, we have it recursively defined: where f is a unary pure term.Besides, we have some additional rules to make use of some pure algebraic operations in the decorated setting.Before going into the rule details, we define some terms that help to form them: given in Fig. 22, lpi is the syntactical term providing loop iteration(s) together with the rule (imp-loopiter) while pbl forms terms of type term (unit + unit) B for compatibility issues in rule statements (imp 2 ) and (imp 4 ).such that tt : unit and inl, inr : unit → (unit + unit) Figure 22: Additional terms: IMP specific In (imp 2 ) and (imp 4 ) by replacing false into true and ffalse into ttrue we get (imp 3 ) and (imp 5 ) that are not explicitly stated here.The fact that IMP commands are of type 1 → 1, they will be designed in such a way that domains and codomains being set to unit within the decorated scope.Now; we recursively define the translator function dCmd which establishes a decorated term of type term unit unit, out of an input command: Figure 24: Translating commands into decorated settings Let us take a closer look into conditionals and loops in terms of diagrams: and (while b do c) in decorated settings there, we use categorical copairs to have case distinction.For instance, in Fig. 25 on the left, after the condition check if the boolean evaluates into ttrue, then we have c 1 in execution or else c 2 .The only difference on the right is that as long as the boolean evaluates into ttrue, c is in execution: diagrammatically, it says that the arrow lpd b c is each time replaced by the whole diagram itself.As mentioned, this property is provided by the syntactic term lpd and the attached rule (imp-loopiter).When the boolean evaluates into ffalse, we have id forcing the loop to terminate.
Contrarily, in the translation of throw and try/catch, the basis is the core decorated operations for the exception effect.Recall that they are defined as they are given in Section 4.2 with a single difference in the signatures: domains/codomains are now set to 1. Below, we have the translation in terms of diagrams:  Expressions are inductively defined forming a new Coq Type, Exp.Indeed, Exp is a dependent type.That means that the type of Exp A depends on the term A: Type.For instance, when A := B, we build the type for boolean expressions while the case A := Z enables us to construct the type for arithmetic expressions.Obviously, Exp is polymorphic, too.Speaking of the constructors: an expression might be a constant term (constructed by const), a variable (by loc), an expression with an applied pure term (by apply) or a pair of expressions (by pExp).The translation given in Fig. 21 is characterized by the fixpoint dExp.
A similar idea of implementation follows for the commands:  In Fig. 28 on the left, we inductively define commands and on the right, recursively translate their behaviors into decorated settings.This translation is similar to the one given in Fig. 24, but this time done in Coq terms.Within the above context, we retain sufficient material to prove equivalences among programs involving not only the state but also the exception effect.
Remark 6.1.IMP specific properties of the state are slightly different than their generic versions given in Fig. 12.The ones we use through the following proofs are re-stated below.The full certified proofs can be found in the Coq release: see the given link at the end of the section.Proof.We first sketch the diagrams of both programs as below: where k = (if b then f else g).Thus, The proof proceeds by the induction on b.If b = false, by unfolding pbl and (c false), we have f g • tpure(bool to two) • tpure(λx : unit.false)≡ k g • tpure(bool to two) • tpure(λx : unit.false).We rewrite (imp 6 ) to get f g • tpure(λx : unit.bool to two false) ≡ k g • tpure (λx : unit.booltwo false).Now, we cut tpure (λx : unit.bool to two false) ≡≡ inr.So that we obtain f g • inr ≡≡ k g • inr.Then, we use (copair 2 ), and finally have g ≡≡ g.It remains to show tpure (λx : unit.bool to two false) ≡≡ inr.By simplifying tpure (λx : unit.bool to two false) and unfolding inr, we have tpure (λx : unit.inr x) ≡≡ (tpure inr).Now, we apply (imp 7 ) and get ∀x : unit, inr x = inr x.
Proof.In the proof structure, we first deal with the pre-loop assignments and the looping pre-condition.Since it evaluates into true, in the second step we identify things related to the first loop iteration.The third step primarily studies the second and then the third loop iteration after which the looping pre-condition switches to false.Finally, we explain the program termination.Let us sketch the diagram of prog5: where f = (x := x + 4) and b = (x < 11).
1.So that we have (lpi b f) Let us try to simplify it as far as possible.By commutation − lookup − constant − update, we obtain (lpibf) We first convert ≡≡ into ≡∼ and then rewrite (copair 1 ).So that we have Since, there is no exceptional case, we are back to ≡≡.By rewriting commutation −lookup −const ant −update, we obtain (lpi b f)   Proof.Within the below enumerated proof structure, we first tackle with the downcast operator.The second task is to deal with the first loop iteration which has the state but no exception effect.In the third, we study the second iteration of the loop where an exception is thrown.Finally, in the fourth step, we explain the loop termination followed by the exception recovery and the program termination.Let us now sketch the diagram of prog3: G G 1 lpi ffalse c1 r r lpi ttrue c1 x x  The complete Coq library with all certified proofs can be found on https://forge.imag.fr/frs/download.php/651/IMP-STATES

Conclusion
We have presented new frameworks for formalizing the treatment of the state and the exception via the decorated logic both separately and combined with Coq implementations.Decorations form a bridge between the syntax and the interpretation by turning the syntax sound without adding any explicit type of the state nor the exception.Combined setting is specialized for the IMP+Exc language and finally equivalence proofs of programs are given with related certifications in Coq.Besides, in [5], we prove that the core language for the state and exception as well as the programmers' language for the exception are complete.

2 Figure 4 :(try 3 ) exc 1 exc 2 : 1 Figure 5 :
Figure 4: Syntax for additional commandswhere exc is an exception name of a new type EName.There might be different exception names but EName is the only type within the context that we introduce in this paper.The small-step semantics for throw and TRY/CATCH commands are detailed below:

Figure 6 :
Figure 6: Syntax for the state

Figure 7 :
Figure 7: Rules for the state

3. 2
Decorated logic for the state in Coq We represent the set of memory locations by a Coq parameter Loc: Type.Since memory locations may contain different types of values, we also assume an arrow type Val : Loc → Type that is the type of values contained in each location.Parameter Loc: Type.Parameter Val: Loc → Type.

Figure 8 :
Figure 8: Locations and values in Coq The terms of the logic are defined through the inductive type named term which establishes a new Type out of two input Types.The type term Y X is dependent.It depends on the Type instances X and Y and represents the arrow type: X → Y.The constructor tpure takes a Coq side (pure) function and drops it into the decorated environment.So that pure terms as id, π 1 , π 2 and are covered within the scope of tpure.

Figure 10 :
Figure 10: Some derived terms for the state in Coq Fig. 10 includes derivation of some terms that we latter use.I.e., is handled via tpure and called forget.Besides, we state the rules, in Fig 11, up to weak and strong equalities by defining them in a mutually inductive way: mutuality here is used to enable the constructors with both weak and strong equalities.

Figure 16 :
Figure 16: Terms and decorations for the exception in Coq Some derived terms including throw and TRY/CATCH blocks are hereby stated:

Figure 17 :
Figure 17: Some derived terms for the exception in Coq

Figure 20 :
Figure 20: Syntax for the combined state and exception
Figure 26: (throw exp) and (try c 1 catch exp ⇒ c 2 ) in decorated settings We implement such formalizations in Coq: