Skip to content

Commit 621e19b

Browse files
committed
fix: removed convenience functions for testing
1 parent 7ee4996 commit 621e19b

4 files changed

Lines changed: 36 additions & 203 deletions

File tree

evaluation_function/correction/README.md

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,17 @@
22

33
Compares student FSAs against expected FSAs, leveraging the validation module for detailed feedback.
44

5-
## Architecture
5+
## Exports
66

7-
The correction module is a wrapper around the validation module. All detailed "why" feedback comes from `are_isomorphic()` in `validation.py`.
7+
```python
8+
from evaluation_function.correction import (
9+
analyze_fsa_correction, # Main pipeline
10+
check_minimality, # Check if FSA is minimal
11+
CorrectionResult, # Result model
12+
)
13+
```
814

9-
## Pipeline (4 Steps)
15+
## Pipeline
1016

1117
```
1218
┌─────────────────────────────────────────────────────────────────┐
@@ -23,46 +29,42 @@ The correction module is a wrapper around the validation module. All detailed "w
2329
│ └── get_structured_info_of_fsa() → StructuralInfo │
2430
├─────────────────────────────────────────────────────────────────┤
2531
│ Step 4: Language Equivalence │
26-
│ └── fsas_accept_same_language() │
27-
│ └── are_isomorphic() provides detailed feedback: │
28-
│ • State acceptance errors with ElementHighlight │
29-
│ • Transition errors with ElementHighlight │
30-
│ • Alphabet mismatches │
31-
│ • State count differences │
32+
│ └── fsas_accept_same_language() → are_isomorphic() │
33+
│ Provides detailed feedback with ElementHighlight │
3234
├─────────────────────────────────────────────────────────────────┤
3335
│ OUTPUT: CorrectionResult │
3436
│ ├── is_equivalent: bool │
3537
│ ├── is_isomorphic: bool │
3638
│ ├── is_minimal: Optional[bool] │
3739
│ ├── validation_errors: List[ValidationError] │
38-
│ ├── equivalence_errors: List[ValidationError] (from isomorphism)
40+
│ ├── equivalence_errors: List[ValidationError]
3941
│ └── structural_info: StructuralInfo │
42+
│ │
43+
│ Methods: │
44+
│ ├── .model_dump() → dict │
45+
│ ├── .to_fsa_feedback() → FSAFeedback │
46+
│ └── .get_language_comparison() → LanguageComparison │
4047
└─────────────────────────────────────────────────────────────────┘
4148
```
4249

4350
## Usage
4451

4552
```python
46-
from evaluation_function.correction import analyze_fsa_correction, get_fsa_feedback
53+
from evaluation_function.correction import analyze_fsa_correction, check_minimality
4754

48-
# Full analysis
55+
# Compare two FSAs
4956
result = analyze_fsa_correction(student_fsa, expected_fsa, check_minimality=True)
50-
print(result.is_equivalent)
51-
print(result.equivalence_errors) # Detailed errors from are_isomorphic()
57+
58+
# Check result
59+
result.is_equivalent # bool
60+
result.equivalence_errors # List[ValidationError] with ElementHighlight
5261

5362
# For UI
54-
feedback = get_fsa_feedback(student_fsa, expected_fsa)
55-
print(feedback.summary)
56-
print(feedback.errors) # List[ValidationError] with ElementHighlight
57-
```
63+
result.to_fsa_feedback() # FSAFeedback schema
5864

59-
## Functions
65+
# As dict
66+
result.model_dump() # dict
6067

61-
| Function | Returns | Description |
62-
|----------|---------|-------------|
63-
| `analyze_fsa_correction` | `CorrectionResult` | Full comparison pipeline |
64-
| `get_fsa_feedback` | `FSAFeedback` | Structured feedback for UI |
65-
| `get_correction_feedback` | `dict` | Same as above, as dict |
66-
| `check_fsa_properties` | `dict` | Properties of single FSA |
67-
| `check_minimality` | `bool` | Is FSA minimal? |
68-
| `quick_equivalence_check` | `tuple` | Fast equivalence check |
68+
# Check minimality only
69+
check_minimality(fsa) # bool
70+
```
Lines changed: 6 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,21 @@
1-
"""
2-
FSA Correction Module
3-
4-
Compares student FSAs against expected FSAs using the validation module.
5-
6-
Pipeline (4 Steps):
7-
1. Structural Validation - is_valid_fsa
8-
2. Minimality Check - check_minimality (if required)
9-
3. Structural Analysis - get_structured_info_of_fsa
10-
4. Language Equivalence - fsas_accept_same_language (-> are_isomorphic)
1+
"""FSA Correction Module
112
12-
The validation module's are_isomorphic() provides all "why" feedback:
13-
- State acceptance errors with ElementHighlight
14-
- Transition errors (missing/extra/wrong) with ElementHighlight
15-
- Alphabet and state count mismatches
3+
Compares student FSAs against expected FSAs.
164
17-
Main Functions:
18-
- analyze_fsa_correction: Full pipeline (FSA vs FSA -> CorrectionResult)
19-
- get_fsa_feedback: Returns FSAFeedback schema (for UI)
20-
- check_fsa_properties: Structural properties of single FSA
21-
- check_minimality: Verify FSA is minimal
5+
Exports:
6+
- analyze_fsa_correction: Main pipeline (FSA vs FSA -> CorrectionResult)
7+
- check_minimality: Check if FSA is minimal
8+
- CorrectionResult: Result model with .to_fsa_feedback(), .model_dump()
229
"""
2310

2411
from .correction import (
25-
# Main pipeline
2612
analyze_fsa_correction,
27-
get_correction_feedback,
28-
get_fsa_feedback,
29-
check_fsa_properties,
3013
check_minimality,
31-
quick_equivalence_check,
32-
33-
# Result class
3414
CorrectionResult,
3515
)
3616

3717
__all__ = [
3818
"analyze_fsa_correction",
39-
"get_correction_feedback",
40-
"get_fsa_feedback",
41-
"check_fsa_properties",
4219
"check_minimality",
43-
"quick_equivalence_check",
4420
"CorrectionResult",
4521
]

evaluation_function/correction/correction.py

Lines changed: 1 addition & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,9 @@
2424
from ..schemas import FSA, ValidationError, ErrorCode
2525
from ..schemas.result import LanguageComparison, StructuralInfo, FSAFeedback
2626

27-
# Validation imports - these provide all the functionality we need
27+
# Validation imports
2828
from ..validation.validation import (
2929
is_valid_fsa,
30-
is_deterministic,
31-
is_complete,
32-
find_unreachable_states,
33-
find_dead_states,
3430
fsas_accept_same_language,
3531
get_structured_info_of_fsa,
3632
)
@@ -221,104 +217,3 @@ def analyze_fsa_correction(
221217

222218
result.summary = f"Languages differ: {', '.join(error_types) if error_types else f'{len(equiv_errors)} issue(s)'}"
223219
return result
224-
225-
226-
# =============================================================================
227-
# Convenience Functions
228-
# =============================================================================
229-
230-
def get_correction_feedback(
231-
student_fsa: FSA,
232-
expected_fsa: FSA,
233-
check_minimality: bool = False
234-
) -> dict:
235-
"""Returns correction analysis as dict."""
236-
result = analyze_fsa_correction(student_fsa, expected_fsa, check_minimality)
237-
return result.model_dump()
238-
239-
240-
def get_fsa_feedback(
241-
student_fsa: FSA,
242-
expected_fsa: FSA,
243-
check_minimality: bool = False
244-
) -> FSAFeedback:
245-
"""Returns structured FSAFeedback schema (recommended for UI)."""
246-
result = analyze_fsa_correction(student_fsa, expected_fsa, check_minimality)
247-
return result.to_fsa_feedback()
248-
249-
250-
def check_fsa_properties(fsa: FSA) -> dict:
251-
"""Get FSA properties using validation functions."""
252-
result = {
253-
"is_valid": True,
254-
"is_deterministic": True,
255-
"is_complete": True,
256-
"is_minimal": True,
257-
"validation_errors": [],
258-
"determinism_errors": [],
259-
"completeness_errors": [],
260-
"unreachable_states": [],
261-
"dead_states": [],
262-
"structural_info": None
263-
}
264-
265-
validation_errors = is_valid_fsa(fsa)
266-
if validation_errors:
267-
result["is_valid"] = False
268-
result["validation_errors"] = [e.model_dump() for e in validation_errors]
269-
return result
270-
271-
det_errors = is_deterministic(fsa)
272-
result["is_deterministic"] = len(det_errors) == 0
273-
result["determinism_errors"] = [e.model_dump() for e in det_errors]
274-
275-
if result["is_deterministic"]:
276-
comp_errors = is_complete(fsa)
277-
result["is_complete"] = len(comp_errors) == 0
278-
result["completeness_errors"] = [e.model_dump() for e in comp_errors]
279-
result["is_minimal"] = check_minimality(fsa)
280-
else:
281-
result["is_complete"] = False
282-
result["is_minimal"] = False
283-
284-
result["unreachable_states"] = [
285-
e.highlight.state_id for e in find_unreachable_states(fsa)
286-
if e.highlight and e.highlight.state_id
287-
]
288-
result["dead_states"] = [
289-
e.highlight.state_id for e in find_dead_states(fsa)
290-
if e.highlight and e.highlight.state_id
291-
]
292-
result["structural_info"] = get_structured_info_of_fsa(fsa).model_dump()
293-
294-
return result
295-
296-
297-
def quick_equivalence_check(
298-
student_fsa: FSA,
299-
expected_fsa: FSA
300-
) -> Tuple[bool, Optional[str], Optional[str]]:
301-
"""
302-
Quick equivalence check.
303-
304-
Returns:
305-
(are_equivalent, counterexample_hint, hint_type)
306-
"""
307-
if is_valid_fsa(student_fsa) or is_valid_fsa(expected_fsa):
308-
return False, None, None
309-
310-
equiv_errors = fsas_accept_same_language(student_fsa, expected_fsa)
311-
if not equiv_errors:
312-
return True, None, None
313-
314-
# Extract hint from first error
315-
first_error = equiv_errors[0]
316-
hint = first_error.message
317-
hint_type = None
318-
319-
if "accepting" in hint.lower():
320-
hint_type = "acceptance_error"
321-
elif "transition" in hint.lower():
322-
hint_type = "transition_error"
323-
324-
return False, hint, hint_type

evaluation_function/test/test_correction.py

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,7 @@
1212
from evaluation_function.correction import (
1313
CorrectionResult,
1414
analyze_fsa_correction,
15-
get_correction_feedback,
16-
get_fsa_feedback,
17-
check_fsa_properties,
1815
check_minimality,
19-
quick_equivalence_check,
2016
)
2117

2218

@@ -164,42 +160,6 @@ def test_get_language_comparison(self, dfa_accepts_a, equivalent_dfa):
164160
assert comparison.are_equivalent is True
165161

166162

167-
# =============================================================================
168-
# Test Convenience Functions
169-
# =============================================================================
170-
171-
class TestConvenienceFunctions:
172-
"""Test convenience functions."""
173-
174-
def test_get_correction_feedback(self, dfa_accepts_a, equivalent_dfa):
175-
feedback = get_correction_feedback(dfa_accepts_a, equivalent_dfa)
176-
assert isinstance(feedback, dict)
177-
assert feedback["is_equivalent"] is True
178-
179-
def test_get_fsa_feedback(self, dfa_accepts_a, equivalent_dfa):
180-
feedback = get_fsa_feedback(dfa_accepts_a, equivalent_dfa)
181-
assert isinstance(feedback, FSAFeedback)
182-
183-
def test_check_fsa_properties(self, dfa_accepts_a):
184-
props = check_fsa_properties(dfa_accepts_a)
185-
assert props["is_valid"] is True
186-
assert props["is_deterministic"] is True
187-
assert props["is_complete"] is True
188-
189-
def test_check_fsa_properties_unreachable(self, dfa_with_unreachable):
190-
props = check_fsa_properties(dfa_with_unreachable)
191-
assert "unreachable" in props["unreachable_states"]
192-
193-
def test_quick_equivalence_check_equal(self, dfa_accepts_a, equivalent_dfa):
194-
is_equiv, hint, hint_type = quick_equivalence_check(dfa_accepts_a, equivalent_dfa)
195-
assert is_equiv is True
196-
197-
def test_quick_equivalence_check_different(self, dfa_accepts_a, dfa_accepts_a_or_b):
198-
is_equiv, hint, hint_type = quick_equivalence_check(dfa_accepts_a, dfa_accepts_a_or_b)
199-
assert is_equiv is False
200-
assert hint is not None
201-
202-
203163
# =============================================================================
204164
# Test Invalid FSAs
205165
# =============================================================================

0 commit comments

Comments
 (0)