123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111(**************************************************************************)(* *)(* This file is part of Aorai plug-in of Frama-C. *)(* *)(* Copyright (C) 2007-2023 *)(* CEA (Commissariat à l'énergie atomique et aux énergies *)(* alternatives) *)(* INRIA (Institut National de Recherche en Informatique et en *)(* Automatique) *)(* INSA (Institut National des Sciences Appliquees) *)(* *)(* 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). *)(* *)(**************************************************************************)openAutomaton_astletvoisins(_,trans_l)st=List.fold_left(funvltr->iftr.start.nums=st.numsthen(tr.stop,1)::vlelsevl)[]trans_lletempty()=[];;letis_emptyheap=(List.lengthheap)=0;;letadd(length,(st,path))heap=(length,(st,path))::heap;;letextract_minheap=let(min,h)=List.fold_left(fun((lmin,min),h)(lcur,cur)->iflmin<=lcurthen((lmin,min),(lcur,cur)::h)else((lcur,cur),(lmin,min)::h))((List.hdheap),[])(List.tlheap)in(min,h)(* Source : wikipedia*)(* l'adjacence est donnee sous la forme d'une fonction : adj v est la liste des voisins de v,
avec leur distance ; la fonction suivante cherche le plus court chemin de v1 a v2 *)letdijkstra(adj:'a->('a*int)list)(v1:'a)(v2:'a)=letvisited=Hashtbl.create97inletreclooph=ifis_emptyhthenraiseNot_found;let(w,(v,p)),h=extract_minhinifv=v2thenList.revp,welseleth=ifnot(Hashtbl.memvisitedv)thenbeginHashtbl.addvisitedv();List.fold_left(funh(e,d)->add(w+d,(e,e::p))h)h(adjv)endelsehinloophinloop(add(0,(v1,[]))(empty()))(** since Nitrogen-20111001 *)letget_transitions_of_statest(_,tr)=List.fold_left(funacctr->iftr.start.nums=st.numsthentr::accelseacc)[]trletget_edgesst1st2(_,tr)=List.find_all(funtr->tr.start.nums=st1.nums&&tr.stop.nums=st2.nums)trletget_init_states(st,_)=List.filter(funx->x.init=Bool3.True)stletat_most_one_path(states,transitionsasauto)st1st2=tryletpath,_=dijkstra(voisinsauto)st1st2inmatchpathwith|[]|[_]->true|x::y::_->let(trans1,trans2)=List.partition(funt->t.start.nums=x.nums&&t.stop.nums=y.nums)transitionsinlettransitions=(List.tltrans1)@trans2inletauto=states,transitionsinignore(dijkstra(voisinsauto)st1st2);falsewithNot_found->true(*
Local Variables:
compile-command: "make -C ../../.."
End:
*)