3 research outputs found

    Translating Clojure to ACL2 for Verification

    Get PDF
    Software spends a significant portion of its life-cycle in the maintenance phase and over 20\% of the maintenance effort is fixing defects. Formal methods, including verification, can reduce the number of defects in software and lower corrective maintenance, but their industrial adoption has been underwhelming. A significant barrier to adoption is the overhead of converting imperative programming languages, which are common in industry, into the declarative programming languages that are used by formal methods tools. In comparison, the verification of software written in declarative programming languages is much easier because the conversion into a formal methods tool is easier. The growing popularity of declarative programming --- evident from the rise of multi-paradigm languages such as Javascript, Ruby, and Scala --- affords us the opportunity to verify the correctness of software more easily. Clojure is a declarative language released in 2007 that compiles to bytecode that executes on the Java Virtual Machine (JVM). Despite being a newer, declarative programming language, several companies have already used it to develop commercial products. Clojure shares a Lisp syntax with ACL2, an interactive theorem prover that is used to verify the correctness of software. Since both languages are based on Lisp, code written in either Clojure or ACL2 is easily converted to the other. Therefore, Clojure can conceivably be verified by ACL2 with limited overhead assuming that the underlying behavior of Clojure code matches that of ACL2. ACL2 has been previously used to reason about Java programs through the use of formal models of the JVM. Since Clojure compiles to JVM bytecode, a similar approach is taken in this dissertation to verify the underlying implementation of Clojure. The research presented in this dissertation advances techniques to verify Clojure code in ACL2. Clojure and ACL2 are declarative, but they are specifically functional programming languages so the research focuses on two important concepts in functional programming and verification: arbitrary-precision numbers ("bignums") and lists. For bignums, the correctness of a model of addition is verified that addresses issues that arise from the unique representation of bignums in Clojure. Lists, in Clojure, are implemented as a type of sequence. This dissertation demonstrates an abstraction that equates Clojure sequences to ACL2 lists. In support of the research, an existing ACL2 model of the JVM is modified to address specific aspects of compiled Clojure code and the new model is used to verify the correctness of core Clojure functions with respect to corresponding ACL2 functions. The results support the ideas that ACL2 can be used to reason about Clojure code and that formal methods can be integrated more easily in industrial software development when the implementation corresponds semantically to the verification model

    Conception, optimisation, et vérification formelle de techniques de tolérance aux fautes pour circuits

    Get PDF
    Technology shrinking and voltage scaling increase the risk of fault occurrences in digital circuits. To address this challenge, engineers use fault-tolerance techniques to mask or, at least, to detect faults. These techniques are especially needed in safety critical domains (e.g., aerospace, medical, nuclear, etc.), where ensuring the circuit functionality and fault-tolerance is crucial. However, the verification of functional and fault-tolerance properties is a complex problem that cannot be solved with simulation-based methodologies due to the need to check a huge number of executions and fault occurrence scenarios. The optimization of the overheads imposed by fault-tolerance techniques also requires the proof that the circuit keeps its fault-tolerance properties after the optimization.In this work, we propose a verification-based optimization of existing fault-tolerance techniques as well as the design of new techniques and their formal verification using theorem proving. We first investigate how some majority voters can be removed from Triple-Modular Redundant (TMR) circuits without violating their fault-tolerance properties. The developed methodology clarifies how to take into account circuit native error-masking capabilities that may exist due to the structure of the combinational part or due to the way the circuit is used and communicates with the surrounding device.Second, we propose a family of time-redundant fault-tolerance techniques as automatic circuit transformations. They require less hardware resources than TMR alternatives and could be easily integrated in EDA tools. The transformations are based on the novel idea of dynamic time redundancy that allows the redundancy level to be changed "on-the-fly" without interrupting the computation. Therefore, time-redundancy can be used only in critical situations (e.g., above Earth poles where the radiation level is increased), during the processing of crucial data (e.g., the encryption of selected data), or during critical processes (e.g., a satellite computer reboot).Third, merging dynamic time redundancy with a micro-checkpointing mechanism, we have created a double-time redundancy transformation capable of masking transient faults. Our technique makes the recovery procedure transparent and the circuit input/output behavior remains unchanged even under faults. Due to the complexity of that method and the need to provide full assurance of its fault-tolerance capabilities, we have formally certified the technique using the Coq proof assistant. The developed proof methodology can be applied to certify other fault-tolerance techniques implemented through circuit transformations at the netlist level.La miniaturisation de la gravure et l'ajustement dynamique du voltage augmentent le risque de fautes dans les circuits intégrés. Pour pallier cet inconvénient, les ingénieurs utilisent des techniques de tolérance aux fautes pour masquer ou, au moins, détecter les fautes. Ces techniques sont particulièrement utilisées dans les domaines critiques (aérospatial, médical, nucléaire, etc.) où les garanties de bon fonctionnement des circuits et leurs tolérance aux fautes sont cruciales. Cependant, la vérification de propriétés fonctionnelles et de tolérance aux fautes est un problème complexe qui ne peut être résolu par simulation en raison du grand nombre d'exécutions possibles et de scénarios d'occurrence des fautes. De même, l'optimisation des surcoûts matériels ou temporels imposés par ces techniques demande de garantir que le circuit conserve ses propriétés de tolérance aux fautes après optimisation.Dans cette thèse, nous décrivons une optimisation de techniques de tolérance aux fautes classiques basée sur des analyses statiques, ainsi que de nouvelles techniques basées sur la redondance temporelle. Nous présentons comment leur correction peut être vérifiée formellement à l'aide d'un assistant de preuves.Nous étudions d'abord comment certains voteurs majoritaires peuvent être supprimés des circuits basés sur la redondance matérielle triple (TMR) sans violer leurs propriétés de tolérance. La méthodologie développée prend en compte les particularités des circuits (par ex. masquage logique d'erreurs) et des entrées/sorties pour optimiser la technique TMR.Deuxièmement, nous proposons une famille de techniques utilisant la redondance temporelle comme des transformations automatiques de circuits. Elles demandent moins de ressources matérielles que TMR et peuvent être facilement intégrés dans les outils de CAO. Les transformations sont basées sur une nouvelle idée de redondance temporelle dynamique qui permet de modifier le niveau de redondance «à la volée» sans interrompre le calcul. Le niveau de redondance peut être augmenté uniquement dans les situations critiques (par exemple, au-dessus des pôles où le niveau de rayonnement est élevé), lors du traitement de données cruciales (par exemple, le cryptage de données sensibles), ou pendant des processus critiques (par exemple, le redémarrage de l'ordinateur d'un satellite).Troisièmement, en associant la redondance temporelle dynamique avec un mécanisme de micro-points de reprise, nous proposons une transformation avec redondance temporelle double capable de masquer les fautes transitoires. La procédure de recouvrement est transparente et le comportement entrée/sortie du circuit reste identique même lors d'occurrences de fautes. En raison de la complexité de cette méthode, la garantie totale de sa correction a nécessité une certification formelle en utilisant l'assistant de preuves Coq. La méthodologie développée peut être appliquée pour certifier d'autres techniques de tolérance aux fautes exprimées comme des transformations de circuits

    Inductive representation, proofs and refinement of pointer structures

    Get PDF
    Cette thèse s'intègre dans le domaine général des méthodes formelles qui donnent une sémantique aux programmes pour vérifier formellement des propriétés sur ceux-ci. Sa motivation originale provient d'un besoin de certification des systèmes industriels souvent développés à l'aide de l'Ingénierie Dirigée par les Modèles (IDM) et de langages orientés objets (OO). Pour transformer efficacement des modèles (ou graphes), il est avantageux de les représenter à l'aide de structures de pointeurs, économisant le temps et la mémoire grâce au partage qu'ils permettent. Cependant la vérification de propriétés sur des programmes manipulant des pointeurs est encore complexe. Pour la simplifier, nous proposons de démarrer le développement par une implémentation haut-niveau sous la forme de programmes fonctionnels sur des types de données inductifs facilement vérifiables dans des assistants à la preuve tels que Isabelle/HOL. La représentation des structures de pointeurs est faite à l'aide d'un arbre couvrant contenant des références additionnelles. Ces programmes fonctionnels sont ensuite raffinés si nécessaire vers des programmes impératifs à l'aide de la bibliothèque Imperative_HOL. Ces programmes sont en dernier lieu extraits vers du code Scala (OO). Cette thèse décrit la méthodologie de représentation et de raffinement et fournit des outils pour la manipulation et la preuve de programmes OO dans Isabelle/HOL. L'approche est éprouvée par de nombreux exemples dont notamment l'algorithme de Schorr-Waite et la construction de Diagrammes de Décision Binaires (BDDs).This thesis stands in the general domain of formal methods that gives semantics to programs to formally prove properties about them. It originally draws its motivation from the need for certification of systems in an industrial context where Model Driven Engineering (MDE) and object-oriented (OO) languages are common. In order to obtain efficient transformations on models (graphs), we can represent them as pointer structures, allowing space and time savings through the sharing of nodes. However verification of properties on programs manipulating pointer structures is still hard. To ease this task, we propose to start the development with a high-level implementation embodied by functional programs manipulating inductive data-structures, that are easily verified in proof assistants such as Isabelle/HOL. Pointer structures are represented by a spanning tree adorned with additional references. These functional programs are then refined - if necessary - to imperative programs thanks to the library Imperative_HOL. These programs are finally extracted to Scala code (OO). This thesis describes this kind of representation and refinement and provides tools to manipulate and prove OO programs in Isabelle/HOL. This approach is put in practice with several examples, and especially with the Schorr-Waite algorithm and the construction of Binary Decision Diagrams (BDDs)
    corecore