Advertisement
Guest User

Untitled

a guest
Jan 24th, 2018
56
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.40 KB | None | 0 0
  1. let trans_form_or_pattern env (ps, ue) pf tt =
  2. let state = PFS.create () in
  3.  
  4. let rec transf_r opsc env f =
  5. let transf = transf_r opsc in
  6.  
  7. match f.pl_desc with
  8. | PFhole -> begin
  9. match ps with
  10. | None -> tyerror f.pl_loc env PatternNotAllowed
  11. | Some ps ->
  12. let x = EcIdent.create (Printf.sprintf "?%d" (EcUid.unique ())) in
  13. let ty = UE.fresh ue in
  14. ps := Mid.add x ty !ps; f_local x ty
  15. end
  16.  
  17. | PFmem _ -> tyerror f.pl_loc env MemNotAllowed
  18.  
  19. | PFscope (popsc, f) ->
  20. let opsc = lookup_scope env popsc in
  21. transf_r (Some opsc) env f
  22.  
  23. | PFglob gp ->
  24. let mp = fst (trans_msymbol env gp) in
  25. let me =
  26. match EcEnv.Memory.current env with
  27. | None -> tyerror f.pl_loc env NoActiveMemory
  28. | Some me -> EcMemory.memory me
  29. in PFS.set_memused state; f_glob mp me
  30.  
  31. | PFint n ->
  32. f_int n
  33.  
  34. | PFtuple args -> begin
  35. let args = List.map (transf env) args in
  36. match args with
  37. | [] -> f_tt
  38. | [f] -> f
  39. | fs -> f_tuple fs
  40. end
  41.  
  42. | PFident ({ pl_desc = name; pl_loc = loc }, tvi) ->
  43. let tvi = tvi |> omap (transtvi env ue) in
  44. let ops = select_form_op env opsc name ue tvi [] in
  45. begin match ops with
  46. | [] ->
  47. tyerror loc env (UnknownVarOrOp (name, []))
  48.  
  49. | [sel] -> begin
  50. let op = form_of_opselect (env, ue) loc sel [] in
  51. let inmem =
  52. match op.f_node with
  53. | Fpvar _ | Fproj ({ f_node = Fpvar _ }, _) -> true
  54. | _ -> false in
  55. if inmem then PFS.set_memused state; op
  56. end
  57.  
  58. | _ ->
  59. let matches = List.map (fun (_, _, subue, m) -> (m, subue)) ops in
  60. tyerror loc env (MultipleOpMatch (name, [], matches))
  61. end
  62.  
  63. | PFside (f, side) -> begin
  64. let (sloc, side) = (side.pl_loc, unloc side) in
  65. let me =
  66. match EcEnv.Memory.lookup side env with
  67. | None -> tyerror sloc env (UnknownMemName side)
  68. | Some me -> EcMemory.memory me
  69. in
  70.  
  71. let used, aout =
  72. PFS.new_memused
  73. (transf (EcEnv.Memory.set_active me env))
  74. state f
  75. in
  76. if not used then begin
  77. let ppe = EcPrinting.PPEnv.ofenv env in
  78. EcEnv.notify ~immediate:false env `Warning
  79. "unused memory `%s', while typing %a"
  80. side (EcPrinting.pp_form ppe) aout
  81. end;
  82. aout
  83. end
  84.  
  85. | PFeqveq (xs, om) ->
  86. let lookup me x =
  87. match EcEnv.Var.lookup_progvar_opt ~side:me (unloc x) env with
  88. | None -> tyerror x.pl_loc env (UnknownVarOrOp (unloc x, []))
  89. | Some (x, ty) ->
  90. match x with
  91. | `Var x -> f_pvar x ty me
  92. | `Proj (x, ty', (i, n)) ->
  93. if i = 0 && n = 1
  94. then f_pvar x ty me
  95. else f_proj (f_pvar x ty' me) i ty
  96. in
  97.  
  98. let check_mem loc me =
  99. match EcEnv.Memory.byid me env with
  100. | None -> tyerror loc env (UnknownMemName (EcIdent.name me))
  101. | Some _ -> ()
  102. in
  103.  
  104. let qual (mq : pmsymbol option) (x : pqsymbol) =
  105. match mq with
  106. | None -> x
  107. | Some qs ->
  108. let (nm, name) = x.pl_desc in
  109. { x with pl_desc = ((List.map (unloc |- fst) qs)@nm, name) }
  110. in
  111.  
  112. let do1 = function
  113. | GVvar x ->
  114. let x1 = lookup EcFol.mleft (qual (om |> omap fst) x) in
  115. let x2 = lookup EcFol.mright (qual (om |> omap snd) x) in
  116. unify_or_fail env ue x.pl_loc ~expct:x1.f_ty x2.f_ty;
  117. f_eq x1 x2
  118.  
  119. | GVglob gp ->
  120. let (mp, _) = trans_msymbol env gp in
  121. let x1 = f_glob mp EcFol.mleft in
  122. let x2 = f_glob mp EcFol.mright in
  123. unify_or_fail env ue gp.pl_loc ~expct:x1.f_ty x2.f_ty;
  124. f_eq x1 x2
  125. in
  126. check_mem f.pl_loc EcFol.mleft;
  127. check_mem f.pl_loc EcFol.mright;
  128. EcFol.f_ands (List.map do1 xs)
  129.  
  130. | PFeqf fs ->
  131. let check_mem loc me =
  132. match EcEnv.Memory.byid me env with
  133. | None -> tyerror loc env (UnknownMemName (EcIdent.name me))
  134. | Some _ -> ()
  135.  
  136. and do1 (me1, me2) f =
  137. let _, f1 =
  138. PFS.new_memused
  139. (transf (EcEnv.Memory.set_active me1 env))
  140. state f in
  141. let _, f2 =
  142. PFS.new_memused
  143. (transf (EcEnv.Memory.set_active me2 env))
  144. state f in
  145. unify_or_fail env ue f.pl_loc ~expct:f1.f_ty f2.f_ty;
  146. f_eq f1 f2
  147.  
  148. in
  149. check_mem f.pl_loc EcFol.mleft;
  150. check_mem f.pl_loc EcFol.mright;
  151. EcFol.f_ands (List.map (do1 (EcFol.mleft, EcFol.mright)) fs)
  152.  
  153. | PFapp ({pl_desc = PFident ({ pl_desc = name; pl_loc = loc }, tvi)}, pes) ->
  154. let tvi = tvi |> omap (transtvi env ue) in
  155. let es = List.map (transf env) pes in
  156. let esig = List.map EcFol.f_ty es in
  157. let ops = select_form_op env opsc name ue tvi esig in
  158. begin match ops with
  159. | [] ->
  160. let esig = Tuni.offun_dom (EcUnify.UniEnv.assubst ue) esig in
  161. tyerror loc env (UnknownVarOrOp (name, esig))
  162.  
  163. | [sel] ->
  164. let es = List.map2 (fun e l -> mk_loc l.pl_loc e) es pes in
  165. form_of_opselect (env, ue) loc sel es
  166.  
  167. | _ ->
  168. let esig = Tuni.offun_dom (EcUnify.UniEnv.assubst ue) esig in
  169. let matches = List.map (fun (_, _, subue, m) -> (m, subue)) ops in
  170. tyerror loc env (MultipleOpMatch (name, esig, matches))
  171. end
  172.  
  173. | PFapp (e, pes) ->
  174. let es = List.map (transf env) pes in
  175. let esig = List.map2 (fun f l -> mk_loc l.pl_loc f.f_ty) es pes in
  176. let op = transf env e in
  177. let codom = ty_fun_app e.pl_loc env ue op.f_ty esig in
  178. f_app op es codom
  179.  
  180. | PFif (pf1, pf2, pf3) ->
  181. let f1 = transf env pf1 in
  182. let f2 = transf env pf2 in
  183. let f3 = transf env pf3 in
  184. unify_or_fail env ue pf1.pl_loc ~expct:tbool f1.f_ty;
  185. unify_or_fail env ue pf3.pl_loc ~expct:f2.f_ty f3.f_ty;
  186. f_if f1 f2 f3
  187.  
  188. | PFlet (lp, (pf1, paty), f2) ->
  189. let (penv, p, pty) = transpattern env ue lp in
  190. let aty = paty |> omap (transty tp_uni env ue) in
  191. let f1 = transf env pf1 in
  192. unify_or_fail env ue pf1.pl_loc ~expct:pty f1.f_ty;
  193. aty |> oiter (fun aty-> unify_or_fail env ue pf1.pl_loc ~expct:pty aty);
  194. let f2 = transf penv f2 in
  195. f_let p f1 f2
  196.  
  197. | PFforall (xs, pf) ->
  198. let env, xs = trans_gbinding env ue xs in
  199. let f = transf env pf in
  200. unify_or_fail env ue pf.pl_loc ~expct:tbool f.f_ty;
  201. f_forall xs f
  202.  
  203. | PFexists (xs, f1) ->
  204. let env, xs = trans_gbinding env ue xs in
  205. let f = transf env f1 in
  206. unify_or_fail env ue f1.pl_loc ~expct:tbool f.f_ty;
  207. f_exists xs f
  208.  
  209. | PFlambda (xs, f1) ->
  210. let env, xs = trans_binding env ue xs in
  211. let f = transf env f1 in
  212. f_lambda (List.map (fun (x,ty) -> (x,GTty ty)) xs) f
  213.  
  214. | PFrecord fields ->
  215. let (ctor, fields, (rtvi, reccty)) =
  216. trans_record env ue
  217. (fun f -> let f = transf env f in (f, f.f_ty))
  218. (f.pl_loc, fields) in
  219. let ctor = f_op ctor rtvi (toarrow (List.map snd fields) reccty) in
  220. let ctor = f_app ctor (List.map fst fields) reccty in
  221. ctor
  222.  
  223. | PFproj (subf, x) -> begin
  224. let subf = transf env subf in
  225.  
  226. match select_proj env opsc (unloc x) ue None subf.f_ty with
  227. | [] ->
  228. let ty = Tuni.offun (EcUnify.UniEnv.assubst ue) subf.f_ty in
  229. let lf =
  230. let mp =
  231. match ty.ty_node with
  232. | Tglob mp -> mp
  233. | _ -> tyerror x.pl_loc env (UnknownProj (unloc x)) in
  234.  
  235. match NormMp.norm_glob env EcFol.mhr mp with
  236. | { f_node = Ftuple xs } -> xs
  237. | _ -> tyerror x.pl_loc env (UnknownProj (unloc x))
  238. in
  239.  
  240. let (vx, ty) =
  241. match EcEnv.Var.lookup_progvar_opt ~side:EcFol.mhr (unloc x) env with
  242. | None ->
  243. tyerror x.pl_loc env (UnknownVarOrOp (unloc x, []))
  244. | Some (`Var x, ty) ->
  245. (NormMp.norm_pvar env x, ty)
  246. | Some (_, _) ->
  247. tyerror x.pl_loc env (UnknownVarOrOp (unloc x, [])) in
  248.  
  249. let find = function
  250. | { f_node = Fpvar (x, _) } ->
  251. EcTypes.pv_equal vx (NormMp.norm_pvar env x)
  252. | _ -> false in
  253.  
  254. let i =
  255. match List.oindex find lf with
  256. | None -> tyerror x.pl_loc env (UnknownProj (unloc x))
  257. | Some i -> i
  258.  
  259. in f_proj subf i ty
  260.  
  261. | _ :: _ :: _ ->
  262. tyerror x.pl_loc env (AmbiguousProj (unloc x))
  263.  
  264. | [(op, tvi), pty, subue] ->
  265. EcUnify.UniEnv.restore ~src:subue ~dst:ue;
  266. let rty = EcUnify.UniEnv.fresh ue in
  267. (try EcUnify.unify env ue (tfun subf.f_ty rty) pty
  268. with EcUnify.UnificationFailure _ -> assert false);
  269. f_app (f_op op tvi pty) [subf] rty
  270. end
  271.  
  272. | PFproji (psubf, i) -> begin
  273. let subf = transf env psubf in
  274. let ty = Tuni.offun (EcUnify.UniEnv.assubst ue) subf.f_ty in
  275. match (EcEnv.ty_hnorm ty env).ty_node with
  276. | Ttuple l when i < List.length l ->
  277. f_proj subf i (List.nth l i)
  278. | _ ->
  279. tyerror psubf.pl_loc env (AmbiguousProji (i, ty))
  280. end
  281.  
  282. | PFprob (gp, args, m, event) ->
  283. let fpath = trans_gamepath env gp in
  284. let fun_ = EcEnv.Fun.by_xpath fpath env in
  285. let args,_ =
  286. transcall (fun f -> let f = transf env f in f, f.f_ty)
  287. env ue f.pl_loc fun_.f_sig args in
  288. let memid = transmem env m in
  289. let env = EcEnv.Fun.prF fpath env in
  290. let event' = transf env event in
  291. unify_or_fail env ue event.pl_loc ~expct:tbool event'.f_ty;
  292. f_pr memid fpath (f_tuple args) event'
  293.  
  294. | PFhoareF (pre, gp, post) ->
  295. let fpath = trans_gamepath env gp in
  296. let penv, qenv = EcEnv.Fun.hoareF fpath env in
  297. let pre' = transf penv pre in
  298. let post' = transf qenv post in
  299. unify_or_fail penv ue pre.pl_loc ~expct:tbool pre' .f_ty;
  300. unify_or_fail qenv ue post.pl_loc ~expct:tbool post'.f_ty;
  301. f_hoareF pre' fpath post'
  302.  
  303. | PFBDhoareF (pre, gp, post, hcmp, bd) ->
  304. let fpath = trans_gamepath env gp in
  305. let penv, qenv = EcEnv.Fun.hoareF fpath env in
  306. let pre' = transf penv pre in
  307. let post' = transf qenv post in
  308. let bd' = transf penv bd in
  309. (* FIXME: check that there are not pvars in bd *)
  310. unify_or_fail penv ue pre .pl_loc ~expct:tbool pre' .f_ty;
  311. unify_or_fail qenv ue post.pl_loc ~expct:tbool post'.f_ty;
  312. unify_or_fail env ue bd .pl_loc ~expct:treal bd' .f_ty;
  313. f_bdHoareF pre' fpath post' hcmp bd'
  314.  
  315. | PFlsless gp ->
  316. let fpath = trans_gamepath env gp in
  317. f_losslessF fpath
  318.  
  319. | PFequivF (pre, (gp1, gp2), post) ->
  320. let fpath1 = trans_gamepath env gp1 in
  321. let fpath2 = trans_gamepath env gp2 in
  322. let penv, qenv = EcEnv.Fun.equivF fpath1 fpath2 env in
  323. let pre' = transf penv pre in
  324. let post' = transf qenv post in
  325. unify_or_fail penv ue pre .pl_loc ~expct:tbool pre' .f_ty;
  326. unify_or_fail qenv ue post.pl_loc ~expct:tbool post'.f_ty;
  327. f_equivF pre' fpath1 fpath2 post'
  328.  
  329. | PFeagerF (pre, (s1,gp1,gp2,s2), post) ->
  330. let fpath1 = trans_gamepath env gp1 in
  331. let fpath2 = trans_gamepath env gp2 in
  332. let penv, qenv = EcEnv.Fun.equivF fpath1 fpath2 env in
  333. let pre' = transf penv pre in
  334. let post' = transf qenv post in
  335. let s1 = transstmt env ue s1 in
  336. let s2 = transstmt env ue s2 in
  337. unify_or_fail penv ue pre .pl_loc ~expct:tbool pre' .f_ty;
  338. unify_or_fail qenv ue post.pl_loc ~expct:tbool post'.f_ty;
  339. f_eagerF pre' s1 fpath1 fpath2 s2 post'
  340.  
  341. in
  342.  
  343. let f = transf_r None env pf in
  344. tt |> oiter (fun tt -> unify_or_fail env ue pf.pl_loc ~expct:tt f.f_ty);
  345. f
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement