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
|
import errno
import os
import socket
from clingo import Control, Function, Number
class Receiver:
def __init__(self, conn):
self.conn = conn
self.data = bytearray()
def readline(self):
pos = self.data.find(b"\n")
while pos < 0:
while True:
try:
self.data.extend(self.conn.recv(4096))
except OSError as e:
if e.errno != errno.EINTR:
raise
except socket.error as e:
code, msg = e
if code != errno.EINTR:
raise
else:
break
pos = self.data.find(b"\n")
msg = self.data[:pos]
self.data = self.data[pos + 1 :]
return msg
class States:
SOLVE = 1
IDLE = 2
def main(prg):
with open(".controller.PORT", "r") as f:
p = int(f.read())
os.remove(".controller.PORT")
conn = socket.create_connection(("127.0.0.1", p))
try:
recv = Receiver(conn)
state = States.IDLE
k = 0
prg.ground([("pigeon", []), ("sleep", [Number(k)])])
prg.assign_external(Function("sleep", [Number(k)]), True)
while True:
if state == States.SOLVE:
f = prg.solve(
on_model=lambda model: conn.sendall(
b"Answer: " + str(model).encode() + b"\n"
),
on_finish=lambda ret: conn.sendall(
b"finish:"
+ str(ret).encode()
+ (b":INTERRUPTED" if ret.interrupted else b"")
+ b"\n"
),
async_=True,
)
msg = recv.readline().decode()
if state == States.SOLVE:
f.cancel()
ret = f.get()
else:
ret = None
if msg == "interrupt":
state = States.IDLE
elif msg == "exit":
return
elif msg == "less_pigeon_please":
prg.assign_external(Function("p"), False)
state = States.IDLE
elif msg == "more_pigeon_please":
prg.assign_external(Function("p"), True)
state = States.IDLE
elif msg == "solve":
state = States.SOLVE
else:
raise (RuntimeError("unexpected message: " + msg))
if ret is not None and not ret.unknown:
k = k + 1
prg.ground([("sleep", [Number(k)])])
prg.release_external(Function("sleep", [Number(k - 1)]))
prg.assign_external(Function("sleep", [Number(k)]), True)
finally:
conn.close()
prg = Control()
prg.load("client.lp")
main(prg)
|