We often require our cell complexes to satisfy geometric constraints. The validation system provides modular, extensible validation for embedded cell complexes to ensure they represent proper embeddings in Euclidean space.
The validation system distinguishes between two types of rules:
- Structural Rules (always checked): Basic requirements like vertex counts and dimension validity
- Geometric Rules (optional): Embedding properties like non-intersecting edges and faces
The validation system consists of several components:
- Base Classes: Abstract interfaces for validation rules and results
- Validation Rules: Concrete implementations for specific validation checks
- Validator: Main orchestrator that manages and applies rules
- DimensionValidityRule: Ensures cell dimensions are non-negative
- VertexCountRule: Validates correct vertex counts for cell dimensions
- 0-cells must have exactly 1 vertex
- 1-cells must have exactly 2 vertices
- k-cells (k ≥ 2) must have at least 3 vertices
- EdgeInteriorRule: Ensures no vertices lie on edge interiors
- FaceInteriorRule: Ensures no vertices lie inside face interiors
- SelfIntersectionRule: Validates that face edges don't self-intersect
- BoundaryEdgeRule: Ensures required boundary edges exist for faces
from ect import EmbeddedComplex
# Enable validation during construction
K = EmbeddedComplex(validate_embedding=True)
# Or enable/disable later
K.enable_embedding_validation(tol=1e-10)
K.disable_embedding_validation()
# Override per operation
K.add_cell(vertices, dim=2, check=True)You can create custom validation rules by inheriting from ValidationRule:
from ect.validation import ValidationRule, ValidationResult
class MyCustomRule(ValidationRule):
@property
def name(self) -> str:
return "My Custom Rule"
@property
def is_structural(self) -> bool:
return False # Geometric rule
def applies_to_dimension(self, dim: int) -> bool:
return dim == 2 # Only for 2-cells
def validate(self, cell_coords, all_coords, cell_indices, all_indices, dim):
# Your validation logic here
if some_condition:
return ValidationResult.valid()
else:
return ValidationResult.invalid("Validation failed")
# Add to validator
K.get_validator().add_rule(MyCustomRule()).. automodule:: ect.validation
:members:
.. automodule:: ect.validation.base
:members:
:show-inheritance:
.. automodule:: ect.validation.rules
:members:
:show-inheritance:
.. automodule:: ect.validation.validator
:members:
:show-inheritance: