model_parser.mli 10.7 KB
Newer Older
1 2 3
(********************************************************************)
(*                                                                  *)
(*  The Why3 Verification Platform   /   The Why3 Development Team  *)
Guillaume Melquiond's avatar
Guillaume Melquiond committed
4
(*  Copyright 2010-2018   --   Inria - CNRS - Paris-Sud University  *)
5 6 7 8 9 10 11
(*                                                                  *)
(*  This software is distributed under the terms of the GNU Lesser  *)
(*  General Public License version 2.1, with the special exception  *)
(*  on linking described in file LICENSE.                           *)
(*                                                                  *)
(********************************************************************)

12
(*
13
***************************************************************
14 15 16
**  Counter-example model values
****************************************************************
*)
17 18 19 20 21 22 23 24

type float_type =
  | Plus_infinity
  | Minus_infinity
  | Plus_zero
  | Minus_zero
  | Not_a_number
  | Float_value of string * string * string
25
  | Float_hexa of string * float
26

27 28
val interp_float: string -> string -> string -> float_type

29 30
type model_value =
 | Integer of string
31
 | Decimal of (string * string)
32
 | Fraction of (string * string)
33
 | Float of float_type
34
 | Boolean of bool
35
 | Array of model_array
36
 | Record of model_record
37
 | Bitvector of string
38
 | Apply of string * model_value list
39
 | Unparsed of string
40
and  arr_index = {
41
  arr_index_key : string;
42 43 44 45 46 47
  arr_index_value : model_value;
}
and model_array = {
  arr_others  : model_value;
  arr_indices : arr_index list;
}
48 49
and model_record = (field_name * model_value) list
and field_name = string
50

51 52
val array_create_constant :
  value : model_value ->
53 54 55
  model_array
(** Creates constant array with all indices equal to the parameter value. *)

56 57
val array_add_element :
  array : model_array ->
58
  index : string      ->
59
  value : model_value ->
60
  model_array
61
(** Adds an element to the array.
62
    @param array : the array to that the element will be added
63

64 65 66 67 68 69 70 71
    @param index : the index on which the element will be added.
    Note that the index must be of value model_value.Integer

    @param value : the value of the element to be added
*)

val print_model_value : Format.formatter -> model_value -> unit

72 73

(*
74
***************************************************************
75 76 77
**  Model elements
***************************************************************
*)
78

79
type model_element_kind =
80 81 82
| Result
  (* Result of a function call (if the counter-example is for postcondition)  *)
| Old
83 84 85 86
  (* Old value of function argument (if the counter-example is for postcondition) *)
| Error_message
  (* The model element represents error message, not source-code element.
     The error message is saved in the name of the model element.*)
87 88
| Other

89 90 91 92 93 94 95
(** Information about the name of the model element *)
type model_element_name = {
  men_name   : string;
    (** The name of the source-code element.  *)
  men_kind   : model_element_kind;
    (** The kind of model element. *)
}
96

97 98
(** Counter-example model elements. Each element represents
    a counter-example for a single source-code element.*)
99
type model_element = {
100 101
  me_name     : model_element_name;
    (** Information about the name of the model element  *)
102 103 104 105
  me_value    : model_value;
    (** Counter-example value for the element. *)
  me_location : Loc.position option;
    (** Source-code location of the element. *)
106 107
  me_term     : Term.term option;
    (** Why term corresponding to the element.  *)
108 109
}

110 111 112 113
val create_model_element :
  name     : string ->
  value    : model_value ->
  ?location : Loc.position ->
114 115
  ?term     : Term.term ->
  unit ->
116
  model_element
117
(** Creates a counter-example model element.
118 119 120 121
    @param name : the name of the source-code element

    @param value  : counter-example value for the element

122 123
    @param location : source-code location of the element

124
    @param term : why term corresponding to the element *)
125

126
(*
127
***************************************************************
128 129
**  Model definitions
***************************************************************
130 131
*)
type model
132

133 134
val is_model_empty : model -> bool
val default_model : model
135 136

(*
137
***************************************************************
138 139 140
**  Quering the model
***************************************************************
*)
141

142
val print_model :
143
  ?me_name_trans:(model_element_name -> string) ->
144
  Format.formatter ->
145
  model ->
146 147 148 149
  unit
(** Prints the counter-example model

    @param me_name_trans the transformation of the model elements
150 151
      names. The input is information about model element name. The
      output is the name of the model element that should be displayed.
152 153 154
    @param model the counter-example model to print
*)

155 156 157 158 159 160 161 162 163 164
val print_model_human :
  ?me_name_trans:(model_element_name -> string) ->
  Format.formatter ->
  model ->
  unit
(** Same as print_model but is intended to be human readable.

*)


165
val model_to_string :
166
  ?me_name_trans:(model_element_name -> string) ->
167 168 169
  model ->
  string
(** See print_model  *)
170

171
val print_model_vc_term :
172
  ?me_name_trans: (model_element_name -> string) ->
173 174 175 176 177 178 179 180 181 182 183 184
  ?sep: string ->
  Format.formatter ->
  model ->
  unit
(** Prints counter-example model elements related to term that
    triggers VC.

    @param sep separator of counter-example model elements
    @param me_name_trans see print_model
    @model the counter-example model.
*)

185
val model_vc_term_to_string :
186
  ?me_name_trans: (model_element_name -> string) ->
187 188 189 190 191 192 193 194
  ?sep: string ->
  model ->
  string
(** Gets string with counter-example model elements related to term that
    triggers VC.
    See print_model_vc_term
*)

195
val print_model_json :
196
  ?me_name_trans:(model_element_name -> string) ->
197
  ?vc_line_trans:(int -> string) ->
198
  Format.formatter ->
199
  model ->
200 201
  unit
(** Prints counter-example model to json format.
202

203
    @param me_name_trans see print_model
204 205 206 207 208 209 210 211 212 213
    @param vc_line_trans the transformation from the line number corresponding
      to the term that triggers VC before splitting VC to the name of JSON field
      storing counterexample information related to this term. By default, this
      information is stored in JSON field corresponding to this line, i.e.,
      the transformation is string_of_int.
      Note that the exact line of the construct that triggers VC may not be
      known. This can happen if the term that triggers VC spans multiple lines
      and it is splitted.
      This transformation can be used to store the counterexample information
      related to this term in dedicated JSON field.
214 215
    @model the counter-example model to print.

216 217 218 219 220 221 222 223 224 225 226 227
    The format is the following:
    - counterexample is JSON object with fields indexed by names of files
      storing values of counterexample_file
    - counterexample_file is JSON object with fields indexed by line numbers
      storing values of counterexample_line
    - counterexample_line is JSON array (ordered list) with elements
      corresponding to counterexample_element
    - counterexample_element is JSON object with following fields
      - "name": name of counterexample element
      - "value": value of counterexample element
      - "kind": kind of counterexample element:
        - "result": Result of a function call (if the counter-example is for postcondition)
228
        - "old": Old value of function argument (if the counter-example is for postcondition)
229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249
        - "error_message": The model element represents error message, not source-code element.
            The error message is saved in the name of the model element
        - "other"

    Example:
    {
      "records.adb": {
          "84": [
            {
              "name": "A.A",
              "value": "255",
              "kind": "other"
            },
            {
              "name": "B.B",
              "value": "0",
              "kind": "other"
            }
          ]
      }
    }
250
*)
251

252
val model_to_string_json :
253
  ?me_name_trans:(model_element_name -> string) ->
254
  ?vc_line_trans:(int -> string) ->
255 256 257
  model ->
  string
(** See print_model_json *)
258

259
val interleave_with_source :
260 261
  ?start_comment:string ->
  ?end_comment:string ->
262
  ?me_name_trans:(model_element_name -> string) ->
263
  model ->
264
  rel_filename:string ->
265
  source_code:string ->
266 267
  locations:(Loc.position * 'a) list ->
  string * (Loc.position * 'a) list
268 269 270 271 272 273 274 275 276 277
(** Given a source code and a counter-example model interleaves
    the source code with information in about the counter-example.
    That is, for each location in counter-example trace creates
    a comment in the output source code with information about
    values of counter-example model elements.

    @param start_comment the string that starts a comment
    @param end_comment the string that ends a comment
    @param me_name_trans see print_model
    @param model counter-example model
278
    @param rel_filename the file name of the source relative to the session
279
    @param source_code the input source code
280
    @param locations the source locations that are found in the code
281 282

    @return the source code with added comments with information
283 284 285
    about counter-example model. The second part of the pair are
    locations modified so that it takes into account that counterexamples
    were added.
286
*)
287 288

(*
289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308
***************************************************************
**  Filtering the model
***************************************************************
*)
val model_for_positions_and_decls : model ->
  positions: Loc.position list -> model
(** Given a model and a list of source-code positions returns model
    that contains only elements from the input model that are on these
    positions plus for every file in the model, elements that are
    in the positions of function declarations. Elements with other
    positions are filtered out.

    Assumes that for each file the element on the first line of the model
    has position of function declaration.

    Only filename and line number is used to identify positions.
*)

(*
***************************************************************
309 310 311 312
** Registering model parser
***************************************************************
*)
type model_parser =  string -> Printer.printer_mapping -> model
313 314
(** Parses the input string into model elements, estabilishes
    a mapping between these elements and mapping from printer
315 316
    and builds model data structure.
*)
317

318
type raw_model_parser =
319
  Wstdlib.Sstr.t -> ((string * string) list) Wstdlib.Mstr.t ->
320
    string -> model_element list
321
(** Parses the input string into model elements. It contains the list of
322 323 324
    projections and a map associating the name of printed projections to the
    fields (couple of printed field and model_trace name) that are collected in
    the task.
325
 *)
326

327
val register_model_parser : desc:Pp.formatted -> string -> raw_model_parser -> unit
328 329 330 331

val lookup_model_parser : string -> model_parser

val list_model_parsers : unit -> (string * Pp.formatted) list