Solve the constraints.
(self, verbosity: int = 0)
| 448 | return self |
| 449 | |
| 450 | def solve(self, verbosity: int = 0) -> Self: |
| 451 | """ |
| 452 | Solve the constraints. |
| 453 | """ |
| 454 | |
| 455 | # Get all entities and number them. First entity is marked as locked |
| 456 | ents = {} |
| 457 | |
| 458 | i = 0 |
| 459 | locked: List[int] = [] |
| 460 | |
| 461 | for c in self.constraints: |
| 462 | for name in c.objects: |
| 463 | if name not in ents: |
| 464 | ents[name] = i |
| 465 | i += 1 |
| 466 | if (c.kind == "Fixed" or name == self.name) and ents[ |
| 467 | name |
| 468 | ] not in locked: |
| 469 | locked.append(ents[name]) |
| 470 | |
| 471 | # Lock the first occurring entity if needed. |
| 472 | if not locked: |
| 473 | unary_objects = [ |
| 474 | c.objects[0] |
| 475 | for c in self.constraints |
| 476 | if instance_of(c.kind, UnaryConstraintKind) |
| 477 | ] |
| 478 | binary_objects = [ |
| 479 | c.objects[0] |
| 480 | for c in self.constraints |
| 481 | if instance_of(c.kind, BinaryConstraintKind) |
| 482 | ] |
| 483 | for b in binary_objects: |
| 484 | if b not in unary_objects: |
| 485 | locked.append(ents[b]) |
| 486 | break |
| 487 | |
| 488 | # Lock the first occurring entity if needed. |
| 489 | if not locked: |
| 490 | locked.append(0) |
| 491 | |
| 492 | locs = [self.objects[n].loc for n in ents] |
| 493 | |
| 494 | # construct the constraint mapping |
| 495 | constraints = [] |
| 496 | for c in self.constraints: |
| 497 | ixs = tuple(ents[obj] for obj in c.objects) |
| 498 | pods = c.toPODs() |
| 499 | |
| 500 | for pod in pods: |
| 501 | constraints.append((ixs, pod)) |
| 502 | |
| 503 | # check if any constraints were specified |
| 504 | if not constraints: |
| 505 | raise ValueError("At least one constraint required") |
| 506 | |
| 507 | # check if at least two entities are present |