-
Notifications
You must be signed in to change notification settings - Fork 1
/
sitegen.py
68 lines (56 loc) · 2.26 KB
/
sitegen.py
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
"""
take an expression tree and find all the target sites where
it may be possible to apply our causal calculus rewrite rules.
(note that we have to do do some diagram chasing on the
structural graph to decide if the assumptions of each
rewrite rule are met. none of that stuff is done here.)
"""
from expr import (is_prob, is_do, is_v, prob, gen_matches, make_list_inject,
make_right_inject)
from util import (compose, without)
def is_prob_conditioned_on_do(expr):
return is_prob(expr) and any(map(is_do, expr[2]))
def is_prob_conditioned_on_v(expr):
return is_prob(expr) and any(map(is_v, expr[2]))
def gather_atoms(atoms):
vs = []
dos = []
for atom in atoms:
(vs if is_v(atom) else dos).append(atom)
return vs, dos
def gen_replacement_sites(predicate, expr):
left, right = expr[1], expr[2]
for i, atom in enumerate(right):
if predicate(atom):
iota = make_list_inject(i, right)
inject = make_right_inject('prob', left, iota)
vs, dos = gather_atoms(without(i, right))
yield [atom], inject, left, vs, dos
def make_prob_append_inject(left, right):
def inject(x=None, drop=False):
if drop:
start = ()
else:
start = (x, )
return prob(left, start + tuple(right))
return inject
def gen_birth_sites(expr):
left, right = expr[1], expr[2]
inject = make_prob_append_inject(left, right)
vs, dos = gather_atoms(right)
yield [], inject, left, vs, dos
def make_site_generator(expr_predicate, site_predicate=None, birth_site=False):
if birth_site:
gen_target_sites = gen_birth_sites
else:
gen_target_sites = lambda expr : gen_replacement_sites(site_predicate, expr)
def gen_moves(root_expr):
for (expr, expr_inject) in gen_matches(expr_predicate, root_expr):
for site in gen_target_sites(expr):
target, site_inject, left, vs, dos = site
inject = compose(expr_inject, site_inject)
yield (target, inject, left, vs, dos, expr)
return gen_moves
gen_v_sites = make_site_generator(is_prob_conditioned_on_v, is_v)
gen_do_sites = make_site_generator(is_prob_conditioned_on_do, is_do)
gen_birth_sites = make_site_generator(is_prob, birth_site=True)