let update_intruder_knowledge (() : unit) : unit =
let rec find_match e l =
match l with [] -> false
|(x::ls) -> if (match_message "(Intruder_, 0)" "" x "(Intruder_, 0)" "" e)
then true
else find_match e ls
in
let deduce_knowledge initial_knowledge =
let build_knowledge e y =
let decomp_y = decompose y in
let know_public_key_of_private_key e =
let decomp = decompose e in
if(decomp=[]) then false
else if((car decomp)="inv" && (find_match (cadr decomp) initial_knowledge)) then true
else false
in
let know_private_key_of_public_key e = ("public_key"=(get_type e)) && (find_match e initial_knowledge) in
if(decomp_y<>[])then(
if((car decomp_y)="scrypt" &&
(match_message "(Intruder_, 0)" "" (cadr decomp_y) "(Intruder_, 0)" "" e ))
then [(caddr decomp_y)]
else if((car decomp_y)="xor" &&
(match_message "" "" (cadr decomp_y) "" "" e ))
then [(caddr decomp_y)]
else if((car decomp_y)="xor" &&
(match_message "" "" (caddr decomp_y) "" "" e ))
then [(cadr decomp_y)]
else if((car decomp_y)="crypt" && (know_private_key_of_public_key e))
then [(caddr decomp_y)]
else if((car decomp_y)="crypt" && (know_public_key_of_private_key e))
then [(caddr decomp_y)]
else if((car decomp_y)="pair") then (cdr decomp_y)
else []
)
else []
in
let rec aux2 elt l res =
match l with [] -> res
|x::ls -> let k1 = List.map (fun e -> if(List.mem e initial_knowledge) then "" else e) (build_knowledge x elt) in
let k2 = List.map (fun e -> if(List.mem e initial_knowledge) then "" else e) (build_knowledge elt x) in
aux2 elt ls (k1@k2@res)
in
let rec aux l res =
match l with [] -> remove_double (remove "" (List.flatten res))
|x::ls -> aux ls ((aux2 x ls [])::res)
in
aux initial_knowledge []
in
let replay = let set_ref = (get_value_of_var "(Intruder_, 0)" "Set_knowledge") in
if(is_a_set set_ref) then (
let decomp = decompose(get_value_of_var "x" set_ref) in
if(decomp=[])
then []
else (
let knowledge_to_add =
let rec aux k =
let tmp = deduce_knowledge k in
if(tmp<>[]) then aux (tmp@k)
else k
in aux (cdr decomp)
in
List.iter (fun k -> add_in_set "(Intruder_, 0)" k "(Intruder_, 0)" "Set_knowledge") knowledge_to_add;
knowledge_to_add
)
)
else []
in
let rec add_transition l k new_state new_actions =
match l with [] -> (("Intruder_,0,Set_knowledge,Listen_i",ref false)::new_state,(("Intruder_,0,Set_knowledge,Listen_i","Listen_i"), (([],[]), ([],["cons(Listen_i,Set_knowledge)"])), ("Intruder_,0,Set_knowledge,Listen_i",""))::new_actions)
|(x::ls) -> let action_tmp = ( ("Intruder_,"^(string_of_int k)^",Set_knowledge,Listen_i",""), (([],[]), ([],[])), ("Intruder_,"^(string_of_int (- k))^",Set_knowledge,Listen_i", x) ) in
let state_tmp = ("Intruder_,"^(string_of_int (- k))^",Set_knowledge,Listen_i", ref true) in
if(List.mem action_tmp new_actions)
then add_transition ls k new_state new_actions
else add_transition ls (k+1) (state_tmp::new_state) (action_tmp::new_actions)
in
automate:=(
List.map
(fun (name,id,state,actionsL) ->
if(name="Intruder_" && id=0)
then (
let (new_states,new_actions) = add_transition replay 1 [] [] in
state:=new_states;
(name,id,state,new_actions)
)
else (name,id,state,actionsL)
)
!automate
)