File size: 2,471 Bytes
20c251e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
from __future__ import annotations

import pytest

from dovla_cil.tasks.library import (
    HARD_CAUSALSTRESS_CATEGORIES,
    ToyTaskLibrary,
    built_in_causalstress_tasks,
    built_in_toy_tasks,
)
from dovla_cil.tasks.predicates import evaluate_predicate, evaluate_task_success
from dovla_cil.tasks.schema import RelationSpec, TaskSpec
from dovla_cil.tasks.validators import validate_task


def test_valid_builtin_tasks_pass() -> None:
    tasks = built_in_toy_tasks()
    assert len(tasks) == 10
    for task in tasks:
        validate_task(task)
        assert TaskSpec.from_dict(task.to_dict()) == task


def test_toy_task_library_cycles_tasks() -> None:
    library = ToyTaskLibrary()
    assert library.get(0).task_id == "toy_pick_red_mug"
    assert library.get(10).task_id == "toy_pick_red_mug"
    assert len(library.list()) == 10


def test_hard_causalstress_tasks_pass_validation() -> None:
    tasks = built_in_causalstress_tasks()
    assert len(tasks) == len(HARD_CAUSALSTRESS_CATEGORIES)
    assert {task.family for task in tasks} == set(HARD_CAUSALSTRESS_CATEGORIES)
    for task in tasks:
        validate_task(task)


def test_invalid_predicate_object_fails() -> None:
    task = built_in_toy_tasks()[0].model_copy(
        update={"success_predicates": [RelationSpec(name="grasped", args=["missing_mug"])]}
    )
    with pytest.raises(ValueError, match="unknown object"):
        validate_task(task)


def test_predicate_evaluator_inside_left_of_opened_lifted() -> None:
    state = {
        "objects": {
            "red_mug": {"inside": "blue_bowl", "position": [0.0, 0.0, 0.2]},
            "blue_bowl": {"position": [1.0, 0.0, 0.0]},
            "drawer": {"opened": True},
            "can": {"position": [0.0, 0.0, 0.3]},
        }
    }
    assert evaluate_predicate(RelationSpec(name="inside", args=["red_mug", "blue_bowl"]), state)
    assert evaluate_predicate(RelationSpec(name="left_of", args=["red_mug", "blue_bowl"]), state)
    assert evaluate_predicate(RelationSpec(name="opened", args=["drawer"]), state)
    assert evaluate_predicate(RelationSpec(name="lifted", args=["can"]), state)


def test_evaluate_task_success() -> None:
    task = ToyTaskLibrary().get_by_id("toy_put_red_mug_in_blue_bowl")
    state = {
        "objects": {
            "red_mug": {"inside": "blue_bowl", "position": [0.0, 0.0, 0.0]},
            "blue_bowl": {"position": [0.0, 0.0, 0.0]},
        }
    }
    assert evaluate_task_success(task, state)