package electrod
Formal analysis for the Electrod formal pivot language
Install
Dune Dependency
Authors
Maintainers
Sources
electrod-0.4.1.tbz
sha256=b0bce9cc7126672feda5a02d5ef0c1131ba54db57654f80c0768c2f8d043cef9
sha512=92cc22f81522435e190039324767b6f69fa0b7d9dbfc3fb5561919823136fe492244dae993caf98633828e0090b67f306eec6270b86a1b2ff8630642130a3081
doc/src/electrod.libelectrod/Elo_to_model1.ml.html
Source file Elo_to_model1.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
(******************************************************************************* * electrod - a model finder for relational first-order linear temporal logic * * Copyright (C) 2016-2019 ONERA * Authors: Julien Brunel (ONERA), David Chemouil (ONERA) * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * SPDX-License-Identifier: MPL-2.0 * License-Filename: LICENSE.md ******************************************************************************) (** Provides a converter from Electrod models to (part of) a solver model. *) open Containers module S = Iter module Make (Ltl : Solver.LTL) (ConvertFormulas : Elo_to_ltl_intf.S with type ltl = Ltl.t and type atomic = Ltl.Atomic.t) (Model : Solver.MODEL with type ltl = ConvertFormulas.ltl and type atomic = ConvertFormulas.atomic) = struct type atomic = Ltl.Atomic.t (* Compute an LTL formula and the list of atomic propositions from a list of symmetries *) let syms_to_ltl elo = let open Elo in let open Ltl in let syms = elo.sym in let sym_to_ltl (sym : Symmetry.t) = Symmetry.fold (fun (name1, tuple1) (name2, tuple2) (fml_acc : Ltl.t) -> (*We assume that a symmetry is well-formed: each pair of name and tuple (name, tuple) share the same name *) if not (Name.equal name1 name2) then assert false else let at1 = Ltl.Atomic.make elo.domain name1 tuple1 in let at_fml1 = atomic at1 in let at2 = Ltl.Atomic.make elo.domain name2 tuple2 in let at_fml2 = atomic at2 in and_ (implies at_fml1 (lazy at_fml2)) (lazy (implies (iff at_fml1 at_fml2) (lazy fml_acc)))) sym true_ in List.fold_left (fun fmls_acc sym -> let cur_fml = sym_to_ltl sym in S.cons ("-- (symmetry)", cur_fml) fmls_acc) S.empty syms (* Splits a list of formulas lf into four lists (initf, invf, transf, restf): the list of init formulas, invar formulas, the list of trans formulas and the list of the rest of the formulas. In case restf is empty, then the last formula of transf (or invf if transf is also empty) is put in restf.*) let split_invar_noninvar_fmls elo blk = let open Invar_computation in let invf, tmp_restf = List.partition_map (fun fml -> let color = Invar_computation.color elo fml in (* Msg.debug (fun m -> m "Color of formula %a : %a\n" Elo.pp_fml fml Invar_computation.pp color); *) match color with | Invar | Static_prop -> `Left (remove_always_from_invar fml) | Init | Primed_prop | Trans | Temporal -> `Right fml) blk in let transf, tmp_restf2 = List.partition_map (fun fml -> let color = Invar_computation.color elo fml in (* Msg.debug (fun m -> m "Color of formula %a : %a\n" Elo.pp_fml fml Invar_computation.pp color); *) match color with | Trans -> `Left (remove_always_from_invar fml) | _ -> `Right fml) tmp_restf in let initf, restf = List.partition_map (fun fml -> let color = Invar_computation.color elo fml in (* Msg.debug (fun m -> m "Color of formula %a : %a\n" Elo.pp_fml fml Invar_computation.pp color); *) match color with Init -> `Left fml | _ -> `Right fml) tmp_restf2 in match (restf, List.rev invf, List.rev transf, List.rev initf) with | _ :: _, _, _, _ -> (initf, invf, transf, restf) | [], _, hd :: tl, _ -> (initf, invf, List.rev tl, [ add_always_to_invar hd ]) | [], hd :: tl, _, _ -> (initf, List.rev tl, transf, [ add_always_to_invar hd ]) | [], _, _, hd :: tl -> (List.rev tl, invf, transf, [ hd ]) | _ -> assert false (*the goal cannot be empty*) (* From a non-empty list f1, f2, ..., fn of elo formulas, this function computes the elo formula "(f1 and ... and fn-1) implies not fn" *) let dualise_fmls fmls = let open Elo in match List.rev fmls with | [] -> assert false | (Fml { node; _ } as hd) :: tl -> let premise = List.fold_left (fun x y -> lbinary x and_ y) true_ tl in let rhs_fml = match node with LUn (Not, subfml) -> subfml | _ -> lunary not_ hd in lbinary premise impl rhs_fml let run elo = let open Elo in (* #781 Handle instance: To handle the instance, one possibility would be to update the bound computation (bounds_exp) and [build_Ident]. However, apparently, we won't need to differentiate the domain and the instance in the future. So we take the simpler path that consists in updating the domain itself. As this is confined to the following functions, we do this for the time being. If the need arises, a refactoring won't be too painful. *) let elo = Elo. { elo with domain = Domain.update_domain_with_instance elo.domain elo.instance ; instance = Instance.empty } in Msg.debug (fun m -> m "Elo_to_model1.run: after instance update:@ %a" Elo.pp elo); (* walk through formulas, convert them to LTL and accumulate rigid and flexible variables. *) (* let exception Early_stop in *) let translate_formulas fmls = (* try *) List.fold_left (fun acc_fml fml -> let fml_str, ltl = ConvertFormulas.convert elo fml in (* if ltl = Ltl.false_ then *) (* raise Early_stop *) (* else *) S.cons (fml_str, ltl) acc_fml) S.empty fmls (* with *) (* Early_stop -> S.(empty, empty, Ltl.false_) *) |> S.rev in (* handling symmetries *) let syms_fmls = syms_to_ltl elo in (* handling the goal *) let goal_blk = match elo.goal with Elo.Run (g, _) -> g in (* Partition the goal fmls into invars and non invars *) let detected_inits, detected_invars, detected_trans, general_fmls = split_invar_noninvar_fmls elo goal_blk in (* Msg.debug (fun m -> m "Detected init : %a" Elo.pp_block detected_inits); *) (* Msg.debug (fun m -> m "Detected invariants : %a" Elo.pp_block detected_invars); *) (* Msg.debug (fun m -> m "Detected trans : %a" Elo.pp_block detected_trans); *) let spec_fml = dualise_fmls general_fmls in (* Msg.debug (fun m -> m "Elo property : %a" Elo.pp_fml spec_fml); *) let spec_fml_str, prop_ltl = ConvertFormulas.convert elo spec_fml in (* handling init, invariants and trans *) let inits = translate_formulas detected_inits in let invars = translate_formulas @@ List.append detected_invars elo.Elo.invariants in let trans = translate_formulas detected_trans in Model.make ~elo ~init:S.(append inits syms_fmls) ~invariant:invars ~trans ~property:(spec_fml_str, prop_ltl) end
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>