optimizing a gate level bcm to the end of the earth and back
1"""
2Verification module for BCD to 7-segment decoder synthesis results.
3
4Ensures synthesized expressions produce correct outputs for all valid BCD inputs.
5"""
6
7from .truth_tables import SEGMENT_MINTERMS, SEGMENT_NAMES
8from .quine_mccluskey import Implicant
9from .solver import SynthesisResult
10
11
12def evaluate_implicant(impl: Implicant, a: int, b: int, c: int, d: int) -> bool:
13 """Evaluate an implicant on a specific input."""
14 minterm = (a << 3) | (b << 2) | (c << 1) | d
15 return impl.covers(minterm)
16
17
18def evaluate_sop(implicants: list[Implicant], a: int, b: int, c: int, d: int) -> bool:
19 """Evaluate a sum-of-products on a specific input (OR of AND terms)."""
20 return any(evaluate_implicant(impl, a, b, c, d) for impl in implicants)
21
22
23def verify_result(result: SynthesisResult) -> tuple[bool, list[str]]:
24 """
25 Verify that a synthesis result produces correct outputs for all BCD inputs.
26
27 Args:
28 result: The synthesis result to verify
29
30 Returns:
31 Tuple of (all_correct, list of error messages)
32 """
33 errors = []
34
35 for segment in SEGMENT_NAMES:
36 if segment not in result.implicants_by_output:
37 continue
38
39 implicants = result.implicants_by_output[segment]
40 expected_on = set(SEGMENT_MINTERMS[segment])
41
42 for digit in range(10): # Valid BCD: 0-9
43 a = (digit >> 3) & 1
44 b = (digit >> 2) & 1
45 c = (digit >> 1) & 1
46 d = digit & 1
47
48 actual = evaluate_sop(implicants, a, b, c, d)
49 expected = digit in expected_on
50
51 if actual != expected:
52 errors.append(
53 f"Segment {segment}, digit {digit}: "
54 f"expected {expected}, got {actual}"
55 )
56
57 return len(errors) == 0, errors
58
59
60def print_truth_table_comparison(result: SynthesisResult):
61 """Print truth table comparing expected vs actual outputs."""
62 print("Truth Table Verification")
63 print("=" * 60)
64 print(f"{'Digit':>5} | {'ABCD':>4} | Expected | Actual | Match")
65 print("-" * 60)
66
67 all_match = True
68
69 for digit in range(10):
70 a = (digit >> 3) & 1
71 b = (digit >> 2) & 1
72 c = (digit >> 1) & 1
73 d = digit & 1
74
75 expected = ""
76 actual = ""
77 match_str = ""
78
79 for segment in SEGMENT_NAMES:
80 exp = "1" if digit in SEGMENT_MINTERMS[segment] else "0"
81 expected += exp
82
83 if segment in result.implicants_by_output:
84 implicants = result.implicants_by_output[segment]
85 act = "1" if evaluate_sop(implicants, a, b, c, d) else "0"
86 else:
87 act = "?"
88
89 actual += act
90 match_str += "." if exp == act else "X"
91 if exp != act:
92 all_match = False
93
94 print(f"{digit:>5} | {a}{b}{c}{d} | {expected:>9} | {actual:>9} | {match_str}")
95
96 print("-" * 60)
97 print(f"All correct: {all_match}")
98 return all_match
99
100
101if __name__ == "__main__":
102 from .solver import BCDTo7SegmentSolver
103
104 solver = BCDTo7SegmentSolver()
105 result = solver.solve()
106
107 print("\n")
108 correct, errors = verify_result(result)
109
110 if correct:
111 print("Verification PASSED: All outputs correct!")
112 else:
113 print("Verification FAILED:")
114 for err in errors:
115 print(f" {err}")
116
117 print("\n")
118 print_truth_table_comparison(result)