optimizing a gate level bcm to the end of the earth and back
1"""Command-line interface for BCD to 7-segment optimization."""
2
3import argparse
4import sys
5
6from .solver import BCDTo7SegmentSolver
7from .truth_tables import print_truth_table
8from .export import (
9 to_verilog, to_c_code, to_equations, to_dot,
10 to_verilog_exact, to_c_exact, to_dot_exact,
11)
12
13
14def main():
15 parser = argparse.ArgumentParser(
16 description="Optimize BCD to 7-segment decoder gate inputs",
17 formatter_class=argparse.RawDescriptionHelpFormatter,
18 epilog="""
19Examples:
20 bcd-optimize Run with default settings
21 bcd-optimize --target 20 Try to beat 20 gate inputs
22 bcd-optimize --exact Use SAT-based exact synthesis
23 bcd-optimize --truth-table Show the BCD truth table
24 bcd-optimize --format verilog Output as Verilog module
25 bcd-optimize --format c Output as C function
26 bcd-optimize --format dot Output as Graphviz DOT (render with: dot -Tpng)
27 """,
28 )
29
30 parser.add_argument(
31 "--target",
32 type=int,
33 default=61,
34 help="Target gate input count to beat (default: 61, the no-sharing baseline)",
35 )
36 parser.add_argument(
37 "--exact",
38 action="store_true",
39 help="Use SAT-based exact synthesis (slower but optimal)",
40 )
41 parser.add_argument(
42 "--truth-table",
43 action="store_true",
44 help="Print the BCD to 7-segment truth table and exit",
45 )
46 parser.add_argument(
47 "--format", "-f",
48 choices=["text", "verilog", "c", "equations", "dot"],
49 default="text",
50 help="Output format (default: text)",
51 )
52 parser.add_argument(
53 "--verbose", "-v",
54 action="store_true",
55 help="Verbose output",
56 )
57
58 args = parser.parse_args()
59
60 if args.truth_table:
61 print_truth_table()
62 return 0
63
64 # Suppress progress output for non-text formats
65 quiet = args.format != "text"
66
67 if not quiet:
68 print("BCD to 7-Segment Decoder Optimizer")
69 print("=" * 40)
70 print(f"Target: < {args.target} gate inputs")
71 print()
72
73 solver = BCDTo7SegmentSolver()
74
75 try:
76 # Temporarily redirect stdout for quiet mode
77 if quiet:
78 import io
79 old_stdout = sys.stdout
80 sys.stdout = io.StringIO()
81
82 result = solver.solve(target_cost=args.target, use_exact=args.exact)
83
84 if quiet:
85 sys.stdout = old_stdout
86
87 # Output in requested format (use exact synthesis exports if available)
88 is_exact = result.gates is not None and len(result.gates) > 0
89
90 if args.format == "verilog":
91 print(to_verilog_exact(result) if is_exact else to_verilog(result))
92 elif args.format == "c":
93 print(to_c_exact(result) if is_exact else to_c_code(result))
94 elif args.format == "equations":
95 print(to_equations(result))
96 elif args.format == "dot":
97 print(to_dot_exact(result) if is_exact else to_dot(result))
98 else:
99 print()
100 solver.print_result(result)
101
102 if result.cost < args.target:
103 print(f"\n✓ SUCCESS: Beat target by {args.target - result.cost} gate inputs!")
104 else:
105 print(f"\n✗ Did not beat target (need {result.cost - args.target + 1} more reduction)")
106
107 return 0 if result.cost < args.target else 1
108
109 except Exception as e:
110 if quiet:
111 sys.stdout = old_stdout
112 print(f"Error: {e}", file=sys.stderr)
113 if args.verbose:
114 import traceback
115 traceback.print_exc()
116 return 1
117
118
119if __name__ == "__main__":
120 sys.exit(main())