diff --git a/reasoning_gym/arc/__init__.py b/reasoning_gym/arc/__init__.py index d422e098..fcb2b262 100644 --- a/reasoning_gym/arc/__init__.py +++ b/reasoning_gym/arc/__init__.py @@ -1,10 +1,11 @@ -from .arc_1d import Arc1DConfig, Arc1DDataset +from .arc_1d import Arc1DConfig, Arc1DCurriculum, Arc1DDataset from .arc_agi import ArcAgiConfig, ArcAgiDataset from .rearc import ReArcConfig, ReArcCurriculum, ReArcDataset __all__ = [ "Arc1DConfig", "Arc1DDataset", + "Arc1DCurriculum", "ArcAgiConfig", "ArcAgiDataset", "ReArcDataset", diff --git a/reasoning_gym/arc/arc_1d.py b/reasoning_gym/arc/arc_1d.py index 9a7ee78c..0dfc5bb0 100644 --- a/reasoning_gym/arc/arc_1d.py +++ b/reasoning_gym/arc/arc_1d.py @@ -2,6 +2,7 @@ from dataclasses import dataclass from random import Random from typing import Optional +from ..coaching import BaseCurriculum, RangeAttributeDefinition from ..dataset import ProceduralDataset from ..factory import register_dataset @@ -108,9 +109,31 @@ class Arc1DDataset(ProceduralDataset): "size": size, "train_examples": train_examples, "test_example": test_example, + "difficulty": { + "size": (self.config.min_size, self.config.max_size), + }, }, } +class Arc1DCurriculum(BaseCurriculum): + """Curriculum for ARC 1D tasks""" + + def __init__(self): + super().__init__(Arc1DCurriculum.__name__, Arc1DConfig) + + # Define attributes + self._define_attributes( + RangeAttributeDefinition( + name="size", + levels=[10, 25, 50, 100], + lower_field_name="min_size", + upper_field_name="max_size", + description="Grid size", + ensure_interval=True, + ) + ) + + # Register the dataset -register_dataset(DATASET_NAME, Arc1DDataset, Arc1DConfig) +register_dataset(DATASET_NAME, Arc1DDataset, Arc1DConfig, Arc1DCurriculum) diff --git a/tests/test_arc_1d.py b/tests/test_arc_1d.py index 1eeb0d09..8a267268 100644 --- a/tests/test_arc_1d.py +++ b/tests/test_arc_1d.py @@ -2,7 +2,7 @@ from random import Random import pytest -from reasoning_gym.arc import Arc1DConfig, Arc1DDataset +from reasoning_gym.arc import Arc1DConfig, Arc1DCurriculum, Arc1DDataset def test_arc_1d_config_validation(): @@ -41,6 +41,7 @@ def test_arc_1d_items(): assert "question" in item assert "answer" in item assert "metadata" in item + assert "difficulty" in item["metadata"] # Check metadata contents metadata = item["metadata"] @@ -142,3 +143,44 @@ def test_arc_1d_generate_all_tasks(): break assert i < 20 print(task_name, j, i, x) + + +def test_arc_1d_curriculum(): + """Test the curriculum for complex arithmetic.""" + curriculum = Arc1DCurriculum() + base_value = {"size": 150, "seed": 1} + + base_cfg: Arc1DCurriculum = curriculum.generate_configuration(base_value) + + assert base_cfg.seed == 1 + assert base_cfg.size == 150 + assert base_cfg.min_size == 10 + assert base_cfg.max_size == 25 + + # Test and validate increase in levels + curriculum.increment_attr_level("size") + + increased_cfg: Arc1DCurriculum = curriculum.generate_configuration(base_value) + assert increased_cfg.min_size == 10 + assert increased_cfg.max_size == 50 + + # Test and validate decrease in levels + curriculum.decrement_attr_level("size") + + decreased_cfg: Arc1DCurriculum = curriculum.generate_configuration(base_value) + assert decreased_cfg.min_size == 10 + assert decreased_cfg.max_size == 25 + + # Test upper bound boundary condition + for _ in range(10): + curriculum.increment_attr_level("size") + upper_bound_cfg: Arc1DCurriculum = curriculum.generate_configuration(base_value) + assert upper_bound_cfg.min_size == 10 + assert upper_bound_cfg.max_size == 100 + + # Test lower bound boundary condition + for _ in range(10): + curriculum.decrement_attr_level("size") + lower_bound_cfg: Arc1DCurriculum = curriculum.generate_configuration(base_value) + assert lower_bound_cfg.min_size == 10 + assert lower_bound_cfg.max_size == 25