This repository has been archived by the owner on Feb 5, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
chip.py
74 lines (55 loc) · 2.5 KB
/
chip.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
pieces = range(12)
power = range(2)
regular = range(2,12)
MAX_WIDTH = 30
MAX_HEIGHT = 30
widths = [4,4,4,4,5,6,6,6,7,7,10,10]
heights = [3,3,5,6,20,9,10,11,8,12,10,20]
def declareVar(i):
clause = "(X{i} Int) (Y{i} Int) (O{i} Bool) (H{i} Int) (W{i} Int)"
return clause.format(i=i)
def declareVars():
clause = "(benchmark chip.smt\n:logic QF_UFLIA\n:extrafuns ({})".format(" ".join([declareVar(i) for i in pieces]))
return clause
def declareOrientation(i):
clause = "(or (and (not O{i}) (= H{i} {iheight}) (= W{i} {iwidth})) (and (O{i}) (= H{i} {iwidth}) (= W{i} {iheight})))".format(i=i, iheight=heights[i], iwidth=widths[i])
return clause
def declareOrientations():
return "\n".join([declareOrientation(i) for i in pieces])
def onLeft(i,j):
clause = "(<= (+ X{i} W{i}) X{j})"
return clause.format(i=i, j=j)
def onTop(i,j):
clause = "(<= (+ Y{i} H{i}) Y{j})"
return clause.format(i=i, j=j)
# Piece i connects on left edge
def connectLeftEdge(i,j):
clause = "(and (= X{i} (+ X{j} W{j})) (<= Y{j} (+ Y{i} H{i})) (<= Y{i} (+ Y{j} H{j})))"
return clause.format(i=i, j=j)
def connectTopEdge(i,j):
clause = "(and (= Y{i} (+ Y{j} H{j})) (<= X{j} (+ X{i} W{i})) (<= X{i} (+ X{j} W{j})))"
return clause.format(i=i, j=j)
def connectAnyEdge(i,j):
clause = "(or {})".format(" ".join([connectLeftEdge(i,j), connectLeftEdge(j,i), connectTopEdge(i,j), connectTopEdge(j,i)]))
return clause
def notOverlayingAny():
clause = "{}".format("\n".join([notOverlaying(i,j) for i in pieces for j in pieces if j<i]))
return clause
def notOverlaying(i,j):
return "(or {})".format(" ".join([onLeft(i,j), onLeft(j,i), onTop(i,j), onTop(j,i)]))
def onBoard(i):
return "(<= (+ X{i} W{i}) {mw}) (>= X{i} 0) (>= Y{i} 0) (<= (+ Y{i} H{i}) {mh})".format(i=i, mw=MAX_WIDTH, mh=MAX_HEIGHT)
def allOnBoard():
return "\n".join([onBoard(i) for i in pieces])
def connectToPower(i):
return "(or {})".format(" ".join([connectAnyEdge(i,j) for j in power]))
def allRegularConnectingToPower():
clause = "(and {})".format(" ".join([connectToPower(i) for i in regular]))
return clause
def distanceOver18(i,j):
clause = "(or (>= (abs (- (+ X{i} X{i} W{i}) (+ X{j} X{j} W{j}))) 36) (>= (abs (- (+ Y{i} Y{i} H{i}) (+ Y{j} Y{j} H{j}))) 36))"
return clause.format(i=i,j=j)
def formula():
return ":formula (and \n{}\n))".format("".join([declareOrientations(), notOverlayingAny(), allRegularConnectingToPower() ,distanceOver18(0,1),allOnBoard()]))
print(declareVars())
print(formula())