From a91b14cdcf4dcefd45a3858d93946fba38dc942d Mon Sep 17 00:00:00 2001 From: Virgile Prevosto <virgile.prevosto@m4x.org> Date: Mon, 10 Jan 2022 11:56:09 +0100 Subject: [PATCH] [kernel] skeleton comparison for all global nodes --- src/kernel_services/ast_queries/ast_diff.ml | 120 +++++++++++++++++++- 1 file changed, 117 insertions(+), 3 deletions(-) diff --git a/src/kernel_services/ast_queries/ast_diff.ml b/src/kernel_services/ast_queries/ast_diff.ml index 681d8372391..fd7fad581de 100644 --- a/src/kernel_services/ast_queries/ast_diff.ml +++ b/src/kernel_services/ast_queries/ast_diff.ml @@ -282,6 +282,11 @@ let find_candidate_func ?loc:_loc kf = Some (Globals.Functions.find_by_name (Kf.get_name kf)) with Not_found -> None +let find_candidate_logic_type ?loc:_loc ti = + try + Some (Logic_env.find_logic_type ti.lt_name) + with Not_found -> None + let (&&>) (res,env) f = if res then f env else false, env let (&&|) env f = f env let (&&&) (res,env) b = res && b, env @@ -360,11 +365,52 @@ and is_same_exp _e _e' env = false, env and is_same_offset _o _o' env = false, env -and is_same_funspec _s1 _s2 env = false, env +and is_same_funspec _s _s' env = false, env -and is_same_fundec _f1 _f2 env: body_correspondance*is_same_env = +and is_same_fundec _f _f' env: body_correspondance*is_same_env = `Body_changed, env +and is_same_logic_type _t _t' env = false, env + +and is_same_logic_param _lv _lv' env = false, env + +and is_same_logic_info _li _li' env = false, env + +and is_same_logic_type_info _ti _ti' env = false, env + +and is_same_model_info _mi _mi' env = false, env + +(* because of overloading, we have to check for a corresponding profile, + leading to potentially recursive calls to is_same_* functions. *) +and find_candidate_logic_info ?loc:_loc li env = + let candidates = Logic_env.find_all_logic_functions li.l_var_info.lv_name in + let find_one li' = + is_same_list is_same_logic_param li.l_profile li'.l_profile env + in + let rec extract l = + match l with + | [] -> None + | li' :: tl -> + let (res,_) = find_one li' in + if res then Some li' else extract tl + in + match extract candidates with + | None -> None + | Some li' -> + let (res,_) = is_same_opt is_same_logic_type li.l_type li'.l_type env in + if res then Some li' else None + +and find_candidate_model_info ?loc:_loc mi env = + let candidates = Logic_env.find_all_model_fields mi.mi_name in + let find_one mi' = + fst (is_same_type mi.mi_base_type mi'.mi_base_type env) + in + let rec aux = function + | [] -> None + | mi' :: tl -> if find_one mi' then Some mi' else aux tl + in + aux candidates + and typeinfo_correspondance ?loc ti env = let add ti env = match find_candidate_type ?loc ti with @@ -438,6 +484,39 @@ and gfun_correspondance ?loc vi env = | Some kf' -> `Same kf', env | None -> Kernel_function.memo_env add kf env +and logic_info_correspondance ?loc li env = + let add li env = + match find_candidate_logic_info ?loc li env with + | None -> `Not_present, env + | Some li' -> + let env = + { env with + logic_info = Cil_datatype.Logic_info.Map.add li li' env.logic_info } + in + let res, env = is_same_logic_info li li' env in + (if res then `Same li' else `Not_present), env + in + match Cil_datatype.Logic_info.Map.find_opt li env.logic_info with + | Some li' -> `Same li', env + | None -> Logic_info.memo_env add li env + +and logic_type_correspondance ?loc ti env = + let add ti env = + match find_candidate_logic_type ?loc ti with + | None -> `Not_present, env + | Some ti' -> + let env = + { env with + logic_type_info = + Cil_datatype.Logic_type_info.Map.add ti ti' env.logic_type_info } + in + let res, env = is_same_logic_type_info ti ti' env in + (if res then `Same ti' else `Not_present), env + in + match Cil_datatype.Logic_type_info.Map.find_opt ti env.logic_type_info with + | Some ti' -> `Same ti', env + | None -> Logic_type_info.memo_env add ti env + let gvar_correspondance ?loc vi = let add vi = match find_candidate_varinfo ?loc vi Cil_types.VGlobal with @@ -453,6 +532,40 @@ let gvar_correspondance ?loc vi = in Varinfo.memo add vi +let model_info_correspondance ?loc mi = + let add mi = + match find_candidate_model_info ?loc mi empty_env with + | None -> `Not_present + | Some mi' -> + let res,_ = is_same_model_info mi mi' empty_env in + if res then `Same mi' else `Not_present + in + Model_info.memo add mi + +let rec gannot_correspondance = + function + | Dfun_or_pred (li,loc) -> + ignore (logic_info_correspondance ~loc li empty_env) + + | Dvolatile _ -> () + (* reading and writing function themselves will be checked elsewhere. *) + + | Daxiomatic(_,l,_,_) -> + List.iter gannot_correspondance l + | Dtype (ti,loc) -> ignore (logic_type_correspondance ~loc ti empty_env) + | Dlemma _ -> () + (* TODO: we currently do not have any appropriate structure for + storing information about lemmas. *) + | Dinvariant(li, loc) -> + ignore (logic_info_correspondance ~loc li empty_env) + | Dtype_annot(li,loc) -> + ignore (logic_info_correspondance ~loc li empty_env) + | Dmodel_annot (mi,loc) -> + ignore (model_info_correspondance ~loc mi) + | Dextended _ -> () +(* TODO: provide mechanism for extension themselves + to give relevant information. *) + let global_correspondance g = match g with | GType (ti,loc) -> ignore (typeinfo_correspondance ~loc ti empty_env) @@ -464,7 +577,8 @@ let global_correspondance g = ignore (gvar_correspondance ~loc vi) | GFunDecl(_,vi,loc) -> ignore (gfun_correspondance ~loc vi empty_env) | GFun(f,loc) -> ignore (gfun_correspondance ~loc f.svar empty_env) - | _ -> () + | GAnnot (g,_) -> gannot_correspondance g + | GAsm _ | GPragma _ | GText _ -> () let compare_ast prj = Orig_project.set prj; -- GitLab