Skip to content
Snippets Groups Projects
Commit b1f8150d authored by Julien Signoles's avatar Julien Signoles
Browse files

[e-acsl] update headers

[e-acsl] universal quantifiers over integers. Not yet finished: work only in some cases
[e-acsl] logic variables (required by univ quantif)
parent f73cc8dd
No related branches found
No related tags found
No related merge requests found
Showing
with 385 additions and 72 deletions
(**************************************************************************) (**************************************************************************)
(* *) (* *)
(* This file is part of Frama-C. *) (* This file is part of the E-ACSL plug-in of Frama-C. *)
(* *) (* *)
(* Copyright (C) 2007-2010 *) (* Copyright (C) 2011 *)
(* CEA (Commissariat à l'Énergie Atomique) *) (* CEA (Commissariat à l'énergie atomique et aux énergies *)
(* alternatives) *)
(* *) (* *)
(* you can redistribute it and/or modify it under the terms of the GNU *) (* you can redistribute it and/or modify it under the terms of the GNU *)
(* Lesser General Public License as published by the Free Software *) (* Lesser General Public License as published by the Free Software *)
......
########################################################################## ##########################################################################
# # # #
# This file is part of Frama-C. # # This file is part of the E-ACSL plug-in of Frama-C. #
# # # #
# Copyright (C) 2007-2010 # # Copyright (C) 2011 #
# CEA (Commissariat l'nergie Atomique) # # CEA (Commissariat l'nergie atomique et aux nergies #
# alternatives) #
# # # #
# you can redistribute it and/or modify it under the terms of the GNU # # you can redistribute it and/or modify it under the terms of the GNU #
# Lesser General Public License as published by the Free Software # # Lesser General Public License as published by the Free Software #
...@@ -89,6 +90,17 @@ uninstall:: ...@@ -89,6 +90,17 @@ uninstall::
$(PRINT_RM) E-ACSL share files $(PRINT_RM) E-ACSL share files
$(RM) -r $(FRAMAC_SHARE)/e-acsl $(RM) -r $(FRAMAC_SHARE)/e-acsl
##########
# Header #
##########
headers::
@echo "Applying Headers..."
headache -c license/headache_config.txt -h license/CEA_LGPL \
*.ml *.mli \
Makefile.in configure.ac \
share/e-acsl/*.h
################ ################
# Generic part # # Generic part #
################ ################
......
à traiter avant la 1ère release: ################
- quantifications sans exentension de syntaxe # NEXT RELEASE #
################
- quantifications sur les entiers
- mixed assumes and ensures in contracts
- pas d'arrêt brutal en cas de feature non implémentée
- utiliser Options.use_asserts
######## ########
# CODE # # CODE #
######## ########
- mixed assumes and ensures - Env.new_var*: ajouter la varinfo en sortie de la fonction ?
- function contracts for functions only declared - function contracts for functions only declared
==> le noyau génère un "assigns \nothing" pour ces fonctions... ==> le noyau génère un "assigns \nothing" pour ces fonctions...
ce assign n'est de toute façon pas gérer ce assign n'est de toute façon pas gérer
- multi ensures or multi requirements, their conjunctions and undefinedness - multi ensures or multi requirements, their conjunctions and undefinedness
- utiliser Options.use_asserts [JS 2011/12/06] c'est quoi çà ? :-(
- gestion des initialiseurs des globals: requiert un main - gestion des initialiseurs des globals: requiert un main
- mkcall ne devrait pas générer de nouvelles variables pour une même fonction - mkcall ne devrait pas générer de nouvelles variables pour une même fonction
- garde pour les casts quand overflows potentiels - garde pour les casts quand overflows potentiels
(même pas de warnings aujourd'hui) (même pas de warnings aujourd'hui)
- minimiser le nombre de variables générées
- constante entière longue: utiliser la représentation sous forme de string et - constante entière longue: utiliser la représentation sous forme de string et
rechercher la base appropriée. rechercher la base appropriée.
- arithmetic overflows - arithmetic overflows
...@@ -38,11 +43,17 @@ ...@@ -38,11 +43,17 @@
- utiliser Rte (get_rte_annotations dans Oxygen) - utiliser Rte (get_rte_annotations dans Oxygen)
- [Yannick] Logic functions - [Yannick] Logic functions
- type system for generating C int/float when possible - type system for generating C int/float when possible
(generalisation of current Visit.principal_type) (generalisation of current Visit.principal_type,
nouvelle unité de compilation Typing)
- vérifier le code de la division et du modulo
(div et modulo mathématiques différents des div et modulo de l'ANSI C99)
- customization des noms de variable générés
(par ex pour indiquer le nom de la variable d'origine, ou son rôle)
############## ##############
# KNOWN BUGS # # KNOWN BUGS #
############## ##############
- \at incorrect si StmtLabel faisant référence au stmt courant (voir test at.i) - \at incorrect si StmtLabel faisant référence au stmt courant (voir test at.i)
- incorrect d'utiliser un \old dans le post-state si pre-state == post-state - incorrect d'utiliser un \old dans le post-state si pre-state == post-state
...@@ -56,18 +67,11 @@ ...@@ -56,18 +67,11 @@
- test sizeof.i devraient être plus précis quand logic_typing plus précis - test sizeof.i devraient être plus précis quand logic_typing plus précis
- structs - structs
- unions - unions
- quantifications entières invalides
#################### ####################
# AVANT LA DISTRIB # # AVANT LA DISTRIB #
#################### ####################
- documentation - user manual
- e-acsl implementation manual
en lien avec bts #743:
- make distrib - make distrib
- headers (copyright 2011)
- license
- install répertoire share
VOIR CPAN
########################################################################## ##########################################################################
# # # #
# This file is part of Frama-C. # # This file is part of the E-ACSL plug-in of Frama-C. #
# # # #
# Copyright (C) 2007-2010 # # Copyright (C) 2011 #
# CEA (Commissariat l'nergie Atomique) # # CEA (Commissariat l'nergie atomique et aux nergies #
# alternatives) #
# # # #
# you can redistribute it and/or modify it under the terms of the GNU # # you can redistribute it and/or modify it under the terms of the GNU #
# Lesser General Public License as published by the Free Software # # Lesser General Public License as published by the Free Software #
......
(**************************************************************************) (**************************************************************************)
(* *) (* *)
(* This file is part of Frama-C. *) (* This file is part of the E-ACSL plug-in of Frama-C. *)
(* *) (* *)
(* Copyright (C) 2007-2010 *) (* Copyright (C) 2011 *)
(* CEA (Commissariat l'nergie Atomique) *) (* CEA (Commissariat l'nergie atomique et aux nergies *)
(* alternatives) *)
(* *) (* *)
(* you can redistribute it and/or modify it under the terms of the GNU *) (* you can redistribute it and/or modify it under the terms of the GNU *)
(* Lesser General Public License as published by the Free Software *) (* Lesser General Public License as published by the Free Software *)
...@@ -43,10 +44,10 @@ type local_env = { block_info: block_info; mpz_tbl: mpz_tbl } ...@@ -43,10 +44,10 @@ type local_env = { block_info: block_info; mpz_tbl: mpz_tbl }
type t = type t =
{ visitor: Visitor.frama_c_visitor; { visitor: Visitor.frama_c_visitor;
new_global_vars: varinfo list; (* generated variables at function new_global_vars: varinfo list; (* generated variables at function level *)
level *)
global_mpz_tbl: mpz_tbl; global_mpz_tbl: mpz_tbl;
env_stack: local_env list; env_stack: local_env list;
var_mapping: Varinfo.t Logic_var.Map.t; (* bind logic var to C var *)
cpt: int; (* counter used when generating variables *) } cpt: int; (* counter used when generating variables *) }
let empty_block = let empty_block =
...@@ -66,6 +67,7 @@ let dummy = ...@@ -66,6 +67,7 @@ let dummy =
new_global_vars = []; new_global_vars = [];
global_mpz_tbl = empty_mpz_tbl; global_mpz_tbl = empty_mpz_tbl;
env_stack = []; env_stack = [];
var_mapping = Logic_var.Map.empty;
cpt = 0 } cpt = 0 }
let empty v = let empty v =
...@@ -73,6 +75,7 @@ let empty v = ...@@ -73,6 +75,7 @@ let empty v =
new_global_vars = []; new_global_vars = [];
global_mpz_tbl = empty_mpz_tbl; global_mpz_tbl = empty_mpz_tbl;
env_stack = []; env_stack = [];
var_mapping = Logic_var.Map.empty;
cpt = 0 } cpt = 0 }
let top env = match env.env_stack with [] -> assert false | hd :: tl -> hd, tl let top env = match env.env_stack with [] -> assert false | hd :: tl -> hd, tl
...@@ -164,6 +167,32 @@ let new_var ?(global=false) env t ty mk_stmts = ...@@ -164,6 +167,32 @@ let new_var ?(global=false) env t ty mk_stmts =
let new_var_and_mpz_init ?global env t mk_stmts = let new_var_and_mpz_init ?global env t mk_stmts =
new_var ?global env t Mpz.t (fun v e -> Mpz.init e :: mk_stmts v e) new_var ?global env t Mpz.t (fun v e -> Mpz.init e :: mk_stmts v e)
module Logic_binding = struct
let add env logic_v =
let v_ref = ref Varinfo.dummy in
let mk v _ = v_ref := v; [] in
let ty =
(* TODO: yet incorrect. Waiting for the type system... *)
match logic_v.lv_type with
| Ctype ty -> ty
| Linteger -> Mpz.t
| Ltype _ | Lvar _ | Lreal | Larrow _ -> assert false
in
let _, env = new_var env None ty mk in
{ env with var_mapping = Logic_var.Map.add logic_v !v_ref env.var_mapping }
let get env logic_v =
try Logic_var.Map.find logic_v env.var_mapping
with Not_found -> assert false
let remove env v =
let map = env.var_mapping in
assert (Logic_var.Map.mem v map);
{ env with var_mapping = Logic_var.Map.remove v map }
end
let current_kf env = let current_kf env =
let v = env.visitor in let v = env.visitor in
match v#current_kf with match v#current_kf with
......
(**************************************************************************) (**************************************************************************)
(* *) (* *)
(* This file is part of Frama-C. *) (* This file is part of the E-ACSL plug-in of Frama-C. *)
(* *) (* *)
(* Copyright (C) 2007-2010 *) (* Copyright (C) 2011 *)
(* CEA (Commissariat à l'Énergie Atomique) *) (* CEA (Commissariat à l'énergie atomique et aux énergies *)
(* alternatives) *)
(* *) (* *)
(* you can redistribute it and/or modify it under the terms of the GNU *) (* you can redistribute it and/or modify it under the terms of the GNU *)
(* Lesser General Public License as published by the Free Software *) (* Lesser General Public License as published by the Free Software *)
...@@ -52,6 +53,12 @@ val new_var_and_mpz_init: ...@@ -52,6 +53,12 @@ val new_var_and_mpz_init:
(** Same as [new_var], but dedicated to mpz_t variables initialized by (** Same as [new_var], but dedicated to mpz_t variables initialized by
{!Mpz.init}. *) {!Mpz.init}. *)
module Logic_binding: sig
val add: t -> logic_var -> t
val get: t -> logic_var -> varinfo
val remove: t -> logic_var -> t
end
val add_assert: t -> stmt -> predicate named -> unit val add_assert: t -> stmt -> predicate named -> unit
(** [add_assert kf s p] extends the global environment with an assertion [p] (** [add_assert kf s p] extends the global environment with an assertion [p]
associated to the statement [s] in function [kf]. *) associated to the statement [s] in function [kf]. *)
...@@ -70,14 +77,14 @@ val push: t -> t ...@@ -70,14 +77,14 @@ val push: t -> t
type where = Before | Middle | After type where = Before | Middle | After
val pop_and_get: t -> stmt -> global_clear:bool -> where -> block * t val pop_and_get: t -> stmt -> global_clear:bool -> where -> block * t
(* Pop the last local context and get back the corresponding new block (** Pop the last local context and get back the corresponding new block
containing the given [stmt] at the given place ([Before] is before the containing the given [stmt] at the given place ([Before] is before the
code corresponding to annotations, [After] is after this code and [Middle] is code corresponding to annotations, [After] is after this code and [Middle] is
between the stmt corresponding to annotations and the ones for freeing the between the stmt corresponding to annotations and the ones for freeing the
memory. *) memory. *)
val pop: t -> t val pop: t -> t
(* Pop the last local context (ignore the corresponding new block if any *) (** Pop the last local context (ignore the corresponding new block if any *)
val get_generated_variables: t -> varinfo list val get_generated_variables: t -> varinfo list
(** All the new variables local to the visited function. *) (** All the new variables local to the visited function. *)
......
(**************************************************************************) (**************************************************************************)
(* *) (* *)
(* This file is part of Frama-C. *) (* This file is part of the E-ACSL plug-in of Frama-C. *)
(* *) (* *)
(* Copyright (C) 2007-2010 *) (* Copyright (C) 2011 *)
(* CEA (Commissariat à l'Énergie Atomique) *) (* CEA (Commissariat à l'énergie atomique et aux énergies *)
(* alternatives) *)
(* *) (* *)
(* you can redistribute it and/or modify it under the terms of the GNU *) (* you can redistribute it and/or modify it under the terms of the GNU *)
(* Lesser General Public License as published by the Free Software *) (* Lesser General Public License as published by the Free Software *)
......
(**************************************************************************) (**************************************************************************)
(* *) (* *)
(* This file is part of Frama-C. *) (* This file is part of the E-ACSL plug-in of Frama-C. *)
(* *) (* *)
(* Copyright (C) 2007-2010 *) (* Copyright (C) 2011 *)
(* CEA (Commissariat l'nergie Atomique) *) (* CEA (Commissariat l'nergie atomique et aux nergies *)
(* alternatives) *)
(* *) (* *)
(* you can redistribute it and/or modify it under the terms of the GNU *) (* you can redistribute it and/or modify it under the terms of the GNU *)
(* Lesser General Public License as published by the Free Software *) (* Lesser General Public License as published by the Free Software *)
......
(**************************************************************************) (**************************************************************************)
(* *) (* *)
(* This file is part of Frama-C. *) (* This file is part of the E-ACSL plug-in of Frama-C. *)
(* *) (* *)
(* Copyright (C) 2007-2010 *) (* Copyright (C) 2011 *)
(* CEA (Commissariat l'nergie Atomique) *) (* CEA (Commissariat l'nergie atomique et aux nergies *)
(* alternatives) *)
(* *) (* *)
(* you can redistribute it and/or modify it under the terms of the GNU *) (* you can redistribute it and/or modify it under the terms of the GNU *)
(* Lesser General Public License as published by the Free Software *) (* Lesser General Public License as published by the Free Software *)
......
(**************************************************************************) (**************************************************************************)
(* *) (* *)
(* This file is part of Frama-C. *) (* This file is part of the E-ACSL plug-in of Frama-C. *)
(* *) (* *)
(* Copyright (C) 2007-2010 *) (* Copyright (C) 2011 *)
(* CEA (Commissariat à l'Énergie Atomique) *) (* CEA (Commissariat à l'énergie atomique et aux énergies *)
(* alternatives) *)
(* *) (* *)
(* you can redistribute it and/or modify it under the terms of the GNU *) (* you can redistribute it and/or modify it under the terms of the GNU *)
(* Lesser General Public License as published by the Free Software *) (* Lesser General Public License as published by the Free Software *)
......
(**************************************************************************) (**************************************************************************)
(* *) (* *)
(* This file is part of Frama-C. *) (* This file is part of the E-ACSL plug-in of Frama-C. *)
(* *) (* *)
(* Copyright (C) 2007-2010 *) (* Copyright (C) 2011 *)
(* CEA (Commissariat l'nergie Atomique) *) (* CEA (Commissariat l'nergie atomique et aux nergies *)
(* alternatives) *)
(* *) (* *)
(* you can redistribute it and/or modify it under the terms of the GNU *) (* you can redistribute it and/or modify it under the terms of the GNU *)
(* Lesser General Public License as published by the Free Software *) (* Lesser General Public License as published by the Free Software *)
......
(**************************************************************************) (**************************************************************************)
(* *) (* *)
(* This file is part of Frama-C. *) (* This file is part of the E-ACSL plug-in of Frama-C. *)
(* *) (* *)
(* Copyright (C) 2007-2010 *) (* Copyright (C) 2011 *)
(* CEA (Commissariat l'nergie Atomique) *) (* CEA (Commissariat à l'énergie atomique et aux énergies *)
(* alternatives) *)
(* *) (* *)
(* you can redistribute it and/or modify it under the terms of the GNU *) (* you can redistribute it and/or modify it under the terms of the GNU *)
(* Lesser General Public License as published by the Free Software *) (* Lesser General Public License as published by the Free Software *)
......
(**************************************************************************) (**************************************************************************)
(* *) (* *)
(* This file is part of Frama-C. *) (* This file is part of the E-ACSL plug-in of Frama-C. *)
(* *) (* *)
(* Copyright (C) 2007-2010 *) (* Copyright (C) 2011 *)
(* CEA (Commissariat l'nergie Atomique) *) (* CEA (Commissariat l'nergie atomique et aux nergies *)
(* alternatives) *)
(* *) (* *)
(* you can redistribute it and/or modify it under the terms of the GNU *) (* you can redistribute it and/or modify it under the terms of the GNU *)
(* Lesser General Public License as published by the Free Software *) (* Lesser General Public License as published by the Free Software *)
......
(**************************************************************************) (**************************************************************************)
(* *) (* *)
(* This file is part of Frama-C. *) (* This file is part of the E-ACSL plug-in of Frama-C. *)
(* *) (* *)
(* Copyright (C) 2007-2010 *) (* Copyright (C) 2011 *)
(* CEA (Commissariat à l'Énergie Atomique) *) (* CEA (Commissariat à l'énergie atomique et aux énergies *)
(* alternatives) *)
(* *) (* *)
(* you can redistribute it and/or modify it under the terms of the GNU *) (* you can redistribute it and/or modify it under the terms of the GNU *)
(* Lesser General Public License as published by the Free Software *) (* Lesser General Public License as published by the Free Software *)
......
(**************************************************************************) (**************************************************************************)
(* *) (* *)
(* This file is part of Frama-C. *) (* This file is part of the E-ACSL plug-in of Frama-C. *)
(* *) (* *)
(* Copyright (C) 2007-2010 *) (* Copyright (C) 2011 *)
(* CEA (Commissariat l'nergie Atomique) *) (* CEA (Commissariat à l'énergie atomique et aux énergies *)
(* alternatives) *)
(* *) (* *)
(* you can redistribute it and/or modify it under the terms of the GNU *) (* you can redistribute it and/or modify it under the terms of the GNU *)
(* Lesser General Public License as published by the Free Software *) (* Lesser General Public License as published by the Free Software *)
......
(**************************************************************************) (**************************************************************************)
(* *) (* *)
(* This file is part of Frama-C. *) (* This file is part of the E-ACSL plug-in of Frama-C. *)
(* *) (* *)
(* Copyright (C) 2007-2010 *) (* Copyright (C) 2011 *)
(* CEA (Commissariat à l'Énergie Atomique) *) (* CEA (Commissariat à l'énergie atomique et aux énergies *)
(* alternatives) *)
(* *) (* *)
(* you can redistribute it and/or modify it under the terms of the GNU *) (* you can redistribute it and/or modify it under the terms of the GNU *)
(* Lesser General Public License as published by the Free Software *) (* Lesser General Public License as published by the Free Software *)
......
/**************************************************************************/
/* */
/* This file is part of the E-ACSL plug-in of Frama-C. */
/* */
/* Copyright (C) 2011 */
/* CEA (Commissariat l'nergie atomique et aux nergies */
/* alternatives) */
/* */
/* you can redistribute it and/or modify it under the terms of the GNU */
/* Lesser General Public License as published by the Free Software */
/* Foundation, version 2.1. */
/* */
/* It is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU Lesser General Public License for more details. */
/* */
/* See the GNU Lesser General Public License version 2.1 */
/* for more details (enclosed in the file licenses/LGPLv2.1). */
/* */
/**************************************************************************/
// TODO: remplacer par un e_acsl.h.in // TODO: remplacer par un e_acsl.h.in
// faire gnrer par le makefile un e_acsl.h // faire gnrer par le makefile un e_acsl.h
// avec des #include "FRAMAC_SHARE/libc/stdio.h", etc // avec des #include "FRAMAC_SHARE/libc/stdio.h", etc
......
/**************************************************************************/
/* */
/* This file is part of the E-ACSL plug-in of Frama-C. */
/* */
/* Copyright (C) 2011 */
/* CEA (Commissariat l'nergie atomique et aux nergies */
/* alternatives) */
/* */
/* you can redistribute it and/or modify it under the terms of the GNU */
/* Lesser General Public License as published by the Free Software */
/* Foundation, version 2.1. */
/* */
/* It is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU Lesser General Public License for more details. */
/* */
/* See the GNU Lesser General Public License version 2.1 */
/* for more details (enclosed in the file licenses/LGPLv2.1). */
/* */
/**************************************************************************/
/*****************/ /*****************/
/* GMP functions */ /* GMP functions */
......
/**************************************************************************/
/* */
/* This file is part of the E-ACSL plug-in of Frama-C. */
/* */
/* Copyright (C) 2011 */
/* CEA (Commissariat à l'énergie atomique et aux énergies */
/* alternatives) */
/* */
/* you can redistribute it and/or modify it under the terms of the GNU */
/* Lesser General Public License as published by the Free Software */
/* Foundation, version 2.1. */
/* */
/* It is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU Lesser General Public License for more details. */
/* */
/* See the GNU Lesser General Public License version 2.1 */
/* for more details (enclosed in the file licenses/LGPLv2.1). */
/* */
/**************************************************************************/
/*************/ /*************/
/* GMP types */ /* GMP types */
......
(**************************************************************************) (**************************************************************************)
(* *) (* *)
(* This file is part of Frama-C. *) (* This file is part of the E-ACSL plug-in of Frama-C. *)
(* *) (* *)
(* Copyright (C) 2007-2010 *) (* Copyright (C) 2011 *)
(* CEA (Commissariat l'nergie Atomique) *) (* CEA (Commissariat l'nergie atomique et aux nergies *)
(* alternatives) *)
(* *) (* *)
(* you can redistribute it and/or modify it under the terms of the GNU *) (* you can redistribute it and/or modify it under the terms of the GNU *)
(* Lesser General Public License as published by the Free Software *) (* Lesser General Public License as published by the Free Software *)
...@@ -138,6 +139,72 @@ let is_representable _n k _s = match k with ...@@ -138,6 +139,72 @@ let is_representable _n k _s = match k with
| ILongLong | IULongLong -> | ILongLong | IULongLong ->
false false
let compute_quantif_guards quantif bounded_vars hyps =
let error msg pp x =
let msg1 = Pretty_utils.sfprintf msg pp x in
let msg2 =
Pretty_utils.sfprintf " in guarded quantification %a"
d_predicate_named quantif
in
Misc.type_error (msg1 ^ msg2)
in
let vars =
let h = Logic_var.Hashtbl.create 7 in
List.iter
(fun v ->
(* only allow quantification over integers *)
(match v.lv_type with
| Ctype ty when isIntegralType ty -> ()
| Linteger -> ()
| Ctype _ | Ltype _ | Lvar _ | Lreal | Larrow _ ->
error "non integer variable %a" d_logic_var v);
Logic_var.Hashtbl.add h v ())
bounded_vars;
h
in
let used_vars = Logic_var.Hashtbl.create 7 in
let get_guards p =
let rec aux acc p = match p.content with
| Pand({ content = Prel((Rlt | Rle) as r1, t11, t12) },
{ content = Prel((Rlt | Rle) as r2, t21, t22) }) ->
(match t12.term_node, t21.term_node with
| TLval(TVar x1, TNoOffset), TLval(TVar x2, TNoOffset) ->
if Logic_var.equal x1 x2 then
if Logic_var.Hashtbl.mem vars x1 then begin
Logic_var.Hashtbl.replace used_vars x1 ();
(t11, r1, x1, r2, t22) :: acc
end else
error "unbound variable %a" d_logic_var x1
else
error "invalid guard %a" d_term t21
| TLval _, _ -> error "invalid guard %a" d_term t21
| _, _ -> error "invalid guard %a" d_term t12)
| Pand(p1, p2) -> aux (aux acc p2) p1
| _ -> error "invalid guard %a" d_predicate_named p
in
aux [] p
in
let guards = get_guards hyps in
(* check that all quantifiers are guarded *)
Logic_var.Hashtbl.iter
(fun v () -> Logic_var.Hashtbl.remove vars v)
used_vars;
let len = Logic_var.Hashtbl.length vars in
if len > 0 then begin
let msg =
Pretty_utils.sfprintf
"unguarded variable%s %tin quantification %a"
(if len = 1 then "" else "s")
(fun fmt ->
Logic_var.Hashtbl.iter
(fun v () -> Format.fprintf fmt "%a " d_logic_var v)
vars)
d_predicate_named quantif
in
Misc.type_error msg
end;
guards
let constant_to_exp ?(loc=Location.unknown) = function let constant_to_exp ?(loc=Location.unknown) = function
| CInt64(n, k, s) -> | CInt64(n, k, s) ->
if is_representable n k s then kinteger64_repr ?loc k n s, false if is_representable n k s then kinteger64_repr ?loc k n s, false
...@@ -147,7 +214,8 @@ let constant_to_exp ?(loc=Location.unknown) = function ...@@ -147,7 +214,8 @@ let constant_to_exp ?(loc=Location.unknown) = function
let rec thost_to_host env = function let rec thost_to_host env = function
| TVar { lv_origin = Some v } -> Var v, env | TVar { lv_origin = Some v } -> Var v, env
| TVar { lv_origin = None } -> Misc.not_yet "logic variable" | TVar ({ lv_origin = None } as logic_v) ->
Var (Env.Logic_binding.get env logic_v), env
| TResult _typ -> | TResult _typ ->
let vis = Env.get_visitor env in let vis = Env.get_visitor env in
let kf = Extlib.the vis#current_kf in let kf = Extlib.the vis#current_kf in
...@@ -441,11 +509,11 @@ let rec named_predicate_to_exp env p = ...@@ -441,11 +509,11 @@ let rec named_predicate_to_exp env p =
(fun v _ -> (fun v _ ->
let lv = var v in let lv = var v in
let then_block, _ = let then_block, _ =
let s = mkStmt ~valid_sid:true (Instr (Set(lv, e2, loc))) in let s = mkStmtOneInstr ~valid_sid:true (Set(lv, e2, loc)) in
Env.pop_and_get env2 s ~global_clear:false Env.Middle Env.pop_and_get env2 s ~global_clear:false Env.Middle
in in
let else_block = let else_block =
mkBlock [ mkStmt ~valid_sid:true (Instr (Set(lv, zero loc, loc))) ] mkBlock [ mkStmtOneInstr ~valid_sid:true (Set(lv, zero loc, loc)) ]
in in
[ mkStmt ~valid_sid:true (If(e1, then_block, else_block, loc)) ]) [ mkStmt ~valid_sid:true (If(e1, then_block, else_block, loc)) ])
| Por(p1, p2) -> | Por(p1, p2) ->
...@@ -476,8 +544,125 @@ let rec named_predicate_to_exp env p = ...@@ -476,8 +544,125 @@ let rec named_predicate_to_exp env p =
new_exp ~loc (UnOp(LNot, e, TInt(IInt, []))), env new_exp ~loc (UnOp(LNot, e, TInt(IInt, []))), env
| Pif _ -> Misc.not_yet "_ ? _ : _" | Pif _ -> Misc.not_yet "_ ? _ : _"
| Plet _ -> Misc.not_yet "let _ = _ in _" | Plet _ -> Misc.not_yet "let _ = _ in _"
| Pforall _ -> Misc.not_yet "\\forall" | Pforall(bounded_vars, { content = Pimplies(hyps, goal) }) ->
| Pexists _ -> Misc.not_yet "\\exists" (* universal quantification over integers (or a subtype of integer) *)
let guards = compute_quantif_guards p bounded_vars hyps in
let env = List.fold_left Env.Logic_binding.add env bounded_vars in
let var_res = ref Varinfo.dummy in
let res, env =
(* variable storing the result of the \forall *)
Env.new_var env None intType
(fun v _ ->
var_res := v;
let lv = var v in
[ mkStmtOneInstr ~valid_sid:true (Set(lv, one ~loc, loc)) ])
in
let end_loop_ref = ref dummyStmt in
let rec mk_for_loop env = function
| [] ->
(* innermost loop body: store the result in [res] and go out according
to evaluation of the goal *)
let test, env = named_predicate_to_exp (Env.push env) goal in
let then_block = mkBlock [ mkEmptyStmt ~loc () ] in
let else_block =
mkBlock
[ mkStmtOneInstr
~valid_sid:true (Set(var !var_res, zero ~loc, loc));
mkStmt ~valid_sid:true (Goto(end_loop_ref, loc)) ]
in
let blk, env =
Env.pop_and_get
env
(mkStmt ~valid_sid:true (If(test, then_block, else_block, loc)))
~global_clear:false
Env.After
in
(* TODO: could be optimised if [pop_and_get] would return a list of
stmts *)
[ mkStmt ~valid_sid:true (Block blk) ], env
| (t1, rel1, logic_x, rel2, t2) :: tl ->
let body, env = mk_for_loop env tl in
let t_plus_one t =
Logic_const.term ~loc
(TBinOp(PlusA, t, Logic_const.tinteger ~loc ~ikind:IChar 1))
Linteger
in
let t1 = match rel1 with
| Rlt -> t_plus_one t1
| Rle -> t1
| Rgt | Rge | Req | Rneq -> assert false
in
let t2, t2', bop2 = match rel2 with
| Rlt -> t2, (*t_plus_one*) (* TODO: again, after implementing case
Linteger *) t2, Lt
| Rle -> let t2' = t_plus_one t2 in t2', t2', Le
| Rgt | Rge | Req | Rneq -> assert false
in
let ty = principal_type_from_term t1 t2' in
let e1, env = term_to_exp (Env.push env) ty t1 in
let e2, env = term_to_exp env ty t2 in
let var_x = Env.Logic_binding.get env logic_x in
let x = Misc.new_lval var_x in
let lv_x = var var_x in
(* we increment the loop counter one more time than the value of [t2]
if the relation is [<=]. Thus to prevent overflow, check the type
of [t2 + 1] instead of [t2] *)
match ty with
| Ctype _cty ->
(* loop counter corresponding to the quantified variable *)
let init_blk, env =
Env.pop_and_get
env
(mkStmtOneInstr ~valid_sid:true (Set(lv_x, e1, loc)))
~global_clear:false
Env.Middle
in
let guard = mkBinOp ~loc bop2 x e2 in
let tlv = Logic_const.tvar ~loc (cvar_to_lvar var_x) in
(* [ty] is ok wrt the risk of overflow when computing [x+1]. See
above comment. *)
let incr, env =
term_to_exp (Env.push env) ty (t_plus_one tlv)
in
let next_blk, env =
Env.pop_and_get
env
(mkStmtOneInstr ~valid_sid:true (Set(lv_x, incr, loc)))
~global_clear:false
Env.Middle
in
let stmts_block b = [ mkStmt ~valid_sid:true (Block b) ] in
let start = stmts_block init_blk in
let next = stmts_block next_blk in
mkFor ~start ~guard ~next ~body, env
| Linteger ->
(* TODO: similar translation than the case [Ctype _], but using GMP
operations instead of arithmetic ones. *)
assert false
| Ltype _ | Lvar _ | Lreal | Larrow _ -> assert false
in
let stmts, env = mk_for_loop env guards in
let env =
Env.add_stmt env (mkStmt ~valid_sid:true (Block (mkBlock stmts)))
in
let end_loop = mkEmptyStmt ~loc () in
let label = Label("e_acsl_end_loop", loc, false) in
end_loop.labels <- label :: end_loop.labels;
end_loop_ref := end_loop;
let env = Env.add_stmt env end_loop in
let env = List.fold_left Env.Logic_binding.remove env bounded_vars in
res, env
| Pforall _ -> Misc.not_yet "unguarded \\forall quantification"
| Pexists(bounded_vars, { content = Pand(hyps, _goal) }) ->
let guards = compute_quantif_guards p bounded_vars hyps in
List.iter
(fun (t1, _, x, _, t2) ->
Options.feedback
"getting %a OP %a OP %a"
d_term t1 d_logic_var x d_term t2)
guards;
assert false
| Pexists _ -> Misc.not_yet "unguarded \\exists quantification"
| Pat _ -> Misc.not_yet "\\at" | Pat _ -> Misc.not_yet "\\at"
| Pvalid _ -> Misc.not_yet "\\valid" | Pvalid _ -> Misc.not_yet "\\valid"
| Pvalid_index _ -> Misc.not_yet "\\valid_index" | Pvalid_index _ -> Misc.not_yet "\\valid_index"
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment