1- from collections import defaultdict
2-
3- from comb_spec_searcher import InferralRule
4- from permuta import Perm
5- from tilings import Obstruction , Tiling
6-
7-
8- def compute_new_ineqs (pos , ineqs ):
9- """Computes the transitive relation over positive cells.
10-
11- Given a list of inequalities and positive cells, a new set of inequalities
12- is computed. For every positive cell c, when g < c < l the relation g < l
13- is added if not already there. The new list of inequalities is returned.
14- """
15- gtlist = defaultdict (list )
16- ltlist = defaultdict (list )
17- for left , right in ineqs :
18- ltlist [left ].append (right )
19- gtlist [right ].append (left )
20- stack = list (pos )
21- ineqs = set (ineqs )
22- newineqs = set ()
23- while len (stack ) > 0 :
24- cur = stack .pop (0 )
25- for gt in gtlist [cur ]:
26- for lt in ltlist [cur ]:
27- if (gt , lt ) not in ineqs :
28- gtlist [lt ].append (gt )
29- ltlist [gt ].append (lt )
30- ineqs .add ((gt , lt ))
31- if gt != lt :
32- newineqs .add ((gt , lt ))
33- if lt not in stack and lt in pos :
34- stack .append (lt )
35- if gt not in stack and gt in pos :
36- stack .append (gt )
37- return newineqs
38-
39-
40- def compute_ineq_ob (left , right ):
41- """Given an inequality of cells left < right, compute an obstruction."""
42- if left [0 ] == right [0 ]:
43- # same column
44- if left [1 ] < right [1 ]:
45- return Obstruction (Perm ((1 , 0 )), [right , left ])
46- else :
47- return Obstruction (Perm ((0 , 1 )), [right , left ])
48- elif left [1 ] == right [1 ]:
49- # same row
50- if left [0 ] < right [0 ]:
51- return Obstruction (Perm ((1 , 0 )), [left , right ])
52- else :
53- return Obstruction (Perm ((0 , 1 )), [right , left ])
54- else :
55- raise ValueError (
56- ("Can not construct an obstruction from inequality {} < {}"
57- ).format (left , right ))
1+ from tilings .algorithms import ObstructionTransitivity
582
593
604def obstruction_transitivity (tiling , ** kwargs ):
@@ -66,42 +10,5 @@ def obstruction_transitivity(tiling, **kwargs):
6610 inequality relations. When the the obstructions use a positive cell,
6711 transitivity applies, i.e. if a < b < c and b is positive, then a < c.
6812 """
69- positive_cells_col = defaultdict (list )
70- positive_cells_row = defaultdict (list )
71- for cell in tiling .positive_cells :
72- positive_cells_col [cell [0 ]].append (cell [1 ])
73- positive_cells_row [cell [1 ]].append (cell [0 ])
74- colineq = defaultdict (set )
75- rowineq = defaultdict (set )
76- for ob in tiling .obstructions :
77- if len (ob ) != 2 or ob .is_localized ():
78- continue
79- leftcol , rightcol = ob .pos [0 ][0 ], ob .pos [1 ][0 ]
80- leftrow , rightrow = ob .pos [0 ][1 ], ob .pos [1 ][1 ]
81- # In same column
82- if leftcol == rightcol :
83- if ob .patt == Perm ((0 , 1 )):
84- colineq [leftcol ].add ((rightrow , leftrow ))
85- else :
86- colineq [leftcol ].add ((rightrow , leftrow ))
87- # In same row
88- elif ob .pos [0 ][1 ] == ob .pos [1 ][1 ]:
89- if ob .patt == Perm ((0 , 1 )):
90- rowineq [leftrow ].add ((rightcol , leftcol ))
91- else :
92- rowineq [leftrow ].add ((leftcol , rightcol ))
93-
94- newineqs = []
95- for col , ineqs in colineq .items ():
96- for left , right in compute_new_ineqs (positive_cells_col [col ], ineqs ):
97- newineqs .append (((col , left ), (col , right )))
98- for row , ineqs in rowineq .items ():
99- for left , right in compute_new_ineqs (positive_cells_row [row ], ineqs ):
100- newineqs .append (((left , row ), (right , row )))
101-
102- if newineqs :
103- return InferralRule (
104- "Computing transitivity of inequalities." ,
105- Tiling (obstructions = (tiling .obstructions + tuple (
106- compute_ineq_ob (left , right ) for left , right in newineqs )),
107- requirements = tiling .requirements ))
13+ obs_trans = ObstructionTransitivity (tiling )
14+ return obs_trans .rule ()
0 commit comments