Fix enumerative search halting before budget for refined types (issue #89)#144
Fix enumerative search halting before budget for refined types (issue #89)#144
Conversation
…89) Root cause: the grammar for integer holes used an unlimited-range literal (range -100,000,000 to 100,000,000) as the only integer production. For {y:Int | 0 < y && y < 100}, the enumerative search exhausted the budget iterating through negative integers before ever reaching the valid range 1–99. Fix: replace the unlimited-range Int literal with metahandler-based literals: - The default Int literal now uses IntRange(-1, 256) via a metahandler, so the enumerative search only iterates a small, practical range. - When the synthesis target has a refined type (e.g. {y:Int | 0 < y && y < 100}), pass it via refined_types=True so create_literal_ref_nodes generates an additional metahandler literal (IntRange(1, 99)) as a direct alternative for æInt — no refined abstract class is used as grammar starting symbol. - The refined literal's get_core() returns Literal(v, base_type) so the type checker handles it correctly. - Context variable types are stripped of refinements in gen_grammar_nodes to avoid KeyErrors from mangled variable names in type_info. - SynquidSynthesizer strips the refined type before synthesis since Synquid only handles unrefined types internally. - Add regression test for the exact example from issue #89. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Instead of stripping refinements in synthesizer.py before passing to synthes_memory, handle RefinedType directly in synthes() by normalizing to base type for literal generation and variable/function lookup. The validator handles refinement checking on the synthesized terms. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When sympy's reduce_rational_inequalities encounters a non-linear constraint (e.g. i² - x < 0, produced when a hole type depends on a function parameter via multiplication), it raises NotImplementedError which was re-raised and crashed the synthesis run. Fall back to Interval(-oo, oo) in conditional_to_interval so synthesis can continue with an unbounded range instead of crashing. The hole will still be synthesized correctly; it just won't benefit from the tighter literal range derived from the constraint. Fixes the build (3.11) failure on CI triggered by examples/synthesis/hole_refined_synthesis.ae. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Found and fixed the CI failure ( Root cause: Fix ( Pushed as branch |
Summary
Fixes #89: the enumerative synthesizer was returning
Nonefor refined integer types like{y:Int | 0 < y && y < 100}because the grammar's unlimited-range Int literal (-100,000,000to100,000,000) exhausted the time budget before reaching any valid values.IntRange(-1, 256)) — the enumerative search now iterates a small, practical default range instead of 200 million integers{y:Int | 0 < y && y < 100}), anIntRange(1, 99)literal is added as a direct grammar alternative foræInt, with no refined abstract class as starting symbolget_core()for refined literals — returnsLiteral(v, base_type)so the type checker handles it correctlyKeyErrorfrom mangled variable names intype_infoSynquidSynthesizerto strip the refined type before synthesis (Synquid only handles unrefined types)Test plan
test_enumerative_halts_within_budgetpasses: synthesizes a validIntin(0, 100)within 0.25s budget (with a 10s SIGALRM safety guard)🤖 Generated with Claude Code