| 85 | |
| 86 | |
| 87 | class Constraint(object): |
| 88 | |
| 89 | tags: Tuple[str, ...] |
| 90 | args: Tuple[Edge, ...] |
| 91 | kind: ConstraintKind |
| 92 | param: Any |
| 93 | |
| 94 | def __init__( |
| 95 | self, |
| 96 | tags: Tuple[str, ...], |
| 97 | args: Tuple[Edge, ...], |
| 98 | kind: ConstraintKind, |
| 99 | param: Any = None, |
| 100 | ): |
| 101 | |
| 102 | # validate based on the solver provided spec |
| 103 | if kind not in ConstraintInvariants: |
| 104 | raise ValueError(f"Unknown constraint {kind}.") |
| 105 | |
| 106 | arity, types, param_type, converter = ConstraintInvariants[kind] |
| 107 | |
| 108 | if arity != len(tags): |
| 109 | raise ValueError( |
| 110 | f"Invalid number of entities for constraint {kind}. Provided {len(tags)}, required {arity}." |
| 111 | ) |
| 112 | |
| 113 | if any(e.geomType() not in types for e in args): |
| 114 | raise ValueError( |
| 115 | f"Unsupported geometry types {[e.geomType() for e in args]} for constraint {kind}." |
| 116 | ) |
| 117 | |
| 118 | if not instance_of(param, param_type): |
| 119 | raise ValueError( |
| 120 | f"Unsupported argument types {get_origin(param)}, required {param_type}." |
| 121 | ) |
| 122 | |
| 123 | # if all is fine store everything and possibly convert the params |
| 124 | self.tags = tags |
| 125 | self.args = args |
| 126 | self.kind = kind |
| 127 | self.param = tcast(Any, converter)(param) if converter else param |
| 128 | |
| 129 | |
| 130 | # %% Sketch |