forked from cwhy/i-raven
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathconstraints.py
147 lines (138 loc) · 6.17 KB
/
constraints.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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# -*- coding: utf-8 -*-
from const import (ANGLE_MAX, ANGLE_MIN, COLOR_MAX, COLOR_MIN, NUM_MAX,
NUM_MIN, SIZE_MAX, SIZE_MIN, TYPE_MAX, TYPE_MIN, UNI_MAX,
UNI_MIN)
def gen_layout_constraint(pos_type, pos_list,
num_min=NUM_MIN, num_max=NUM_MAX,
uni_min=UNI_MIN, uni_max=UNI_MAX):
constraint = {"Number": [num_min, num_max],
"Position": [pos_type, pos_list[:]],
"Uni": [uni_min, uni_max]}
return constraint
def gen_entity_constraint(type_min=TYPE_MIN, type_max=TYPE_MAX,
size_min=SIZE_MIN, size_max=SIZE_MAX,
color_min=COLOR_MIN, color_max=COLOR_MAX,
angle_min=ANGLE_MIN, angle_max=ANGLE_MAX):
constraint = {"Type": [type_min, type_max],
"Size": [size_min, size_max],
"Color": [color_min, color_max],
"Angle": [angle_min, angle_max]}
return constraint
def rule_constraint(rule_list, num_min: int, num_max: int,
uni_min: int, uni_max: int,
type_min: int, type_max: int,
size_min: int, size_max: int,
color_min: int, color_max: int):
"""Generate constraints given the rules and the original constraints
from layout and entity. Note that each attribute has at most one rule
applied on it.
Arguments:
rule_list(ordered list of Rule): all rules applied to this layout
others (int): boundary levels for each attribute in a layout; note that
num_max + 1 == len(layout.position.values)
Returns:
layout_constraint(dict): a new layout constraint
entity_constraint(dict): a new entity constraint
"""
assert len(rule_list) > 0
for rule in rule_list:
if rule.name == "Progression":
# rule.value: add/sub how many levels
if rule.attr == "Number":
if rule.value > 0:
num_max = num_max - rule.value * 2
else:
num_min = num_min - rule.value * 2
if rule.attr == "Position":
# Progression here means moving in Layout slots in order
abs_value = abs(rule.value)
num_max = num_max - abs_value * 2
if rule.attr == "Type":
if rule.value > 0:
type_max = type_max - rule.value * 2
else:
type_min = type_min - rule.value * 2
if rule.attr == "Size":
if rule.value > 0:
size_max = size_max - rule.value * 2
else:
size_min = size_min - rule.value * 2
if rule.attr == "Color":
if rule.value > 0:
color_max = color_max - rule.value * 2
else:
color_min = color_min - rule.value * 2
if rule.name == "Arithmetic":
# rule.value > 0 if add col_0 + col_1
# rule.value < 0 if sub col_0 - col_1
if rule.attr == "Number":
if rule.value > 0:
num_max = num_max - num_min - 1
else:
num_min = 2 * num_min + 1
if rule.attr == "Position":
# SET_UNION
# at least two position configurations
if rule.value > 0:
num_max = num_max - 1
# num_min makes sure of overlap
# at least two configurations
# SET_DIFF
else:
num_min = (num_max + 2) // 2 - 1
num_max = num_max - 1
if rule.attr == "Size":
if rule.value > 0:
size_max = size_max - size_min - 1
else:
size_min = 2 * size_min + 1
if rule.attr == "Color":
# at least two different colors
if color_max - color_min < 1:
color_max = color_min - 1
else:
if rule.value > 0:
color_max = color_max - color_min
if rule.value < 0:
color_min = 2 * color_min
if rule.name == "Distribute_Three":
# if less than 3 values, invalidate it
if rule.attr == "Number":
if num_max - num_min + 1 < 3:
num_max = num_min - 1
if rule.attr == "Position":
# max number allowed in the layout should be >= 3
if num_max + 1 < 3:
num_max = num_min - 1
# num_max + 1 == len(layout.position.values)
# C_{num_max + 1}^{num_value} >= 3
# C_{num_max + 1} = num_max + 1 >= 3
# hence only need to constrain num_max: num_max = num_max - 1
# Check Yang Hui’s Triangle (Pascal's Triangle): https://www.varsitytutors.com/hotmath/hotmath_help/topics/yang-huis-triangle
else:
num_max = num_max - 1
if rule.attr == "Type":
if type_max - type_min + 1 < 3:
type_max = type_min - 1
if rule.attr == "Size":
if size_max - size_min + 1 < 3:
size_max = size_min - 1
if rule.attr == "Color":
if color_max - color_min + 1 < 3:
color_max = color_min - 1
assert isinstance(num_min, int)
assert isinstance(num_max, int)
assert isinstance(uni_min, int)
assert isinstance(uni_max, int)
assert isinstance(type_min, int)
assert isinstance(type_max, int)
assert isinstance(size_min, int)
assert isinstance(size_max, int)
assert isinstance(color_min, int)
assert isinstance(color_max, int)
return gen_layout_constraint(None, [],
num_min, num_max,
uni_min, uni_max), \
gen_entity_constraint(type_min, type_max,
size_min, size_max,
color_min, color_max)