示例#1
0
 def drawO(self, posXY):
     [px, py] = self.boardPositionToPixelCenter(posXY)
     circle = Circle(x=px,
                     y=py,
                     z=1,
                     width=self.cell_size * 0.9,
                     color=self.colorO,
                     stroke=5)
     circle.render()
示例#2
0
    def render(self, batch, group=None):

        self.frame.render(batch)
        l_x, l_y = self.calc_label_position(self.label)
        label = pyglet.text.Label(self.text, x=l_x, y=l_y, batch=batch)
        circ_y = l_y + round(self.label.content_height * 0.33)
        circ_x = round((self.frame.x + 10))
        circle = Circle(5, circ_x, circ_y, fill=self.selected)
        circle.render(batch)
示例#3
0
    def draw(self):
        super(CollidableSprite, self).draw()
        if not isinstance(self, BallMan):
            return

        if log.level == logging.DEBUG:
            path_nodes = self.get_ancestor(Level).path_nodes
            for node in path_nodes:
                x,y = node.x, node.y
                c = Circle(x,y,width=10,color=(0.,.9,0.,1.))
                c.render()
示例#4
0
 def drawCell(self, posXY, pixelCenter, cell_size):
     x = self.board.xyToIndex(posXY)
     v = self.assessments[x]
     if v <= -100:
         return
     if not self.dev:
         return
     stand = (v - self.average) / self.dev
     circle = Circle(x=pixelCenter[0],
                     y=pixelCenter[1],
                     z=1,
                     width=cell_size * 0.5,
                     color=(stand, 0, 0, 0.98 * stand),
                     stroke=5)
     circle.render()
    def __init__(self,start_screen=None,loader=None):
        self.start_screen = start_screen
        self.loader = loader

        self.current_screen = self.start_screen
        self.pointer = Circle()

        self.enabled = False
    def process_circle(self, c_info, unnamed=True):
        if isinstance(c_info, str) and not is_number(c_info):
            assert (Circle(c_info) in self.circles)
            return Circle(c_info)
        if not isinstance(c_info, tuple):
            raise NotImplementedError(
                f"[process_circle] c_info must be tuple or string")

        c_pred = c_info[0].lower()
        ps = [self.process_point(p) for p in c_info[1:]]
        c_val = None

        if c_pred == "circ":
            assert (len(ps) == 3)
            c_val = FuncInfo("c3", ps)
        elif c_pred == "coa":
            assert (len(ps) == 2)
            c_val = FuncInfo(c_pred, ps)
        elif c_pred == "diam":
            assert (len(ps) == 2)
            c_val = FuncInfo("diam", ps)
        elif c_pred == "circumcircle":
            assert (len(ps) == 3)
            c_val = FuncInfo("circumcircle", ps)
        elif c_pred == "incircle":
            assert (len(ps) == 3)
            c_val = FuncInfo("incircle", ps)
        elif c_pred == "excircle":
            assert (len(ps) == 3)
            c_val = FuncInfo("excircle", ps)
        elif c_pred == "mixtilinear-incircle":
            assert (len(ps) == 3)
            c_val = FuncInfo(c_pred, ps)

        if c_val is not None:
            C = Circle(c_val)
            if unnamed:
                self.unnamed_circles.append(C)
            return C
        else:
            raise NotImplementedError(
                f"[process_circle] Unsupported circle pred: {c_pred}")
示例#7
0
 def draw(self):
     if self.stop:
         director.scene.end()
         
     if self.state == self.SWITCH:
         text = font.Text(self.font, 'switch to:',color=(0.,0.5,0.5,0.5))
         text.x = 20
         text.y = 300
         text.draw()
         text = font.Text(self.font, self.number ,color=(0.,0.5,0.5,0.5))
         text.x = 20
         text.y = 250
         text.draw()
         
     elif self.state in (self.SHOW, self.DRAG):
         self.path.render()
         if self.near:
             c = Circle(
                 self.near.x,self.near.y,
                 width=15,color=(0.,1.,1.,1.)
                 )
             c.render()
             
     elif self.state == self.ANIMATE:
         dt = time.time() - self.anim_start
         bz = self.path.bezier()
         if dt >= self.duration:
             self.state = self.SHOW
         else:
             x,y = bz.at( (dt/self.duration)**self.time_warp )
             c = Circle(
                     x+self.path.a.x,y+self.path.a.y,
                     width=45,color=(0.,1.,1.,1.)
                     )
             c.render()
                 
             
     text = font.Text(self.font, '[%i,%i] t**%0.2f d=%0.2f n=%d p=%d'%(
                 self.mouse.x, self.mouse.y,
                 self.time_warp,
                 self.duration,
                 len(self.paths), self.pathp
             ),
             color=(0.,0.5,0.5,0.5))
     text.x = 100
     text.y = 20
     text.draw()
示例#8
0
    def draw(self):
        if self.stop:
            director.scene.end()

        if self.state == self.SWITCH:
            text = "switch to: %s" % self.number
            label = pyglet.text.Label(text,
                                      font_name=self.font_name,
                                      font_size=self.font_size,
                                      color=(0, 128, 128, 128),
                                      x=20,
                                      y=300)
            label.draw()

        elif self.state in (self.SHOW, self.DRAG):
            self.path.render()
            if self.near:
                c = Circle(self.near.x,
                           self.near.y,
                           width=15,
                           color=(0., 1., 1., 1.))
                c.render()

        elif self.state == self.ANIMATE:
            dt = time.time() - self.anim_start
            bz = self.path.bezier()
            if dt >= self.duration:
                self.state = self.SHOW
            else:
                x, y = bz.at((dt / self.duration)**self.time_warp)
                c = Circle(x + self.path.a.x,
                           y + self.path.a.y,
                           width=45,
                           color=(0., 1., 1., 1.))
                c.render()

        text = '[%i,%i] t**%0.2f d=%0.2f n=%d p=%d' % (
            self.mouse.x, self.mouse.y, self.time_warp, self.duration,
            len(self.paths), self.pathp)
        label = pyglet.text.Label(text,
                                  font_name=self.font_name,
                                  font_size=self.font_size,
                                  color=(0, 128, 128, 128),
                                  x=100,
                                  y=20)
        label.draw()
    def compute(self, cmd):
        assert (len(cmd) == 4)

        obj_name = cmd[1]
        assert (isinstance(obj_name, str))

        obj_type = cmd[2].lower()
        assert (obj_type in ["point", "line", "circle"])

        if obj_type == "point":
            p = Point(obj_name)
            self.register_pt(p)

            computation = self.process_point(cmd[3], unnamed=False)
            assert (not isinstance(computation.val, str))

            c_instr = Compute(p, computation)
            self.instructions.append(c_instr)
        elif obj_type == "line":
            l = Line(obj_name)
            self.register_line(l)

            computation = self.process_line(cmd[3], unnamed=False)
            assert (not isinstance(computation.val, str))

            c_instr = Compute(l, computation)
            self.instructions.append(c_instr)

        elif obj_type == "circle":
            c = Circle(obj_name)
            self.register_circ(c)

            computation = self.process_circle(cmd[3], unnamed=False)
            assert (not isinstance(computation.val, str))

            c_instr = Compute(c, computation)
            self.instructions.append(c_instr)

        else:
            raise RuntimeError("Invalid define type")
    def param(self, cmd):
        assert (len(cmd) == 3 or len(cmd) == 4)

        obj_type = cmd[2].lower()
        assert (obj_type in ["point", "line", "circle"])

        if obj_type == "line":
            l = Line(cmd[1])
            self.register_line(l)

            param_method = "line"
            if len(cmd) == 4:
                param_method = cmd[3]
            pred, args = self.process_param_line(param_method)
            p_instr = Parameterize(l, (pred, args))
            self.instructions.append(p_instr)
        elif obj_type == "circle":
            c = Circle(cmd[1])
            self.register_circ(c)

            param_method = "circle"
            if len(cmd) == 4:
                param_method = cmd[3]
            pred, args = self.process_param_circ(param_method)
            p_instr = Parameterize(c, (pred, args))
            self.instructions.append(p_instr)
        else:
            p = Point(cmd[1])
            self.register_pt(p)

            param_method = "coords"
            if len(cmd) == 4:
                param_method = cmd[3]
            pred, args = self.process_param_point(param_method)
            p_instr = Parameterize(p, (pred, args))
            self.instructions.append(p_instr)
示例#11
0
class Menu:
    def __init__(self,start_screen=None,loader=None):
        self.start_screen = start_screen
        self.loader = loader

        self.current_screen = self.start_screen
        self.pointer = Circle()

        self.enabled = False

    # Returns the menu to its original state, i.e., to the start screen
    def reset(self):
        self.current_screen = self.start_screen

    # Changes between enabled or disabled. When the menu is being disabled,
    # it is also reset
    def swap(self):
        self.enabled = not self.enabled

        # Initialize
        if not self.enabled:
            self.reset()

    # Disable and reset the menu
    def disable(self):
        self.enabled = False
        self.reset()

    # Enable the menu
    def enable(self):
        self.enabled = True

    # Main method: it receives a point in the screen and looks for the button
    # that is being pressed. It then waits for the loader to finish, and activates
    # the action button when required.
    def process(self, point):
        self.pointer.center = point

        # Retrieves the button being pressed
        button = self.current_screen.buttonTouched(point)


        if button:
            # Set the loader center and radius to fit the button coordinates
            self.loader.center = button.getCenter()
            self.loader.loader_radius = button.getRadius()

            # Calls the loader and check whether it has finished
            if self.loader.load():
                # If it has finished, reset the loader and activates the button
                self.loader.reset()
                if isinstance(button, NavigationalButton):
                    self.current_screen = button.navigate() # Navigate!
                elif isinstance(button, ActionButton):
                    button.act() # Act!
        #If no button is being pressed, then reset the loader
        else:
            self.loader.reset()

    def draw(self):
        if self.enabled:
            self.pointer.draw()
            #for button in self.current_screen.buttons:
            #        button.draw()
            self.loader.draw()
            self.current_screen.draw()
示例#12
0
    def render(self):
        c = Circle(self.a[0], self.a[1], width=10, color=(0., .9, 0., 1.))
        c.render()
        c = Circle(self.ac[0], self.ac[1], width=10, color=(0., .9, 0.5, 1.))
        c.render()
        l = Line(self.a, self.ac, stroke=2, color=(0, 1., 1., 1.))
        l.render()

        c = Circle(self.b[0], self.b[1], width=10, color=(0., .9, 1., 1.))
        c.render()
        c = Circle(self.bc[0], self.bc[1], width=10, color=(0., .9, 1., 0.5))
        c.render()
        l = Line(self.b, self.bc, stroke=2, color=(0, 1., 1., 1.))
        l.render()

        steps = 100.0
        bz = self.bezier()
        last = self.a
        for i in range(int(steps)):
            t = (i + 1) / steps
            val = bz.at(t)
            val = val[0] + self.a.x, val[1] + self.a.y

            glBegin(GL_LINES)
            glVertex2f(last[0], last[1])
            glVertex2f(val[0], val[1])
            glEnd()

            last = val
示例#13
0
    def render(self):
        c = Circle(self.a[0], self.a[1], width=10, color=(0.0, 0.9, 0.0, 1.0))
        c.render()
        c = Circle(self.ac[0], self.ac[1], width=10, color=(0.0, 0.9, 0.5, 1.0))
        c.render()
        l = Line(self.a, self.ac, stroke=2, color=(0, 1.0, 1.0, 1.0))
        l.render()

        c = Circle(self.b[0], self.b[1], width=10, color=(0.0, 0.9, 1.0, 1.0))
        c.render()
        c = Circle(self.bc[0], self.bc[1], width=10, color=(0.0, 0.9, 1.0, 0.5))
        c.render()
        l = Line(self.b, self.bc, stroke=2, color=(0, 1.0, 1.0, 1.0))
        l.render()

        steps = 100.0
        bz = self.bezier()
        last = self.a
        for i in range(int(steps)):
            t = (i + 1) / steps
            val = bz.at(t)
            val = val[0] + self.a.x, val[1] + self.a.y

            glBegin(GL_LINES)
            glVertex2f(last[0], last[1])
            glVertex2f(val[0], val[1])
            glEnd()

            last = val
示例#14
0
    def render(self):
        c = Circle(
            self.a[0],self.a[1],
            width=10,color=(0.,.9,0.,1.)
            )
        c.render()
        c = Circle(
            self.ac[0],self.ac[1],
            width=10,color=(0.,.9,0.5,1.)
            )
        c.render()
        l = Line(self.a,self.ac,stroke=2,color=(0,1.,1.,1.))
        l.render()
        
        c = Circle(
            self.b[0],self.b[1],
            width=10,color=(0.,.9,1.,1.)
            )
        c.render()
        c = Circle(
            self.bc[0],self.bc[1],
            width=10,color=(0.,.9,1.,0.5)
            )
        c.render()
        l = Line(self.b,self.bc,stroke=2,color=(0,1.,1.,1.))
        l.render()
        
        steps=100.0
        bz = self.bezier()
        last = self.a
        for i in range(steps):
            t = (i+1)/steps
            next = bz.at( t )
            next = next[0] + self.a.x, next[1] + self.a.y
            
            glBegin(GL_LINES);
            glVertex2f(last[0], last[1]); 
            glVertex2f(next[0], next[1]); 
            glEnd( );

            last = next
示例#15
0
    def __init__(self,
                 x=0,
                 y=0,
                 random=False,
                 show_vision=False,
                 dna=None,
                 **kwargs):
        self.id = uuid.uuid4()
        self.life = 100
        self._alive = True
        self.genes = 15
        self.age = 0
        self.memory_s = []
        self.memory_a = []
        self.all_memory = None
        if kwargs.get('old_memory', None):
            self.all_memory = [x[:] for x in kwargs['old_memory']]
        if not dna:
            layers = randint(2, 100)
            neurons = randint(2, 100)
            iters = randint(2, 100)
            memorysize = randint(2, 100)
            # [Layers, neurons, iters , memory]
            self.dna = [layers, neurons, iters, memorysize]
        else:
            self.dna = dna

        self._hidden_layers = [self.dna[1] for _ in range(self.dna[0])]
        self._max_memory = self.dna[3]
        self.brain = MLPRegressor(activation='logistic',
                                  alpha=1e-05,
                                  batch_size='auto',
                                  beta_1=0.9,
                                  beta_2=0.999,
                                  early_stopping=False,
                                  epsilon=1e-08,
                                  hidden_layer_sizes=self._hidden_layers,
                                  learning_rate='constant',
                                  learning_rate_init=0.001,
                                  max_iter=self.dna[2] * 100,
                                  momentum=0.9,
                                  nesterovs_momentum=True,
                                  power_t=0.5,
                                  random_state=1,
                                  shuffle=True,
                                  solver='adam',
                                  tol=0.0001,
                                  validation_fraction=0.1,
                                  verbose=False,
                                  warm_start=False)

        if random:
            x = randint(0, WIDTH)
            y = randint(0, HEIGHT)
        self.body = Triangle(x=x, y=y, random=False)
        self.vision = Circle(x=x, y=y, radius=VISION_RADIUS)
        self.show_vision = show_vision
        self.position = Vector(x, y)
        self.velocity = Vector(0, 0)
        self.aceleration = Vector(0, 0)
        self.mass = 10
        self.visible_objects = []
        self.last_action = [0, 0, 0]

        if self.all_memory is None:
            start_sensor = [[randint(-5, 5), randint(-5, 5)]
                            for _ in range(10)]
            start_out = [[randint(0, 1),
                          randint(-5, 5),
                          randint(-5, 5)] for _ in range(10)]
            self.all_memory = [start_sensor, start_out]
        else:
            if np.random.random() < RANDOM_MEMORY:
                # creating some random memories
                self.all_memory[0] += [[randint(-5, 5), randint(-5, 5)]]
                self.all_memory[1] += [[
                    randint(0, 1),
                    randint(-5, 5),
                    randint(-5, 5)
                ]]
            start_sensor = self.all_memory[0]
            start_out = self.all_memory[1]
        try:
            self.brain.fit(start_sensor, start_out)
        except:
            print(start_sensor, start_out)
            raise ValueError
示例#16
0
class Animal:
    def __init__(self,
                 x=0,
                 y=0,
                 random=False,
                 show_vision=False,
                 dna=None,
                 **kwargs):
        self.id = uuid.uuid4()
        self.life = 100
        self._alive = True
        self.genes = 15
        self.age = 0
        self.memory_s = []
        self.memory_a = []
        self.all_memory = None
        if kwargs.get('old_memory', None):
            self.all_memory = [x[:] for x in kwargs['old_memory']]
        if not dna:
            layers = randint(2, 100)
            neurons = randint(2, 100)
            iters = randint(2, 100)
            memorysize = randint(2, 100)
            # [Layers, neurons, iters , memory]
            self.dna = [layers, neurons, iters, memorysize]
        else:
            self.dna = dna

        self._hidden_layers = [self.dna[1] for _ in range(self.dna[0])]
        self._max_memory = self.dna[3]
        self.brain = MLPRegressor(activation='logistic',
                                  alpha=1e-05,
                                  batch_size='auto',
                                  beta_1=0.9,
                                  beta_2=0.999,
                                  early_stopping=False,
                                  epsilon=1e-08,
                                  hidden_layer_sizes=self._hidden_layers,
                                  learning_rate='constant',
                                  learning_rate_init=0.001,
                                  max_iter=self.dna[2] * 100,
                                  momentum=0.9,
                                  nesterovs_momentum=True,
                                  power_t=0.5,
                                  random_state=1,
                                  shuffle=True,
                                  solver='adam',
                                  tol=0.0001,
                                  validation_fraction=0.1,
                                  verbose=False,
                                  warm_start=False)

        if random:
            x = randint(0, WIDTH)
            y = randint(0, HEIGHT)
        self.body = Triangle(x=x, y=y, random=False)
        self.vision = Circle(x=x, y=y, radius=VISION_RADIUS)
        self.show_vision = show_vision
        self.position = Vector(x, y)
        self.velocity = Vector(0, 0)
        self.aceleration = Vector(0, 0)
        self.mass = 10
        self.visible_objects = []
        self.last_action = [0, 0, 0]

        if self.all_memory is None:
            start_sensor = [[randint(-5, 5), randint(-5, 5)]
                            for _ in range(10)]
            start_out = [[randint(0, 1),
                          randint(-5, 5),
                          randint(-5, 5)] for _ in range(10)]
            self.all_memory = [start_sensor, start_out]
        else:
            if np.random.random() < RANDOM_MEMORY:
                # creating some random memories
                self.all_memory[0] += [[randint(-5, 5), randint(-5, 5)]]
                self.all_memory[1] += [[
                    randint(0, 1),
                    randint(-5, 5),
                    randint(-5, 5)
                ]]
            start_sensor = self.all_memory[0]
            start_out = self.all_memory[1]
        try:
            self.brain.fit(start_sensor, start_out)
        except:
            print(start_sensor, start_out)
            raise ValueError

    def rotate(self):
        angle = self.position.angle
        self.body.rotate(angle=angle)

    def move(self, vel):
        self.spend_energy(0.1)
        self.velocity = vel
        self.position += vel
        if self.position.x >= WIDTH:
            self.position.x = WIDTH
        if self.position.y >= HEIGHT:
            self.position.y = HEIGHT
        if self.position.x <= 0:
            self.position.x = 0
        if self.position.y <= 0:
            self.position.y = 0
        self.body.move(self.position, vel)

    def check_near_food(self, foods):
        creature_path = pltpath.Path(
            [*np.array_split(self.vision.vertex, self.vision.points)])
        food_positions = [food.body.vertex for food in foods]
        collide = creature_path.contains_points(food_positions)
        if any(collide):
            food_positions = np.array(list(foods))
            near_food = food_positions[collide]
            self.visible_objects = near_food
        else:
            self.visible_objects = []
        # print(self.visible_objects)

    def check_collision(self, food_manager):
        foods = food_manager.foods.values()
        body_path = pltpath.Path([*np.array_split(self.body.vertex2D, 3)])
        food_positions = [food.body.vertex for food in foods]
        collide = body_path.contains_points(food_positions)
        if any(collide):
            food_positions = np.array(list(foods))
            target_food = food_positions[collide]
            energy = food_manager.consume_food(target_food[0].id)
            self.eat(energy)
        else:
            target_food = []
        # print(self.life)

    def breath(self):
        self.spend_energy(0.1)

    def eat(self, energy):
        self.spend_energy(0.1)
        self.life += energy
        max_m = self._max_memory * 2
        if len(self.memory_s) < max_m and len(self.memory_a) < max_m:
            self.memory_s += [
                list(self.visible_objects[0].position - self.position)
            ]
            self.memory_a += [self.last_action]

    def spend_energy(self, energy):
        self.life -= energy

    def update(self, food_manager):
        self.breath()
        foods = food_manager.foods.values()
        if self.show_vision:
            self.vision.update(self.position[0], self.position[1])
            pyglet.graphics.draw(*self.vision.vertex_list)
        self.check_near_food(foods)
        self.check_collision(food_manager)
        saida = None
        if any(self.visible_objects):
            saida = self.brain.predict([self.visible_objects[0].position._v])
        self.take_action(saida)

    def take_action(self, trial):
        actions = {
            0: self.walk,
            1: self.think,
        }
        if trial is not None:
            trial = np.round(trial)
            # print(trial)
            try:
                choice = actions.get(int(trial[0][0]), self.walk)
                choice(trial[0][1:])
            except:
                choice = actions[0]
                choice()
                traceback.print_exc()
                raise ValueError
        else:  # if no trial, walk
            choice = actions[0]
            choice()

    def walk(self, direction=None):
        self.spend_energy(0.1)

        if direction is None:
            acc = Vector(randint(-MAX_SPEED, MAX_SPEED),
                         randint(-MAX_SPEED, MAX_SPEED))
        else:
            acc = Vector(*direction)
        if self.velocity.x >= MAX_SPEED and acc.x < 0:
            self.velocity.x += acc.x
        elif self.velocity.x <= -MAX_SPEED and acc.x > 0:
            self.velocity.x += acc.x
        if self.velocity.y >= MAX_SPEED and acc.y < 0:
            self.velocity.y += acc.y
        elif self.velocity.y <= -MAX_SPEED and acc.y > 0:
            self.velocity.y += acc.y
        if -MAX_SPEED <= self.velocity.x <= MAX_SPEED:
            self.velocity.x += acc.x
        if -MAX_SPEED <= self.velocity.y <= MAX_SPEED:
            self.velocity.y += acc.y
        self.last_action = [0, acc[0], acc[1]]
        self.move(self.velocity)
        # print(f" velocidade: {self.velocity}, acc: {acc}")

    def think(self, *args):
        # self.think_count += 1
        self.spend_energy(0.1)
        self.last_action = [1, 0, 0]
        if any(self.memory_a) or any(self.memory_s):
            # print("memoria de entrada", self.Memory_s)
            # print("memoria de saida", self.Memory_a)
            try:
                self.brain.partial_fit(self.memory_s, self.memory_a)
            except:
                traceback.print_exc()
                print("Memoria", self.memory_a, self.memory_s)
                raise ValueError
            self.remember()
            self.memory_s = []
            self.memory_a = []

    def remember(self):

        # put good lessons on memory
        self.all_memory[0] += self.memory_s
        self.all_memory[1] += self.memory_a

        # check memory capacity, forget the long past
        if self.all_memory:
            while len(self.all_memory[0]) > self._max_memory:
                self.all_memory[0].pop(0)
            while len(self.all_memory[1]) > self._max_memory:
                self.all_memory[1].pop(0)
    def process_constraint(self, constraint):
        assert (isinstance(constraint, tuple))

        negate = (isinstance(constraint[0], str)
                  and constraint[0].lower() == "not")
        if negate:
            constraint = constraint[1]

        pred = constraint[0].lower()
        args = constraint[1:]

        args = [self.process_term(t) for t in args]

        ps = [t for t in args if isinstance(t, Point)]
        ls = [t for t in args if isinstance(t, Line)]
        cs = [t for t in args if isinstance(t, Circle)]
        ns = [t for t in args if isinstance(t, Num)]

        # Validate
        if pred in ["circumcenter", "orthocenter", "incenter", "centroid"]:
            assert (len(args) == 4)
            assert (all([isinstance(t, Point) for t in args]))
        elif pred in ["con-tri", "sim-tri"]:
            assert (len(args) == 6)
            assert (all([isinstance(t, Point) for t in args]))
        elif pred == "coll":
            assert (len(args) == 3)
            assert (all([isinstance(t, Point) for t in args]))
        elif pred == "concur":
            assert (len(args) == 3)
            assert (all([isinstance(t, Line) for t in args]))
        elif pred == "cong":
            assert (len(args) == 4)
            assert (all([isinstance(t, Point) for t in args]))
        elif pred == "cycl":
            assert (len(args) >= 4)
            assert (all([isinstance(t, Point) for t in args]))
            self.unnamed_circles.append(Circle(FuncInfo("c3", args[:3])))
        elif pred == "eq" or pred == "=":
            assert (len(args) == 2)
            if all([isinstance(t, Num) for t in args]):
                pred = "eq-n"
            elif all([isinstance(t, Point) for t in args]):
                pred = "eq-p"
            elif all([isinstance(t, Line) for t in args]):
                pred = "eq-l"
            else:
                raise RuntimeError("Invalid usage of eq")
        elif pred == "foot":
            assert (len(args) == 3)
            assert (isinstance(args[0], Point) and isinstance(args[1], Point))
            assert (isinstance(args[2], Line))
        elif pred == "gt" or pred == ">":
            pred = "gt"
            assert (len(args) == 2)
            assert (all([isinstance(t, Num) for t in args]))
        elif pred == "gte" or pred == ">=":
            pred = "gte"
            assert (len(args) == 2)
            assert (all([isinstance(t, Num) for t in args]))
        elif pred == "lt" or pred == "<":
            pred = "lt"
            assert (len(args) == 2)
            assert (all([isinstance(t, Num) for t in args]))
        elif pred == "lte" or pred == "<=":
            pred = "lte"
            assert (len(args) == 2)
            assert (all([isinstance(t, Num) for t in args]))
        # elif pred == "eq-angle":
        # assert(len(args) == 8)
        # assert(all([isinstance(t, Point) for t in args]))
        elif pred == "eq-ratio":
            assert (len(args) == 8)
            assert (all([isinstance(t, Point) for t in args]))
        elif pred == "i-bisector":
            assert (len(args) == 4)
            assert (all([isinstance(t, Point) for t in args]))
        elif pred == "inter-ll":
            assert (len(args) == 5)
            assert (all([isinstance(t, Point) for t in args]))
        elif pred == "in-poly":
            assert (len(args) >= 4)
            assert (all([isinstance(t, Point) for t in args]))
        elif pred == "midp":
            assert (len(args) == 3)
            assert (all([isinstance(t, Point) for t in args]))
        elif pred == "on-line":
            assert (len(args) == 2)
            assert (isinstance(args[0], Point) and isinstance(args[1], Line))
        elif pred in ["on-seg", "on-ray"]:  # no more between
            assert (len(args) == 3)
            assert (all([isinstance(t, Point) for t in args]))
        elif pred == "on-circ":
            assert (len(args) == 2)
            assert (isinstance(args[0], Point) and isinstance(args[1], Circle))
        elif pred == "opp-sides":
            assert (len(args) == 3)
            assert (isinstance(args[0], Point) and isinstance(args[1], Point))
            assert (isinstance(args[2], Line))
        elif pred == "para" or pred == "perp":
            assert (len(args) == 2)
            assert (all([isinstance(t, Line) for t in args]))
        elif pred in ["right", "right-tri"]:
            assert (len(args) == 3)
            assert (all([isinstance(t, Point) for t in args]))
        elif pred == "reflect-pl":
            assert (len(args) == 4)
            assert (all([isinstance(t, Point) for t in args]))
        elif pred == "same-side":
            assert (len(args) == 3)
            assert (isinstance(args[0], Point) and isinstance(args[1], Point))
            assert (isinstance(args[2], Line))
        elif pred == "tangent-cc":
            assert (len(args) == 2)
            assert (all([isinstance(t, Circle) for t in args]))
        elif pred == "tangent-lc":
            assert (len(args) == 2)
            assert (isinstance(args[0], Line) and isinstance(args[1], Circle))
        elif pred == "tangent-at-cc":
            assert (len(args) == 3)
            assert (isinstance(args[0], Point))
            assert (isinstance(args[1], Circle)
                    and isinstance(args[2], Circle))
        elif pred == "tangent-at-lc":
            assert (len(args) == 3)
            assert (isinstance(args[0], Point))
            assert (isinstance(args[1], Line) and isinstance(args[2], Circle))
        else:
            raise NotImplementedError(
                f"[process_constraint] Unsupported pred {pred}")

        return negate, pred, args