10.6092/issn.1972-5787/3887
The use of real numbers in a program can introduce differences between the expected and the actual behavior of the program, due to the finite representation of these numbers. Therefore, one may want to define programs using real numbers such that this difference vanishes. This paper defines a program transformation for a certain class of programs that improves the accuracy of the computations on real number representations by removing the square root and division operations from the original program in order to enable exact computation with addition, multiplication and subtraction. This transformation is meant to be used on embedded systems, therefore the produced programs have to respect constraints relative to this kind of code. In order to ensure that the transformation is correct, i.e. preserves the semantics, we also aim at specifying and proving this transformation using the PVS proof assistant.
application/pdf
1972-5787
3887
1
en
Pierre Neron
Journal of Formalized Reasoning
Embedded Systems
A Formal Proof of Square Root and Division Elimination in Embedded Programs
Text.Serial.Journal
https://jfr.unibo.it/
6
Articles
2013-12-06
2013-07-24
2013-08-27
2016-01-29
89-111
JFR
Pierre Neron
2013/12/06
10.6092/issn.1972-5787/3887
89
INRIA
1972-5787
1
Embedded Systems
en
111
A Formal Proof of Square Root and Division Elimination in Embedded Programs
https://jfr.unibo.it/article/download/3887/3466
6
A Formal Proof of Square Root and Division
Elimination in Embedded Programs
Pierre NERON
École polytechnique - INRIA


The use of real numbers in a program can introduce dierences between the expected and the
actual behavior of the program, due to the nite representation of these numbers. Therefore, one
may want to dene programs using real numbers such that this dierence vanishes. This paper
denes a program transformation for a certain class of programs that improves the accuracy of the
computations on real number representations by removing the square root and division operations
from the original program in order to enable exact computation with addition, multiplication
and subtraction. This transformation is meant to be used on embedded systems, therefore the
produced programs have to respect constraints relative to this kind of code. In order to ensure
that the transformation is correct, i.e. preserves the semantics, we also aim at specifying and
proving this transformation using the Pvs proof assistant.




1. INTRODUCTION
Safety critical embedded systems, for instance in aeronautics, demand a very high
level of reliability since any failure can have critical consequences. One approach
to ensure such levels of safety is the use of proof assistants such as Pvs, Coq,
Hol, to prove properties on these programs, ensuring that the program satises
its specication. Some of these systems use computation over real numbers, this is
the case of the conict detection and resolution algorithms introduced in [NMD12,
MBMD09] that have an extended use of solid geometry. However computing with
real numbers is unsafe since concrete implementations of real numbers do not always
behave as one would expect.
   One of the main challenges is that real numbers can not be represented in an
exact way in programs and we have to use dierent representations in order to make
computation,    e.g.,  the oating point numbers dened by the IEEE754-Standard
[IEE85] with a xed number of bits. This kind of representation always introduces
dierences between the     expectedbehavior (dened by the abstract semantics), where
we assume that numbers are genuine real numbers, and the                actual
                                                                    behavior (dened
by a concrete semantics), happening when we run the program. Furthermore some
programs,   e.g., air trac management systems [NMD10], use tests on comparisons
between real numbers and we may want to ensure some numerical stability on the
programs that use these features since a tiny error in a test can make the actual
behavior greatly diverge from the expected one.
   Using formalizations of the oating point semantics [BM06, BF07, Har95, Min95]
makes proofs of programs used in aeronautics dicult since most of the properties
of real numbers and operations (       e.g.,
                                         associativity) do not hold on such represen-
tations. Therefore many proofs are done on the abstract semantics which does not
represent the actual behavior of the program. Dierences between the abstract
and the oating point semantics have been studied in a particularly ecient way

                                      Journal of Formalized Reasoning Vol. 6, No. 1, 2013, Pages 89111.
90     ·     Pierre Neron




using static analysis by abstract interpretation with numerical abstract domains
[CMC08] and interval arithmetic in order to provide numerical analysis of programs
[DMM05]. These methods have been used to dene a program transformation to
improve accuracy [Mar09] but our goal is slightly dierent.
   We aim at producing, for any program that computes a boolean with real arith-
                         √
metic using +, −, ×, /, , an equivalent program whose concrete semantics is equal
to its abstract semantics on genuine real numbers. By introducing dynamic rep-
resentations of real numbers, techniques have been developed to compute exactly.
In 1980, Wiedmer studied the computation over innite objects [Wie80] and intro-
duced a representation with innite decimal fraction. Then Boehm and Cartwright
[BCRO86] both extended this representation as a sequence of fractions and in-
troduced a representation using lazy evaluation of the digits representing the real
number. Dierent constructions of real numbers have since been introduced, with
redundant representation of continued fractions [Vui87] or with functional represen-
tation and lazy evaluation [Sim98, DGL04]. Some representations have even been
formalized in the Coq system, a constructive construction of the real number eld
is presented in [O'C08, KS11] and a construction of the algebraic numbers [Bos03]
is formalized in [Coh12]. However, in embedded systems we favor programs that
can be executed in a xed size memory, this prevents us from using these dynamic
representations of real numbers since computation over it requires an unbounded
amount of memory.
   Exact computation over real numbers can also be done on addition and multipli-
cation by using a xed point representation with dynamic size since we are able to
predict the sizes required by such computations using static analysis, the language
we target being free of loops or recursion. Thus, we aim at dening a program
transformation that removes square root and√division operations in every boolean
expression of the program,        e.g.,
                                  transforms x > y into y < 0 ∨ x > y 2 , in order
to use this exact computation with only addition and multiplication. Exactly com-
puting the boolean values protects the control ow of the program from rounding
errors.
   As our goal is to improve the safety of the systems we target, we want to for-
mally prove in Pvs that this transformation preserves the semantics. Therefore, by
computing exactly with addition and multiplication, we can ensure that the path
taken in each test is the same in both abstract and concrete semantics and that for-
mal proofs of properties about boolean values done on the abstract semantics still
hold on the concrete one. Indeed, if proofs on the original program using concrete
semantics are dicult, so are proofs on the output of program transformations due
to the size and the complexity of the produced code, this is the reason why the
correction of the transformation needs to be formally proven.
   The paper is an extended version of [Ner12],x it is organized as follows. First, we
dene the language on which the transformation applies and some general features
about the Pvs formalization. Then we dene the main transformation and two
auxiliary methods that respectively remove square roots and divisions from boolean
expression and from variable denitions. Finally, we present some experimental
results using the OCaml implementation of the transformation which is almost an
executable copy of Pvs formalization with few hand made extra features (Pvs and
OCaml les are available on the author's web page).
Journal of Formalized Reasoning Vol. 6, No. 1, 2013.
                                           Square Root and Division Elimination         ·     91




2. PRESENTATION OF THE LANGUAGE
2.1 Language denition
In this section we dene the syntax of the language the transformation applies to.
This language, that embeds the core functionalities of our targeted programs, is
a typed functional language that contains numerical (R) and boolean constants,
variable denitions (as let in instructions), tests (if then else), pairs and the usual
                                                        √
arithmetic +, −, × (we also use · instead of ×), /,        , the comparisons =, 6=, >,
≥, <, ≤ and boolean operators (∧, ∨, ¬). Therefore we can dene the syntax of
our language as follows:
  Definition 2.1.1.     Syntax of the language
   Prog :=      Constant           | fst Prog         | Var
              | uop Prog           | snd Prog         | let Var = Prog in Prog
              | Prog op Prog       | (Prog, Prog)     | if Prog then Prog else Prog
where:           Constant     ⊂ R ∪ {T rue, F alse}
                       op     ∈ {+, ×, /, =, 6=, >, ≥, <, ≤, ∧, ∨}
                                 √
                      uop     ∈ { , −, ¬}
  In order to complete the description of the language, we dene the type of a
program, in a typing environment Γ that associates to every free variable its type.
  Definition 2.1.2.     Type system
                            T ype := R | B | T ype × T ype
The rules are the usual ones for a functional language:
               Γ,x:A ` x:A
                Γ ` e:B
               Γ ` ¬e:B
                 Γ ` e:R                                          √
               Γ ` uop e:R
                                                     uop ∈ {−,         }
               Γ ` e1 :R    Γ ` e2 :R
                  Γ ` e1 op e2 :R
                                                     op ∈ {+, ×, /}
               Γ ` e1 :R    Γ ` e2 :R
                  Γ ` e1 op e2 :B
                                                     op ∈ {=, 6=, >, <, ≥, ≤}
               Γ ` e1 :B    Γ ` e2 :B
                  Γ ` e1 op e2 :B
                                                     op ∈ {∨, ∧}
               Γ ` e:T1 ×T2
               Γ ` fst(e):T1
               Γ ` e:T1 ×T2
               Γ ` snd(e):T2
               Γ ` e1 :T1     Γ ` e2 :T2
                 Γ ` (e1 , e2 ):T1 ×T2
               Γ ` e1 :T1     Γ,x:T1 ` e2 :T2
                  Γ ` let x = e1 in e2 :T2
               Γ ` f :B    Γ ` e1 :T     Γ ` e2 :T
                   Γ ` if f then e1 else e2 :T

  These types are used to identify the way a program has to be transformed. Indeed,
the transformation is dierent for pure numerical expressions (            e.g.,
                                                                       in a variable
denition) and for the ones used in boolean expressions (      i.e.,
                                                             as arguments of a com-
parison). It is easy to dene a type checking function in Pvs, type_infer(p,Γ),
                                             Journal of Formalized Reasoning Vol. 6, No. 1, 2013.
92      ·       Pierre Neron




that returns either a type or an undened value (U) if the program has no valid type
in the given environment. T yΓ (p) now denotes the result of type_infer(Γ)(p).
     Notation.
             In this paper we use the teletype font to represent Pvs expressions.
For clarity and conciseness, every element of Prog and subtypes of Prog will be
written using the sans serif font in the concrete syntax (instead of their Pvs abstract
syntax,     e.g.,
            we will write e1 op e2 for bop(op,e1,e2)), some Pvs expressions will
be abstracted by their equivalent mathematic expressions (                   e.g.,
                                                                       ∀Γ, T yΓ (p) 6= U
stands for FORALL tenv, type_infer(p,tenv) /= Undefined) and we will not
give the type when there is no ambiguity (Γ is always a typing environment             a   i.e.,
function from Var to T ype).
   Next, we dene the denotational semantics of a program in the language, using
an environment Env that associates to every variable its value. It is the usual
semantics of a functional language. The F ail value corresponds to the square roots
of negative numbers, divisions by zero and unsound types cases.
                               Denotational semantics of the language
The semantics is dened by the following induction rules:
     Definition 2.1.3.



  Env ` JcK=c
                                                 c   ∈ Constant

  Env,(x,e) ` JxK=e
    Env ` JEK=F ail
  Env ` Juop EK=F ail
      Env ` JEK=e
  Env ` Juop EK=uop(e)
                                                 uop ∈ {−, ¬} ∧ e 6= F ail
    Env ` JEK=e
          √                                      e < 0 ∨ e = F ail
  Env ` J EK=F ail
   Env ` JEK=e
          √     √                                e≥0
  Env ` J EK= e
  Env ` JE1 K=e1      Env ` JE2 K=e2
     Env ` JE1 op E2 K=e1 op e2
                                                 e1 6= F ail ∧ e2 6= F ail ∧ (op = / ⇒ e2 6= 0)
  Env ` JE1 K=e1      Env ` JE2 K=e2
       Env ` JE1 op E2 K=F ail
                                                 e1 = F ail ∨ e2 = F ail ∨ (op = / ∧ e2 = 0)
  Env ` JE1 K=e1      Env ` JE2 K=e2
        Env ` J(E1 ,E2 )K=F ail
                                                 e1 = F ail ∨ e2 = F ail
  Env ` JE1 K=e1      Env ` JE2 K=e2
      Env ` J(E1 ,E2 )K=(e1 ,e2 )
                                                 e1 6= F ail ∧ e2 6= F ail
  Env ` JEK=(e1 ,e2 )
  Env ` Jfst(E)K=e1
                                                 e1 6= F ail ∧ e2 6= F ail
   Env ` JEK=(e1 ,e2 )
  Env ` Jfst(E)K=F ail
                                                 e1 = F ail ∨ e2 = F ail
  Env ` JEK=(e1 ,e2 )
  Env ` Jsnd(E)K=e2
                                                 e1 6= F ail ∧ e2 6= F ail
   Env ` JEK=(e1 ,e2 )
  Env ` Jsnd(E)K=F ail
                                                 e1 = F ail ∨ e2 = F ail
  Env ` JE1 K=e1 Env,(x,e1 ) ` JE2 K=e2
       Env ` Jlet x = E1 in E2 K=e2
                                                 e1 6= F ail ∧ e2 6= F ail
  Env ` JE1 K=e1 Env,(x,e1 ) ` JE2 K=e2
      Env ` Jlet x = E1 in E2 K=F ail
                                                 e1 = F ail ∨ e2 = F ail




Journal of Formalized Reasoning Vol. 6, No. 1, 2013.
                                               Square Root and Division Elimination          ·     93



 Env ` JFK=T rue     Env ` JE1 K=e1
   Env ` Jif F then E1 else E2 K=e1
 Env ` JFK=F alse     Env ` JE2 K=e2
   Env ` Jif F then E1 else E2 K=e2
        Env ` JFK=F ail
 Env ` Jif F then E1 else E2 K=F ail

  We now denote JpKEnv the abstract semantics of p into an environment Env
i.e.,
(     the v such that Env ` JpK = v , in Pvs the corresponding function is called
semantics). The language being dened, we now describe some subtypes of Prog,
that represent restricted syntactic forms.

2.2 Program subtypes
  2.2.1            Normalized language.
                                 The normalized language is the subtype on which
our transformation applies, it is a subtype of the Prog type that has the following
denition:
                                Expressions and programs normal form
The unary expressions E are built with operators and the expressions E with pairs.
  Definition 2.2.1.

                                 u

                   Eu     := Var | Constant | uop Eu | Eu op Eu | fst Eu | snd Eu
                    E     := (E, E) | Eu
The programs P can also contain variable denitions and tests:
                            P := let Var = P in P | if P then P else P | E
Hence, every time we meet an arithmetic or boolean operator, we know there are
neither denitions nor tests inside its arguments and fst and snd constructs can
only be applied to variables (in well typed programs) since the pair constructs have
been removed at top level in their arguments. Therefore they can not contain any
square roots or divisions as subexpressions. In Section 3.5 the rules allowing the
transformation of any program in Prog into a program in P is introduced.
   2.2.2           Target language.
                            Then we dene the language that corresponds to pro-
grams from which divisions and square roots have been eliminated. Certainly, we
can not eliminate all square
                        √      roots and divisions from any program,
                                                                   √                 e.g.,
                                                                               the exe-
cution of the program 2 will still return a rounded value of 2, but we are able
to remove them from all the boolean values computations, particularly the boolean
values of the tests. Therefore, it allows us to protect the control ow of the program
from rounding errors introduced by these operations. We dene new subtypes of
expressions and programs, depending on which operators are allowed in dierent
parts of the program.
                       Target language The Figure 1 describes the dierent set
of operators, expressions and programs that are used to dene the target language.
  Definition 2.2.2.



N is the set of numerical expression with square roots and divisions
    √

N is the set of square root and division free numerical expressions
        ,/


in B , we allow variable denitions of square root and division free boolean
   expressions in order to reduce the size of the output program as we will see in
             let


   Section 5.
                                                  Journal of Formalized Reasoning Vol. 6, No. 1, 2013.
94       ·      Pierre Neron




                                 √
               •   N uop√ = {−, }                                       •   N uop = {−}
               •   N bop/ = {+, ×, /}                                   •   N bop = {+, ×}

                                                 Numerical Operators

               •   Buop = {¬}
                                                                        •   Cbop = {=, 6=, <, >, ≤, ≥}
               •   Bbop = {∧, ∨}

                      Boolean Operators                                     Comparison Operators

                    •N     :=   N uop N | N N bop N | fst N | snd N
                    •N√
                           ,/ :=   N uop√ N√,/ | N√,/ N bop/ N√,/ | fst N√,/ | snd N√,/

                                                Numerical Expressions

             •Blet   :=         Buop Blet                  | Blet   Bbop Blet             | N   Cbop N
                            | (Blet , Blet )               | fst Blet                     | snd Blet
                            | let Var = Blet in Blet

                                                 Boolean Expressions

                   •EN     := N | Blet | (EN , EN )           •EN√           := N√,/ | Blet | (EN√,/ , EN√,/ )
                                                                  ,/


                                                       Expressions

             •PN :=       let Var = PN in PN | if PN then PN else PN | EN
             •PN√         := let Var = PN in PN√,/ | if PN then PN√,/ else PN√,/ | EN√,/
                     ,/


                                                       Programs

                                            Fig. 1. Target language denitions

E is the set of expressions where square roots and divisions are not allowed
     N
E is the set of expressions where square roots and divisions are only allowed
  in numerical expressions that are not sub-terms of boolean expressions
     N√,/


P is the set of programs that do not contain any square root or division
     N
P is the set of programs that can contain square roots or divisions only in
  the nal numerical expressions (not in the body of any variable denition or any
     N√,/


  test).
The language P is the language the main transformation targets. For all pro-
grams in this language, the boolean sub-expressions and the variables they might
                           N√,/

depend on are free of square roots and divisions, they can be exactly computed with
+, ×, −. Thus the control ow of such a program is protected from any rounding
error.
Journal of Formalized Reasoning Vol. 6, No. 1, 2013.
                                       Square Root and Division Elimination          ·     95


                √                                      √
  For example ( x, a > b) is in EN√,/ but not in EN but a > b is in none of them.
One can notice that any program in the targeted subtype that returns a boolean
value is completely square root and division free.
                        Output Boolean program A program in PN                     returning
a boolean value is in PN:
  Proposition 2.2.1.                                                         √
                                                                              ,/




                    ∀ p ∈ EN√,/ , ∃Γ, T yΓ (p) = Bn =⇒ p ∈ PN
These denitions allow us to characterize the set of programs transformed by each
step of our transformation and what kind of programs it produces.

3. PRELIMINARIES ON THE PROGRAM TRANSFORMATION
3.1 About the Pvs Proof Assistant
   3.1.1 Pvs  sub-typing.  The specication of an algorithm and the related proofs
in Pvs can be expressed using the Pvs predicate sub-typing. Given a type T and
a predicate P of type T > B, {x: T | P(x)} is the subtype of T of all elements x
of type T that satisfy P, this type can also be denoted (P). Then every denition
of a function in Pvs can be specied using these subtypes,      e.g.,
                            f(x: (P)): {x': T' | P'(x')}
denes a partial function on T that takes only elements x of type T that satisfy
P and returns elements of type T' that satisfy P'. When Pvs typechecks such a
function, it generates Type Check Conditions (TCC) where we have to prove that:

f can be applied to every element of type (P) (     Completeness
                                                              )
∀ x: T, f(x): T' ∧ P'(f(x)) (      Soundness    )
if f is recursive, then for every recursive call on e:
  - e : (P) ( Recursive call correctness  )
  - a measure decreases, according to a well founded order provided in the deni-
              Termination
    tion of f (              )
The type of a function can also be restricted using the HAS_TYPE judgement,              e.g.,
given two types T and T', two subtypes S of T and S' of T' and a function:
              f (x: T): T'
then we can state the following judgement:
              f (x: S) HAS_TYPE S'
and once the corresponding TCC are proven, use either T' or S' as type of f(x)
when x has type S. Therefore, in this paper, we will not give correctness lemmas of
the functions we dene, these lemmas will be encoded in the type of the function
using the predicate sub-typing of Pvs.
   3.1.2 Orders on abstract datatypes.   Pvs requests us to prove the termination
of every recursive function by giving a measure that decreases according to a well
founded order in every recursive call. When using Pvs abstract datatypes, most of
the time the order used is the subterm relation (denoted ) but this measure is not
always sucient. Therefore, in order to prove the termination of some functions we
had to dene some lexicographical orders. To this purpose, we dened the following
functions :
                                         Journal of Formalized Reasoning Vol. 6, No. 1, 2013.
96     ·     Pierre Neron




- lexical_order_nat_based(m: [T -> N], o1: (wf ?[T])): (wf ?[T])
- lexical_order(o1: (wf ?[T]), o2: (wf ?[S])): (wf ?[[T,S]])
where wf ?[T] is the Pvs predicate well_founded[T] and
- lexical_order_nat_based(m,o)(x,y) =
             m(x) < m(y) ∨ (m(x) = m(y) ∧ o(x,y))
- lexical_order(o1,o2)((x1,x2),(y1,y2)) =
             o1(x1,y1) ∨ (x1 = y1 ∧ o2(x2,y2))
These orders will be used to extend the subterm relation in some particular cases.

3.2 No Fail Assumption
The transformation we dene in this paper targets critical embedded systems, these
programs are proved to be type safe and one can also prove that failure due to
divisions by zero or square roots of negative number do not occur. Therefore we
assume that the programs we want to transform are well typed (there exists a
type environment that allows us to type the program) and we prove the type and
semantics preservation only for every environments where the initial program is
well typed and its semantics does not fail. Hence we will not have to force the
failure cases that disappear when removing divisions and square roots,  e.g.,
                                                                            we can
transform 1/x > 0 into x > 0 instead of if x = 0 then Fail else x > 0 even if in an
environment where x is evaluated to 0 the program 1/x > 0 fails whereas x > 0
returns false. The type and semantics preservations are dened in the language of
Pvs by the predicate sem_ty_nf_eq(p)(p'), that is:

            (∀Γ, T yΓ (p) 6= U =⇒ T yΓ (p') = T yΓ (p)) ∧
            (∀Env, J p KEnv 6= F ail =⇒ J p' KEnv = J p KEnv )
We consider that programs p and p' are                 equivalent
                                                       when sem_ty_nf_eq(p)(p')
holds. Given this type and semantics preservation predicate, we can now formally
dene our main goal which is to present a transformation Elim that has the following
specication:
    Definition 3.2.1. Elim specication
  Elim(Γ)(p: Prog | T yΓ (p) 6= U) : { p': PN√,/ | sem_ty_nf_eq(p)(p')}

The Elim function is dened by a sequence of elementary transformations, all of
them preserving the semantics when the program does not fail. Every elementary
transformation is formalized using a function whose output type is of the form:
       { p': P' | sem_ty_nf_eq(p)(p')}        where P' is a subtype of Prog

3.3 Well typed program
In the previous denition, the typing environment Γ which is an argument of the
function and proves the program is well typed, is needed to ensure some syntactic
structure (  e.g.,
                fst(a+b)) never happens. It allows us to prove type checking con-
ditions when we dene some partial transformations and to prove the transformed
program is in PN√,/ but the transformed program does not depend on it.
Most of the time the predicate wtp(p) (well_typed_program = ∃Γ, T yΓ (p) 6= U)
would be sucient but we need to have the environment explicit when we want to
prove, for example, that T yΓ (e) 6= U ∧ T yΓ (e') 6= U =⇒ T yΓ ((e,e')) 6= U

Journal of Formalized Reasoning Vol. 6, No. 1, 2013.
                                               Square Root and Division Elimination         ·     97




3.4 Substitution
We now describe a function that denes a capture avoiding substitution of every
free occurrence of a variable x in a program p by a given program e (also denoted
p[x:=e]). The semantics and the types of p are preserved in every environment
where e is well typed and does not fail. That gives the following specication:
 replace(x: Var,e,p: Prog):         {p': Prog | ∀Γ, Env,
       J p' KEnv = J p KEnv;(x,JeKEnv ) ∧ T yΓ (p') = T yΓ,(x,T yΓ (e)) (p)}
This substitution renames bound variables in p that are free in e. If Pvs usual ter-
mination proofs on inductive structures relies on the well founded subterm relation,
the variable renaming and substitution prevent us from using this order. Therefore,
termination is ensured by the lexicographic order:
              lexical_order_nat_based(let_number,)
let_number(p) being the number of variable denitions in p. The replace func-
tion also has several types that ensure the preservation of program subtypes when
we have some hypothesis on e,          e.g.,
              replace(x: Var, e: Eu , p: P) HAS_TYPE P
Correctness of the substitution is proven using the two following lemmas that we
will use every time we have to rename variables. We denote F V (p) the set of the
free variables of p, then:
    - no_FV_no_change: LEMMA =
              ∀ x, p, x ∈ / F V (p) =⇒ ∀ Env, v, JpKEnv = JpKEnv;(x,v)
    - no_FV_no_change_type: LEMMA =
              ∀ x, p, x ∈ / F V (p) =⇒ ∀ Γ, S, T yΓ (p) = T y(Γ;(x,S)) (p)
3.5 Program normalization
The core of the transformation operates on programs in P, however since we aim at
transforming every program in Prog we rst present a transformation that trans-
forms every program in Prog into an equivalent program of type P. This trans-
formation can be done using the following set of reduction rules that takes the
tests and variable denitions out of the binary operators and pairs and reduces the
projections:
inversions between variable denitions and other kinds of expressions:
  - uop (let x = e1 in e2)    −→ let   x = e1 in (uop e2)

  - (let x = e1 in e2) op e3   −→
              let x' = e1 in (e2[x:=x'] op e3)            x'   ∈
                                                               / F V ((e2,e3))
  - e1 op (let x = e2 in e3)   −→
              let x' = e2 in (e1 op e3[x:=x'])            x'   ∈
                                                               / F V ((e1,e3))
  - ((let x = e1 in e2),e3)   −→
              let x' = e1 in (e2[x:=x'],e3)          x'   ∈
                                                          / F V ((e2,e3))
  - (e1,let x = e2 in e3)    −→
              let x' = e2 in (e1,e3[x:=x'])          x'   ∈
                                                          / F V ((e1,e3))
  - fst (let x = e1 in e2)  −→ let x   = e1 in fst (e2)

  - snd (let x = e1 in   e2)) −→ let   x = e1 in snd (e2))




                                                 Journal of Formalized Reasoning Vol. 6, No. 1, 2013.
98       ·       Pierre Neron




inversions between tests and other kinds of expressions:
     - uop (if f then e1 else e2)    −→
                  if f then (uop e1) else (uop e2)

     - (if f then e1 else e2) op e3   −→
                  let xi = if f then e1 else e2 in (xi op e3)        xi   ∈
                                                                          / F V (e3)
     - e1 op (if f then e2 else e3)   −→
                  let xi = if f then e2 else e3 in (e1 op xi)        xi   ∈
                                                                          / F V (e1)
     - ((if f then e1 else e2),e3)   −→
                  let xi = if f then e1 else e2 in (xi,e3)      xi   ∈
                                                                     / F V (e3)
     - (e1,(if f then e2 else e3))   −→
                  let xi = if f then e2 else e3 in (e1,xi)       xi ∈
                                                                    / F V (e1)
     - fst (if f then e1 else e2)  −→ if f then fst (e1) else fst (e2)
     - snd (if f then e1 else   e2) −→ if f then snd (e1) else snd (e2)

projections reductions:
     - fst (e1,e2)   −→ e1
     - snd (e1,e2)    −→ e2
The transformation rules for a test inside a binary operator or a pair use a variable
denition in order to avoid duplicating the other arguments, a process that can
strongly increase the size of the transformed code.
   Pvs       specication.
                      Creating new variable denitions makes the direct termination
proof more complicated. Therefore we rst dene the following set of functions that
normalize the application of operators, pair or projections to a program in normal
form:
- uop_P_switch(uop)(p:P | wtp(p)): {p':P | sem_ty_nf_eq(uop p)(p')}
- fst_P_switch(p:P | wtp(p)): {p':P | sem_ty_nf_eq(fst(p))(p')}
- snd_P_switch(p:P | wtp(p)): {p':P | sem_ty_nf_eq(snd(p))(p')}
- op_P_switch(xi)(op)(p1,p2:P | wtp(p1 op p2)):
                                 {p':P | sem_ty_nf_eq(p1 op p2)(p')}
- pair_P_switch(xi)(p1, p2:P | wtp((p1,p2))) :
                                 {p':P | sem_ty_nf_eq((p1,p2))(p')}
The unary operator switches terminate using the usual subterm order. Binary
operator switches involving variable renaming, the termination proof of the last
two functions is done using the depth of the program. The correctness is proven
by using the no_FV_no_change lemmas introduced in Section 3.4. Using these
denitions we can dene the main function that transforms any program into an
equivalent normalized program by iterating these functions:
p_norm_reduction(xi:Var)(p:(wtp)): {pp:P | sem_ty_nf_eq(p)(pp)} =
CASES p OF
        uop e1: uop_P_switch(uop)(p_norm_reduction(xi)(e1))...
   Since we can transform every well typed program in Prog into an equivalent one in
P, we now describe the major function Elim of the transformation that transforms
any well typed program in P into an equivalent one in PN√,/ .

4. NORMALIZED PROGRAM TRANSFORMATION
This Elim function is a recursive program transformation algorithm eliminating
square roots and divisions. It uses two functions, Elim_bool and Elim_let, that
Journal of Formalized Reasoning Vol. 6, No. 1, 2013.
                                       Square Root and Division Elimination          ·     99




have the following specications:
                     Elim_bool    and Elim_let specications
            transforms any comparison (the comparison_expression subtype will
  Definition 4.1.
Elim_bool
be formally dened in Section 5) into an equivalent boolean program without any
square root or division and Elim_let transforms a variable denition into an equiv-
alent one that contains neither square root nor division in its body. Formally these
functions have the following denitions:
Elim_bool(Γ)(xsq: Var)(c: comparison_expression(Γ)) :
                                    { e: Blet | sem_ty_nf_eq(c)(e) }
Elim_let(Γ)(x: Var, p1: PN√,/ , p2: P | T yΓ (let x = p1 in p2) 6= U):
      { x': Var, p1': PN , p2': P |
                  sem_ty_nf_eq(let x = p1 in p2)(let x' = p1' in p2') &
                  if_letin_number(p2') <= if_letin_number(p2) }
xsq is a variable used to name some boolean expressions in order to avoid formula
duplications.
                Given an expression in E, then by applying the Elim_bool function
to every comparison we can nd in this expression, we can dene the Elim_bool
  Remark 1.


function that transforms every well typed expression in E into an equivalent one in
EN√,/ that does not contain any square root or division.
The function if_letin_number(p) gives the number of variable denitions and
tests which occur in p, it will be used to prove the termination of the main algorithm.
The Elim_bool function will be described in Section 5, and the Elim_let one in
Section 6. Therefore using these two functions, we can dene the recursive algorithm
that transforms any program in P in an equivalent one in PN√,/ :

                       The Elim function
 The transformation is a recursive algorithm on p:
    Definition 4.2.


 Elim(Γ, xsq)(p:P | T yΓ (p) 6= F ail): {p':PN√,/ | sem_ty_nf_eq(p)(p')}=
      CASES p OF
        let x = p1 in p2:

           LET pn1 = Elim(Γ,xsq)(p1) IN
           LET (x',p1',p2') = Elim_let(Γ)(x,pn1,p2) IN
                     let x' = p1' in Elim(Γ,xsq)(x', T yΓ (p1')))(xsq)(p2'),

        if f then p1 else p2:

           if Elim(Γ,xsq)(f) then Elim(Γ,xsq)(p1) else Elim(Γ,xsq)(p2)

      ELSE Elim_bool_expr(Γ)(xsq)(p)
      ENDCASES
      MEASURE (if_letin_number(p)) BY <

elim_bool_expr applies elim_bool on all the subterms of an expression that are
comparison expressions. According to the typing predicate of the Elim_let func-
tion, the termination is ensured by proving that the number of variable denitions
and tests strictly decreases. The correction is ensured by both Elim_bool and
Elim_let typing predicates. Therefore, applying the main_elim function, which is
the composition of both p_norm_reduction and Elim functions to any program in
Prog, we can state that every program in Prog has an equivalent one in PN√,/ :
                                          Journal of Formalized Reasoning Vol. 6, No. 1, 2013.
100       ·     Pierre Neron




     Theorem 1.     Prog is equivalent to PN√,/
       ∀ Γ, xsq, ifname,
             main_elim(Γ)(xsq,ifname)(p: Prog | T yΓ (p) 6= F ail):
                                          {p': PN√,/ | sem_ty_nf_eq(p)(p')}
And its corollary, using Proposition 2.2.1, stating that every boolean program
(whose type is in Bn ) has an equivalent division and square root division free pro-
gram:
     Corollary 1.       Elimination in boolean programs
       ∀ Γ, xsq, ifname,
           main_elim(Γ)(xsq,ifname)(p: Prog | T yΓ (p) ∈ Bn ) HAS_TYPE PN
  Once we have seen the general structure of our transformation, let us focus on
the Elim_bool function in Section 5 and on the Elim_let function in Section 6.

5. √ AND / ELIMINATION IN BOOLEAN EXPRESSIONS: Elim_bool
In this section, we describe the function Elim_bool that transforms a well typed
boolean expression built with comparisons into an equivalent expression which is
free of divisions and square roots (     i.e.,
                                       of class Blet ). The elimination of square roots
and divisions in boolean formulas is a particular    case of the quantier elimination
over real closed elds     e.g.,        √
                             the formula x + √3y > 4 can be rewritten as:

              ∃ x0 , y 0 , y 00 , x02 = x ∧ y 02 = y ∧ y 00 × y 0 = 3 ∧ x0 + y 00 > 4
 Then by eliminating the three quantiers, we get an equivalent boolean formula
without any division or square root. The general quantier elimination with cylin-
drical algebraic decomposition [Tar51, Col76] has been implemented as QEPCAD1
but this algorithm does not succeed in most of our cases due to the large num-
ber of free variables in the context of program transformation. The elimination of
square roots and division in formulas has also been studied by V. Weispfenning in
its restriction of the quantier elimination to the quadratic case [Wei97]. However
we do not need a general quantier elimination algorithm nor even the quadratic
case restriction for the elimination of square roots and division. Thus, we dene
a specic transformation for square root and division elimination that allows us
to eliminate all occurrences of one square root in a single step and produce more
concise code.

5.1 Expressions subtyping
As introduced in Section 2, we describe the input and output program type of the
transformations using the subtypes of Prog. Elim_bool is a partial function that
only applies to a subtype of the general programs that is:
comparison_expression(Γ): TYPE =
 { e1 op e2: Prog | T yΓ (e1 op e2) = B & op ∈ Cbop & e1: N√,/ & e2: N√,/ }
We also dene the type of well typed numerical expressions:
         wt_num_expr(Γ): TYPE = { e: N√,/ | T yΓ (e) = R}.

1   see http://www.usna.edu/cs/~qepcad/B/QEPCAD.html
Journal of Formalized Reasoning Vol. 6, No. 1, 2013.
                                       Square Root and Division Elimination                     ·   101




It is more convenient to explicitly have the syntactic form of the arguments e1 and
e2 using the type N√,/ , it allows us to prove completeness of the function without
extracting their syntactic structure from the type. However this needs to be done
when we invoke the Elim_bool itself using the following lemma :
expr_wt_num_is_num_expr: LEMMA ∀ (e:E |∃Γ, T yΓ (e) = R) HAS_TYPE N√,/
The well typed hypothesis is also used to ensure arguments of projections are either
projections or variables (since the projections on pair constructors has already been
reduced and no constant has type pair):
no_op_st_fst_wt_num: LEMMA ∀ (x: {p: N√,/ | wtp(p)}), (y: Prog):
      (fst?(x) OR snd?(x)) & y  x ⇒ fst?(y) OR snd?(y) OR Var?(y)
where fst?, snd? and Var? are predicates that are true if the element has the
corresponding constructor as head symbol.
   Using these type denitions we can dene the rst step of elimination of square
roots and divisions which is a reduction to a normal form for numerical expressions
N√,/ with division as head operator.
5.2 One division normal form
The elimination of the division is in fact quite simple since every numerical ex-
                          √
pression on +, −, ×, /,       can be represented with only one division at head.
Therefore the expression we get by reducing expressions to the same denominator
without splitting square roots corresponds to the following normal form:
  Definition 5.2.1.      Division and polynomial normal forms
                       PNF
        DNF := PNF |
                       PNF                                                          q
        PNF :=   | PNF   +   PNF   | PNF   ×   PNF       |   −   PNF            |   N√,/

                 | fst PNF         | snd PNF             | Constant             | Var

   Reduction to division normal form is done by the to_dnf function that transforms
any well typed numerical expression into an equivalent one with only one division
(if there is any) as head operation. This corresponds to the following specication:
 to_dnf(Γ)( e: wt_num_expr(Γ) ):
   { eout: DNF | sem_ty_nf_eq(e)(eout) & sq_number_eq(e,eout) }
which implements the following set of rules :
  Definition 5.2.2.      Head division reduction
        e1 +
             e2
             e3
                −→
                   e3 .e1 + e2
                        e3
                                           e1
                                           e2
                                              + e3 −→
                                                      e1 + e2 .e3
                                                          e2
                                                                 (HD +)
           −
             e1
             e2
                −→
                   −e1
                    e2
                                      −(−e ) −→ e   1            (HD −)
                                                                   1


        e1 ×
             e2
             e3
                −→
                   e1 × e2
                       e3
                                      e
                                      e
                                         × e −→
                                               1
                                               2
                                                     e ×e
                                                     3
                                                        e
                                                                 (HD ×)
                                                                   1
                                                                           2
                                                                                3

             e1
             e2
             e3
                −→
                    e1
                   e2 .e3
                                           e
                                               −→  e2
                                                     e .e
                                                     1
                                                      e
                                                                 (HD /)
                                                                   1       3

                                                   e3                  2

                This transformation is only correct in the context of the no fail
assumption since the semantics equivalence of the rule −→              only holds
  Remark 2.
                                                                       e1               e1.e3

when Je3K 6= 0.
                                                                           e2            e2
                                                                           e3

                                               Journal of Formalized Reasoning Vol. 6, No. 1, 2013.
102     ·       Pierre Neron




                sq_number_eq(e,eout) is a predicate that will be used to prove the
termination of the Elim_bool function. It states that every square root that appears
  Remark 3.


in the output was already in the input: √                  √
       sq_number_eq(e,eout) = ∀ sq, sq ≤≤ eout ⇒ sq ≤≤ e
where x ≤≤ y means that x is a subterm of y or is equal to y.
5.3 Division elimination rules
Once we have a comparison between two DNF form, the head division can be easily
eliminated by multiplying both arguments by the denominators.
  Definition 5.3.1.          Elimination of division with cases
      when < ∈ {=, 6=}: <        e1
                                  e2
                                         e3
                                         e4 −→      e1.e4 − e3.e2 < 0
      when < ∈ {>, <, ≥, ≤}:           e1   e3
                                        e2 < e4
                                             −→
            (e1.e4 − e3.e2 < 0 ∧ e2.e4 > 0) ∨ (e3.e2 − e1.e4 < 0 ∧ e2.e4 < 0)
But since we want to avoid the creation of new comparisons due to the case distinc-
tion depending on the sign of the denominators when multiplying, we will sometimes
prefer the following elimination rule that multiplies both arguments by the square
of the denominators:
  Definition 5.3.2.          Elimination of division
     when < ∈ {=, 6=}: < −→ e1.e4 − e3.e2 < 0
                                  e1
                                  e2
                                         e3
                                         e4
     when < ∈ {>, <, ≥, ≤}: < −→ e1.e2.e4 − e3.e4.e2 < 0
                                        e1
                                        e2
                                               e3
                                               e4
                                                                    2         2


                 The application of this rule eliminates the last division that is not
inside a square root. Therefore the expressions produced are boolean combinations
  Remark 4.


of relations between numerical expressions in and 0.    PNF

These elimination rules are implemented in  Pvs with the following function:

 elim_div_rule1(Γ)(p: comparison_expression(Γ)):
       { e1 op e2: comparison_expression(Γ) | sq_number_eq(p,e1) &
              sem_ty_nf_eq(p)(e1 op e2) & P N F ?(e1) & e2 = 0 }
The OCaml implementation gives the option to use either this rule or the usual one
(with case distinction) but only this one was proven in Pvs since it gives better
results for the size of the produced code.
The head division being eliminated, we have to eliminate a top level square root
that will make the divisions in the arguments of square roots appear at top level
and allow us to continue the elimination of both operations.

5.4 Square root elimination
For every comparison between a PNF form and 0 we choose one square root that
is at top-level, that means this square root does not appear in the argument of
another square root.
                       Top level square root Given e an arithmetic expression,
an expression q is a top level square rootp of e when: p
  Definition 5.4.1.


                        √                                       √
                            q ≤≤ e ∧ ¬∃ q',         q' ≤≤ e ∧       q   q'

Journal of Formalized Reasoning Vol. 6, No. 1, 2013.
                                               Square Root and Division Elimination         ·        103


                                                                               √
          √ level square root Q we factorize the PNF expression in the form (P. Q +
Given a top
R) where Q does not appear in P or R:
  factorize_sqrt(Γ)(e:wt_N_expr(Γ) | P N F ?(e))(q:wt_N_expr(Γ)):
                                                    √
     { p,r: wt_N_expr(Γ) | sem_ty_nf_eq(e)(p. q + r)
         sq_number_but_q_eq(e)(q)(p) & sq_number_but_q_eq(e)(q)(r)}
where sq_number_but_q_eq states that every square root of an output was already
in an input and is dierent from q. Then by splitting
                                                  √ cases depending on the signs
of P and R we get a new formula equivalent to P. Q + R > 0 under the condition
that Q ≥ 0,        e.g.,
                 when < is >, we have the following rule:

           √                                  (P > 0 ∧ R > 0) ∨
        (P. Q + R) > 0            −→          (P > 0 ∧ P2 .Q − R2 > 0) ∨
                                              (R > 0 ∧ R2 − P2 .Q > 0)
In the last expression, one can notice some of the comparisons that are present in
this formula are equal. Thus, in order to reduce the size of the nal expression, we
name them and share their dierent occurrences instead of duplicating them, this
is the reason why we allowed variable denitions of boolean expressions in the Blet
subtype, therefore the complete elimination rule of one square root is:
                              let xsq = ((P > 0,R > 0),(P2 .Q − R2 > 0,P2 .Q − R2 6= 0))        in
        √                            fst(fst(xsq)) ∧ snd(fst(xsq)) ∨
  (P.       Q   + R) > 0 −→
                                       fst(fst(xsq)) ∧ fst(snd(xsq)) ∨

                                         snd(fst(xsq)) ∧¬ fst(snd(xsq)) ∧ snd(snd(xsq))


This corresponds to the elimination of one square root in a > comparison, similar
rules can be dened for the other comparison operators.
   Since the transformation we are dening in Pvs only applies on comparisons,
we rst have to recursively eliminate all the square roots and divisions from the
four produced comparisons before combining them to produce a boolean expression
equivalent to the input comparison. Therefore the implementation of these rules
relies on composition functions such as
name_comp(xsq: Var, e1, e2, e3, e4: Prog): Prog =
       let xsq = ((e1,e2),(e3,e4)) in
               fst(fst(xsq)) ∧ snd(fst(xsq)) ∨
                 fst(fst(xsq)) ∧ fst(snd(xsq)) ∨
                   snd(fst(xsq)) ∧¬ fst(snd(xsq)) ∧ snd(snd(xsq))
and on elimination rules such as
 elim_sqrt_rule_gt(Γ)(p,q,r: wt_num_expr(Γ)) :
  { e1, e2, e3, e4: comparison_expression(Γ) |
                                       √
     ∀(x: Var): sem_ty_nf_eq(p. q + r > 0)(name_comp(x,e1,e2,e3,e4))} =
         (p > 0,r > 0,p2 .q − r2 > 0,p2 .q − r2 6= 0)
Using reduction to DNF, square root factorization and the elimination rules for
division and square root, we can dene the main algorithm which transforms a
comparison into an equivalent fragment of code that contains neither division nor
square root. This algorithm is a recursive combination of these four transforma-
tions:


                                                  Journal of Formalized Reasoning Vol. 6, No. 1, 2013.
104        ·      Pierre Neron




                                 elim_bool     description
  While the comparisons contains divisions or square roots, do:
      Definition 5.4.2.



         Reduce to          DNF
         Eliminate the head division
         Factorize using one top level square root
         Eliminate that square root
The full transformation of the comparisons is dened by the elim_bool function
whose specication was given in Denition 4.1. There are two distinct kinds of
TCC that have to be proven:
p: Blet , comes from the fact that the elim_bool functions returns either a PNF
 comparison whose square root list is empty or a composition (such as name_comp)
 of expressions in Blet
sem_ty_nf_eq, this is proven by composition of the sem_ty_nf_eq predicates of
 the reductions and elimination rules
In order to ensure the termination of the algorithm, we prove that the number
of distinct square roots that are sub-terms of the comparison strictly decreases.
Indeed, after applying the 4 steps, every square root in the output comparisons was
already in the input and is dierent from the one we eliminated, which was also in
the input.
                            √
   Example 5.4.1. / and         elimination
                        let xsq = ((z   > 0,x.z > 0),(z2 .y − (x.z)2 > 0,z2 .y − (x.z)2 6= 0))   in
        √
      x+ y                       fst(fst(xsq)) ∧ snd(fst(xsq)) ∨
       z       > 0 −→
                                   fst(fst(xsq)) ∧ fst(snd(xsq)) ∨

                                     snd(fst(xsq)) ∧¬ fst(snd(xsq)) ∧ snd(snd(xsq))


  Complexity. In a comparison A, if we write |A|    the number of distinct square
                                                                √

roots, the number of comparisons produced by eliminating the square roots in this
                                √
comparison is bounded by 4|A| . We did not study the exact complexity of the
algorithm since the reduction into DNF and the factorization may also increase the
size of the formula. Nevertheless, experimentally our specialized algorithm is able
to transform bigger formulas than the QEPCAD implementation of the quantier
elimination by cylindrical algebraic decomposition,                 e.g.,
               ∃sq, sq 2 = q ∧ sq ≥ 0 ∧ (p1 .sq + r1 ).(p2 .sq + r2 ).(p3 .sq + r3 ) > 0
Indeed, the complexity of our transformation does not depend on the number of
variables of the formula but only on the number of square roots and divisions.
   The elimination of square roots and divisions being dened, we detail in the
following section the second transformation used in the main transformation. It
transforms a variable denition into an equivalent one without square roots or
divisions.

6. TRANSFORMATION OF VARIABLES DEFINITIONS: Elim_let
In this section, our goal is to dene how to transform a variable denition in order to
take the divisions and square roots out of the body. We will describe a function that
Journal of Formalized Reasoning Vol. 6, No. 1, 2013.
                                               Square Root and Division Elimination              ·      105




corresponds to the specication given in Denition 4.1. We noticed that inlining
the variable denitions satises this specication but it leads to an explosion of the
size of the code therefore we will now present a way to inline only the divisions and
square roots as in Example 6.1.
   The intuitive idea for suppressing these operations in a variable denition is to
only name its subexpressions that are free of them. Then we replace the variable
in the scope with an expression depending on these new dened variables, as in the
following example:
  Example 6.1.
                                                      √
   let x = if y > 0 then   (a1 + a2)/b   else c   +       d1.d2 in P   −→
                                                                                            √
                                                                                        x0+ x2
      let (x0,x1,x2) = if y > 0 then (a1    + a2,b,0)      else (c,1,d1.d2) in P[x:=
                                                                                          x1 ]

Square roots and divisions that were used to dene x are now explicit in P. In this
section, we only use the mathematic font in order to describe the transformation
and for clarity we use multiple variable denitions.

6.1 Transformation of the variable denition code
The elimination of square roots and divisions from a variable denition (let x = p1
in p2 where x: Var, p1: PN√,/ and p2: P) relies on a decomposition of its body p1 in:
the   program part P p of type E       n
                                        N√,/   −→ PN√,/ and EnN −→ PN
the list of expressions (e1 , ..., en ) of EnN√,/ such that P p(e1 , ..., en ) = p1, that
 decomposes itself in:
 - the    template T emp of type EkN −→ EN√,/
 - the list of k -tuples of division and square root free                 subexpressions
                                                                                 se1 , ..., sen
   of type EkN such that: ∀i ∈ [1...n], Env, JT emp(sei )KEnv = Jei KEnv
Given such a decomposition, we have that:
                    ∀Env, Jp1K = JP p(T emp(se1 ), ..., T emp(sen ))KEnv
and we transform the variable denition in the following way:
                           Variable denition transformation
A variable denition is transformed by commuting elements of its decomposition:
  Definition 6.1.1.



let x =   P p(T emp(se1 ), ..., T emp(sen ))                  let (x1 , ..., xn ) = P p(se1 , ..., sen )
                                                      −→
 in p2                                                          in p2[ x := T emp(x1 , ..., xn ) ]

The is not a unique solution for the template computation and due to the complexity
of the elimination of square roots and divisions we really focus on minimizing the
number of square roots that appear in it (the template is then inlined). Therefore,
for genericity reasons, the template computation is only axiomatized in Pvs (we
assume that such a function exists) but the OCaml program implements one version.
   We now begin the description of the two decompositions. In order to sim-
plify the presentation, we introduce the following notation. For every program
p, (f un (x1 , ..., xn ) → p) is a function of Pn −→P, such that:
             (f un (x1 , ..., xn ) → p)(u1 , ..., un ) = p[x1 := u1 ; ...; xn := un ]
The rst decomposition transforms the body of the denition that is in PN√,/ into
                                                  Journal of Formalized Reasoning Vol. 6, No. 1, 2013.
106      ·     Pierre Neron




a program part (the part that contains the local variable denitions and tests) and
the expression part.
6.2 Program and expression part decomposition
We dene the following recursive algorithm             Decompose, that computes from a pro-
gram p in PN√,/ , its      program part
                                  and its            expression part.
                            Program and expression part decomposition
   Decompose(p) =
  Definition 6.2.1.


     if p ∈ E then ((f un x → x), [p])
                    N√,/
     if p = let y = a in p' then
       (pp,ep) := Decompose(p')
       return ((f un x → let y = a in pp(x)), ep)
     if p = if B then p else p then
       (pp ,ep ) := Decompose(p )
                              1          2


       (pp ,ep ) := Decompose(p )
                1    1                       1


       return ((f un (x , x ) → if B then pp (x ) else pp (x )), ep @ep )
                2    2                       2
                               1    2                    1   1              2   2       1   2

     where @ denotes the concatenation of lists.
  Example 6.2.1.
                                             √
      Decompose( if F then let y = a in a + b else c) = √
          (f un (x, y) → if F then let y = a in x else y , (a+ b,c))
The program p being in PN√,/ , neither the local variable denitions bodies nor the
boolean arguments of the tests can contain division or square root. Therefore if we
apply P p to a tuple of expressions in EN , the result does not contain any divisions
or square roots.
  Lemma 6.2.1.           Program part restriction
                           ∀ e1 , ..., ek : EN =⇒ P p(e1 , ..., ek ) ∈ PN
Now we will see how we can decompose the expression part in order to remove
square roots and divisions from it.
6.3 Expression decompositions
Initially we will see how to decompose a single expression by assuming that the
body of the denition does not contain any test, thus the expression part is a list
of one element, then we will extend this denition to any list of expressions.
   6.3.1     Template of an expression.
                                     The idea for transforming a variable denition
with an expression is to transform this denition into several variable denitions
that correspond to the subexpressions that are free of square roots and divisions.
Therefore we need to introduce this decomposition of an expression as the applica-
tion of a function to square roots and divisions free expressions:
                            Template of expression
Given an expression e ∈ E , a template for e is a function t of E                                 such
  Definition 6.3.1.
                                                                                    k
                                                                                        −→EN√,/
that:
                                  N√,/                                              N


                               ∃ e1 , ..., ek : EN , e = t(e1 , ..., ek )
Journal of Formalized Reasoning Vol. 6, No. 1, 2013.
                                                 Square Root and Division Elimination                  ·       107




  The template and subexpression tuple of a unique expression can be computed
by giving the tuple of square roots and division free subexpressions.
  Example 6.3.1.
              √                                                             √
                                                                   x1 +x2  sq1
    a1 .a2 +b
    √           c
                √    = (f un (x1 , x2 , x3 , sq1 , sq21 ) →        √       √    )(a1 .a2 , b, d, c, e1     + e2 )
  d.    e1 +e2 + c                                            x3     sq21 + sq1

  We use special names for square roots because we want to avoid creating dierent
names for the same square root.
  Example 6.3.2.            Unique square root name
                          √                      let (x1 ,sq1 ) = (2, a) in
             let x = 2. a√in
                                −→               let (y1 ) = 5 in
             let y = 5 + a in P                                √                      √
                                                   P[x:=   x1 . sq1 ;       y:=   y1 + sq1 ]
Spotting the identical square roots is essential in order to preserve a reasonable size
for the produced code.
  6.3.2      Common template of expressions.   Given the denition of a template of
one expression, we will now extend this decomposition (template, square root and
division free sub expressions) to programs that contain tests. If the body contains
a test as √in Example 6.1, its            expression part
                                                  is a list of expressions ( [(a1 +                i.e.,
            d1.d2]). The objective is now to decompose these expressions using the

                i.e.,
a2)/b; c +
                         √
                      x0+ x2
same template (         x1 ), we call it the common template:
                       Common template of expressions A common template
of two expressions e and e is a function t that is a template of both e and e ,
  Definition 6.3.2.


that means t satises:
                            1         2                                                            1            2


                           ∃ se1 , se2 : EkN , e1 = t(se1 ) and e2 = t(se2 )
Existence:    Let x1 , ...xk be the local variables corresponding to e1 and x01 , ...x0k0
the one to e2 , then if we dene t as:
                     f un (s, x1 , ..., xk , x01 , ..., x0k0 ) → (s × e1 + (1 − s) × e2 )
  we have: t(1, x1 , ...xk , 0, ..., 0) = e1 ∧ t(0, 0, ..., 0, x01 , ...x0k0 ) = e2 , it is a common
template of e1 and e2 . This is only an example since we use a more compact form
in our transformation in order to limit the number of square roots produced by the
template but we will not describe the common template computation in this paper.
Thus the transformation of a variable denition with tests has the following form:
  Example 6.3.3.            Declaration with test
       let x =                                           let (x1 ,x2 ,x3 ,x4 ,sq1 ,sq2 ,sq3 ) =
         if F                                              if F
                                   √
           then a1 + a2 . b1 + b2 . b3        −→             then (a1 , a2 , 1, 0, b1 , b2 , b3 )
                         p

                    c1 √                                     else (c1 , 0, c2 , c3 , 0, 0, d1 )
           else c2 +c3 . d1
         in P                                              in P[x:= t(x1 ,x2 ,x3 ,x4 ,sq1 ,sq2 ,sq3 )]
                                                                    √           √
                                                         x +x .         sq +sq . sq
where t = f un (x1 , x2 , x3 , x4 , sq1 , sq2 , sq3 ) → 1 2x3 +x41.√sq23 3
                                                                           is the common tem-
                            √                 c1 √
plate of a1 + a2 . b1 + b2 . b3 and c +c . d .
                  p
                                          2    3     1
   The denition of a common template of two expressions extends naturally to
several expressions. Therefore we are able to build a common template for any list
of expressions in EN√,/ .
                                                     Journal of Formalized Reasoning Vol. 6, No. 1, 2013.
108     ·        Pierre Neron




6.4 Correctness
We can prove that this transformation is correct by using the following semanti-
cal equivalences (with some conditions on the variable names that enforce some
renaming).
  Lemma 6.4.1.          Semantics equivalences
            let x = let y =
             in P
                              e   in t(y)
                                            ←→
                                                  let y =   e   in
                                                  let x = t(y) in P
                                                                                       (lift-let)
            if F then t(e1 ) else t(e2 )    ←→    t(if F then    e1   else   e2 )      (lift-if)
            let x = e in p                  ←→    p[ x := e ]                          (inline)
These rules allow us to prove that the rule used to transform variable denitions
introduced in Denition 6.1.1 preserves the semantics. This transformation being
described, it completes the description of the transformation algorithm. The last
section presents some remarks about the eective implementation of this transfor-
mation.

7. PRACTICAL ASPECTS OF THE PROGRAM TRANSFORMATION
  Exact computation with                    .
                            +, −, × The air trac management system introduced
in [NMD10] computes with distances and other geometric quantities. Therefore it
has use of the square root and division operations. There is a fundamental dierence
between division and square roots on one side and the three other arithmetic oper-
ations that are addition multiplication and subtraction on the other side. Indeed,
let us now introduce the subset D of R. D is the set of dyadic rational numbers, the
rational numbers which denominator is a power of 2. Therefore every element of D
can be exactly represented using a nite sequence of bits and this set D is closed
under addition, multiplication and subtraction, whereas division and square roots
can not be precisely dened (1/5 has no nite binary representation) and will force
us to use round os.
   Computing in D with addition, multiplication and subtraction can be done ex-
actly by using a dynamic representation of real numbers which will allow us to use
all the bits we need to avoid losing accuracy during computation (       the producte.g.,
of two numbers of size n can be stored in a number of size 2.n). Certainly, this
kind of computation does not respect the constraint of embedded systems that re-
quires to know at compile time the memory the program will use at run time. But,
since our language does not contain loop or recursion, a simple static analysis can
give us the number of bits required by every computation depending the number
of bits of the inputs. Being able to compute exactly with addition, multiplication
and subtraction is the reason why we want to eliminate square root and division
operations.
  Experiments.  We have tested this transformation on several functions dened by
the NASA Langley Formal Method Team in their Airborne Coordinated Conict
Resolution and Detection (ACCoRD) framework. Since our language does not
support function denitions yet, we had to inline the calls by hand in the target
program. We tried our transformation on the cd3d program, which is an improved
Journal of Formalized Reasoning Vol. 6, No. 1, 2013.
                                      Square Root and Division Elimination         ·     109




version of the cd2d function dened in [MBMD09], this function contains only one
distinct square roots which is used many times along with several divisions. We
also tested the track_line function, dened in [NMD10], this function contains
two distinct and dependent square roots and also several divisions. On these two
functions we computed the transformation and therefore we can give the size of the
produced code but we also computed an estimation of the required memory size if
we want to compute on that produced code using exact computation with +, −, ×.
Assuming the inputs are represented on 64 bits, that gives the following results:
         Function       Input code      Output code         Required memory
         cd3d               2,3 KB            13 KB                   15 Kb
         trackline            1 KB            13 KB                   57 Kb
The size and the memory required by the output programs quickly growing with the
number of square roots and division, it is absolutely critical to keep that number as
low as possible during the transformation process in order to get reasonable sizes.

Conclusion
In this paper, we described a way to transform any program built with variable
denitions and tests into another semantically equivalent one where the control ow
never depends on the result of a square root or division, thus protecting this control
ow from rounding errors introduced by these operations. This transformation
allows proofs done on the abstract semantics to still hold on the concrete one. The
programs produced by this transformation also respects the constraints of embedded
code since they do not use any dynamic structures.
   The main issues of this transformation were not only to dene procedures that
remove divisions and square roots from nearly every part of the program but also to
keep the size of the produced code in an acceptable range. This is the reason why
we did not dene the computation of the template, since several complex algorithms
may be used to generate the most appropriate template in order to minimize the
size of the produced code. Nevertheless, validity of the proof only relies on the
correctness of the template used in this optimization. This work led us to dene
the problem of template generation that may be of general interest and will be
discussed in future work.
   Most of the program generic transformations such as the elimination of square
roots and divisions in expressions have already been formalized and proved in the
Pvs proof assistant. Both the Pvs development and the OCaml implementation
can be found on the web site of the author. The Pvs specication has also been
used to dene a Pvs strategy using computational reection as presented in [Ner13].
Future work includes extending this transformation to more complex languages
which contain structures such as function denitions and bounded loops and keep
reducing the size of the produced code by using static analysis techniques such
as using the information given by the tests values in the corresponding branches
during the transformation.
  Acknowledgement.  I would like to thank both my PhD. advisors Gilles Dowek
and Cesar Muñoz for this topic proposal and the helpful discussions and Catherine
Dubois, Cyril Cohen and the anonymous reviewers for their useful comments on

                                         Journal of Formalized Reasoning Vol. 6, No. 1, 2013.
110     ·      Pierre Neron




this paper. This work was supported by the Assurance of Flight Critical System's
project of NASA's Aviation Safety Program at Langley Research Center under
Research Cooperative Agreement No. NNL09AA00A awarded to the National In-
stitute of Aerospace.

References
[BCRO86] Hans-Juergen Boehm, Robert Cartwright, Mark Riggle, and Michael J.
         O'Donnell. Exact real arithmetic: a case study in higher order pro-
         gramming. In         Proceedings of the 1986 ACM conference on LISP and
               functional programming
                                 , LFP '86, pages 162173, New York, NY, USA,
         1986. ACM.
[BF07]   Sylvie Boldo and Jean-Christophe Filliâtre. Formal verication of
         oating-point programs. In Peter Kornerup and Jean-Michel Muller,
         editors,        Proceedings of the 18th IEEE Symposium on Computer Arith-
               metic
               , pages 187194, Montpellier, France, June 2007.
[BM06]   Sylvie Boldo and César Muñoz. A formalization of oating-point num-
         bers in PVS. Report NIA Report No. 2006-01, NASA/CR-2006-214298,
         NIA-NASA Langley, National Institute of Aerospace, Hampton, VA,
         2006.
[Bos03]  Alin Bostan.            Algorithmique ecace pour des opérations de base en
               Calcul formel
                       . Ph.d. thesis, Ecole polytechnique, 2003.
[CMC08] Liqian Chen, Antoine Miné, and Patrick Cousot. A sound oating-point
         polyhedra abstract domain. In G. Ramalingam, editor,      APLAS  , volume
         5356 of      Lecture Notes in Computer Science
                                                     , pages 318. Springer, 2008.
[Coh12]  Cyril Cohen. Construction of real algebraic numbers in Coq. In Lennart
         Beringer and Amy Felty, editors,       ITP - 3rd International Conference
               on Interactive Theorem Proving - 2012
                                                 , Princeton, États-Unis, August
         2012. Springer.
[Col76]  George E. Collins. Quantier elimination for real closed elds by cylin-
         drical algebraic decomposition: a synopsis.        SIGSAM Bull.
                                                                       , 10:1012,
         February 1976.
[DGL04]  Pietro Di Gianantonio and Pier Luca Lanzi. Lazy algorithms for exact
         real arithmetic.           Electron. Notes Theor. Comput. Sci.
                                                                   , 104:113128,
         November 2004.
[DMM05] Marc Daumas, Guillaume Melquiond, and César Muñoz. Guaranteed
         proofs using interval arithmetic. In          IEEE Symposium on Computer
               Arithmetic
                    , pages 188195, 2005.
[Har95]  John Harrison. Floating point verication in HOL. In Phillip J. Wind-
         ley, Thomas Schubert, and Jim Alves-Foss, editors,     Higher Order Logic
               Theorem Proving and Its Applications: Proceedings of the 8th Interna-
               tional Workshop, volume 971 of Lecture Notes in Computer Science,
               pages 186199, Aspen Grove, Utah, 1995. Springer.
[IEE85]        IEEE. IEEE standard for binary oating-point arithmetic. Institute of
               Electrical and Electronics Engineers, New York, 1985. Note: Standard
               7541985.
Journal of Formalized Reasoning Vol. 6, No. 1, 2013.
                                     Square Root and Division Elimination         ·     111




[KS11]   Robbert Krebbers and Bas Spitters. Type classes for ecient exact real
         arithmetic in Coq.     Logical Methods in Computer Science  , 9(1), 2011.
[Mar09]  Matthieu Martel. Program transformation for numerical precision. In
            PEPM , pages 101110, 2009.
[MBMD09] Jerey Maddalon, Ricky Butler, César Muñoz, and Gilles Dowek.
         Mathematical basis for the safety analysis of conict prevention al-
         gorithms. Technical Memorandum NASA/TM-2009-215768, NASA,
         Langley Research Center, Hampton VA 23681-2199, USA, June 2009.
[Min95]  Paul S. Miner. Dening the IEEE-854 oating-point standard in PVS,
         1995.
[Ner12]  Pierre Neron. A formal proof of square root and division elimination
         in embedded programs. In Chris Hawblitzel and Dale Miller, editors,
            CPP
              , volume 7679 of     Lecture Notes in Computer Science  , pages 256
         272. Springer, 2012.
[Ner13]  Pierre Neron. Square root and division elimination in PVS. In Sandrine
         Blazy, Christine Paulin-Mohring, and David Pichardie, editors,      Inter-
            active Theorem Proving  , volume 7998 of     Lecture Notes in Computer
            Science
                  , pages 457462. Springer, 2013.
[NMD10] Anthony Narkawicz, César Muñoz, and Gilles Dowek. Formal verica-
         tion of air trac prevention bands algorithms. Technical Memorandum
         NASA/TM-2010-216706, NASA, 2010.
[NMD12] Anthony Narkawicz, Céar Muñoz, and Gilles Dowek. Provably correct
         conict prevention bands algorithms.        Science of Computer Program-
            ming
              , 77(12):10391057, September 2012.
[O'C08]  Russell O'Connor. Certied exact transcendental real number com-
         putation in Coq. In OtmaneAit Mohamed, César César, Muñoz,
         and Soène Tahar, editors,    Theorem Proving in Higher Order Logics      ,
         volume 5170 of      Lecture Notes in Computer Science   , pages 246261.
         Springer Berlin Heidelberg, 2008.
[Sim98]  Alex K. Simpson. Lazy functional algorithms for exact real functionals.
         In Lubo² Brim, Jozef Gruska, and Ji°í Zlatu²ka, editors,Mathematical
            Foundations of Computer Science 1998                Lecture Notes
                                                   , volume 1450 of
            in Computer Science , pages 456464. Springer Berlin Heidelberg, 1998.
[Tar51]  Alfred Tarski.   A Decision Method for Elementary Algebra and Geom-
            etry
             . Univ. of California Press, 2nd edition, 1951.
[Vui87]  Jean Vuillemin. Exact real arithmetic with continued fractions. Rap-
         port de recherche RR-760, INRIA, 1987.
[Wei97]  Volker Weispfenning. Quantier elimination for real algebra - the
         quadratic case and beyond.       Appl. Algebra Eng. Commun. Comput.       ,
         8(2):85101, 1997.
[Wie80]  Edwin Wiedmer. Computing with Innite Objects.        Theoretical Com-
            puter Science
                        , 10:133155, 1980.




                                        Journal of Formalized Reasoning Vol. 6, No. 1, 2013.
