-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpushout.ml
More file actions
51 lines (46 loc) · 1.75 KB
/
pushout.ml
File metadata and controls
51 lines (46 loc) · 1.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
open Util
open Util.OptionExtra
open Syntax
open Preprocess
(** lambda abstraction atom を評価した時に,クロージャにする *)
let make_closure theta = function
| Lam (ctx, e, _), links -> (Lam (ctx, e, theta), links)
| atom -> atom
(** Check that the given two atoms or graph contexts have the same functors. *)
let check_functor (v1, args1) (v2, args2) =
(v1, List.length args1) = (v2, List.length args2)
(** [synthesis theta template_graph] substitutes with [theta] to
[template_graph]. *)
let synthesis theta template_graph =
let i, (atoms, ctxs) = alpha 0 [] template_graph in
let atoms = List.map (make_closure theta) atoms in
let subst_graph i ctx =
match List.find_opt (check_functor ctx <. fst) theta with
| None ->
failwith @@ "unbound graph context " ^ fst ctx ^ " in "
^ String.concat ", "
(List.map
(fun ((x, xs), _) -> x ^ "/" ^ string_of_int (List.length xs))
theta)
| Some (ctx2, graph) ->
let link_theta = List.combine (snd ctx2) (snd ctx) in
alpha_atoms (i, link_theta) graph
in
let _, graphs = List.fold_left_map subst_graph i ctxs in
atoms @ List.concat graphs
(** Get fusing links from an atom. At least one of the links should be a local
link. *)
let get_local_fusion_opt = function
| Constr "><", ([ (LocalLink _ as x); y ] | [ y; (LocalLink _ as x) ]) ->
Some (x, y)
| _ -> None
(** [fuse_fusions graph] absorbs all the fusions in the [graph] except for that
connects free links. *)
let fuse_fusions graph =
let fuse_fusion graph =
let+ fusion, (g1, g2) =
ListExtra.rev_break_opt get_local_fusion_opt graph
in
Postprocess.subst_link_of_atoms [ fusion ] (List.rev_append g1 g2)
in
whileM fuse_fusion graph