123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193(*******************************************************************************
* electrod - a model finder for relational first-order linear temporal logic
*
* Copyright (C) 2016-2020 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
******************************************************************************)(** Definition of the type for Electrod models. *)openContainersmoduleG=Gen_goal(* variables introduced by a binder *)typevar=BVarofVar.tletbound_varv=BVarvletequal_varid1id2=match(id1,id2)withBVarv1,BVarv2->Var.equalv1v2(* any identifier: a binder-introduced variable or a set/relation name *)typeident=|VarofVar.t|NameofName.tletvar_identi=Variletname_identi=Nameiletvar_ident_of_bound_var(BVarv)=Varvletequal_identid1id2=match(id1,id2)with|Namen1,Namen2->Name.equaln1n2|Varv1,Varv2->Var.equalv1v2|Name_,_|Var_,_->falsetypegoal=(var,ident)G.t(* type of (well-formed) Electrod models *)typet={file:stringoption;(* table of relations indexed by names (remark: a {!Relation.t} also knows its
own name) *)domain:Domain.t;instance:Instance.t;sym:Symmetry.tlist;invariants:(var,ident)G.fmllist;goal:goal;atom_renaming:(Atom.t,Atom.t)List.Assoc.t;name_renaming:(Name.t,Name.t)List.Assoc.t}letmakefiledomaininstancesyminvariantsgoal={file;domain;instance;sym;invariants;goal;atom_renaming=[];name_renaming=[]}(* pretty printers *)letpp_varout(BVarv)=Var.ppoutvletpp_identout=function|Namen->Fmtc.(styled`CyanName.pp)outn|Varv->Fmtc.(styled`Yellowpp_var)out(BVarv)letpp_goal=G.pppp_varpp_identletpp_fml=G.pp_fmlpp_varpp_identletpp_prim_fml=G.pp_prim_fmlpp_varpp_identletpp_exp=G.pp_exppp_varpp_identletpp_prim_exp=G.pp_prim_exppp_varpp_identletpp_iexp=G.pp_iexppp_varpp_identletpp_prim_iexp=G.pp_prim_iexppp_varpp_identletpp_block=G.pp_blockpp_varpp_identletpp_sim_binding=G.pp_sim_bindingpp_varpp_identletppout{domain;instance;invariants;goal;_}=letopenFmtcinpfout"%a@\n%a@\n%a@\n%a"Domain.ppdomainInstance.ppinstance(vbox2@@styled`Bold@@(conststring"invariant"**<cut**<Fmtc.listpp_fml))invariants(vbox@@pp_goal)goal(* substitution *)letsubstitute=object(_:'self)inherit[_]G.mapmethodvisit_'v_=Fun.idmethodvisit_'i_=Fun.idmethod!visit_Ident(env:(Var.t,(var,ident)G.prim_exp)CCList.Assoc.t)(id:ident)=(* Msg.debug *)(* (fun m -> m "Ast.substitute.visit_Ident: %a [%a]" *)(* pp_ident id *)(* (List.pp *)(* @@ Fmt.pair ~sep:Fmtc.(const string "<-") Var.pp *)(* @@ pp_prim_exp) *)(* env); *)matchidwith|VarvarwhenList.Assoc.mem~eq:Var.equalvarenv->List.Assoc.get_exn~eq:Var.equalvarenv|Var_|Name_->G.identid(* method visit_exp env exp = *)(* Msg.debug *)(* (fun m -> m "Ast.substitute.visit_exp: %a [%a]" *)(* pp_exp exp *)(* (List.pp *)(* @@ Fmt.pair ~sep:Fmtc.(const string "<-") Var.pp *)(* @@ pp_prim_exp) *)(* env); *)(* super#visit_exp env exp *)(* method visit_prim_fml env pfml = *)(* Msg.debug *)(* (fun m -> m "%a [%a]" *)(* pp_prim_fml pfml *)(* (List.pp *)(* @@ Fmt.pair ~sep:Fmtc.(const string ":=") Var.pp *)(* @@ pp_prim_exp) *)(* env); *)(* super#visit_prim_fml env pfml *)(* |> Fun.tap (fun res -> *)(* Msg.debug (fun m -> *)(* m "%a [%a] --> %a" *)(* pp_prim_fml pfml *)(* (List.pp *)(* @@ Fmt.pair ~sep:Fmtc.(const string ":=") Var.pp *)(* @@ pp_prim_exp) env *)(* pp_prim_fml res *)(* )) *)end(* renames relation/set names *)letrename=object(_:'self)inherit[_]G.mapmethodvisit_'v_(v:var)=vmethodvisit_'i_=Fun.idmethod!visit_Ident(relation_renaming:(Name.t,Name.t)List.Assoc.t)(id:ident)=matchidwith|Namename->G.ident(Name(List.assoc~eq:Name.equalnamerelation_renaming))|Var_->G.identidend