File: client.py

package info (click to toggle)
gringo 5.8.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 32,128 kB
  • sloc: cpp: 210,867; ansic: 37,507; python: 11,271; yacc: 825; javascript: 627; sh: 368; xml: 364; makefile: 102
file content (95 lines) | stat: -rw-r--r-- 2,898 bytes parent folder | download
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)