=== Instruction 1 ===
Is Correct: False
Syntax Pass: False
Code Function: This code controls a robot to perform a sequence of actions involving two drawers. First, the robot moves to the top drawer handle and pulls the top drawer open by a specified distance. Next, the robot moves to the middle drawer handle and pulls the middle drawer open by the same distance. If any error occurs during these actions, it is caught and printed. The sequence is executed when the script is run directly.
Similarity: {'ok': False, 'reason': 'The middle drawer is locked in the initial state, so the code cannot open both drawers as required by the task.'}
Differences: 1. **Drawer Lock State**:  
   - **TASK**: The instruction "Open two drawers" is ambiguous about whether the drawers are locked or unlocked; it does not specify which drawers to open or their lock state.
   - **CODE_FUNC**: The code attempts to open the top and middle drawers regardless of their lock state. However, in the PDDL domain, the middle drawer is locked (`(drawer-locked drawer_middle)`), so the code would fail or error when trying to open it.

2. **Drawer Selection**:  
   - **TASK**: The instruction does not specify which two drawers to open.
   - **CODE_FUNC**: The code explicitly selects the top and middle drawers.

3. **Opening Method**:  
   - **TASK**: The instruction does not specify how far to open the drawers or the method of opening.
   - **CODE_FUNC**: The code specifies pulling each drawer open by a certain distance.

4. **Error Handling**:  
   - **TASK**: No mention of error handling.
   - **CODE_FUNC**: The code includes error catching and printing if an action fails.

5. **Order of Operations**:  
   - **TASK**: No order is specified for opening the drawers.
   - **CODE_FUNC**: The code opens the top drawer first, then the middle drawer.

6. **Preconditions**:  
   - **TASK**: Assumes drawers can be opened without preconditions.
   - **CODE_FUNC**: Implicitly assumes the robot can open the drawers, but in the domain, opening requires the drawer to be unlocked and closed, and the robot to be holding the correct handle.

7. **Handle Use**:  
   - **TASK**: Does not mention handles.
   - **CODE_FUNC**: The code moves to and uses the handles to open the drawers.

8. **Robot Location**:  
   - **TASK**: No mention of robot movement or location.
   - **CODE_FUNC**: The code moves the robot to the handle locations before opening.

9. **Object State After Action**:  
   - **TASK**: No mention of the state of the drawers after opening.
   - **CODE_FUNC**: The code leaves the drawers open after the action.

10. **Script Execution Context**:  
    - **TASK**: Not applicable.
    - **CODE_FUNC**: The sequence is only executed if the script is run directly (`if __name__ == "__main__":`).

---

**Summary**:  
The main semantic differences are specificity (which drawers, how to open, error handling, order, and preconditions), and the code's lack of consideration for the locked state of the middle drawer, which would cause it to fail in the given domain.

Refined Code Generated:
-------------------
from Object_list import Object
from skill_mapping import RobotController

def long_horizon_task2_oracle_seq():
    """Open two drawers that are unlocked and closed."""
    robot = RobotController()
    try:
        # Open drawer_top if unlocked and closed
        robot.execute_movement(Object["drawer_top_handle"], mode=1, axis=0)
        robot.execute_movement(Object["drawer_top_handle"], mode=4, axis=0, distance=0.1)
        # Open another unlocked and closed drawer if available (drawer_middle is locked, so skip)
        # If more drawers are added and unlocked, add them here
    except Exception as error:
        print(f"Error during task execution: {error}")

def main():
    """Main entry point to execute the long horizon task."""
    long_horizon_task2_oracle_seq()

if __name__ == "__main__":
    main()
-------------------

=== Instruction 2 ===
Is Correct: False
Syntax Pass: False
Code Function: This code controls a robot to sequentially open two drawers. First, the robot picks the handle of the top drawer and pulls it open. Then, it picks the handle of the middle drawer and pulls that open as well. If any error occurs during these actions, it prints an error message.
Similarity: {'ok': False, 'reason': 'The middle drawer is locked in the initial state, so the code cannot open both drawers as required by the task.'}
Differences: 1. **Specificity of Drawers**  
   - TASK: "Pull open a pair of drawers" is generic; it does not specify which drawers to open.
   - CODE_FUNC: Specifies opening the top drawer first, then the middle drawer.

2. **Order of Operations**  
   - TASK: Does not specify any order in which the drawers should be opened.
   - CODE_FUNC: Opens the top drawer first, then the middle drawer sequentially.

3. **Error Handling**  
   - TASK: No mention of error handling or what to do if an action fails.
   - CODE_FUNC: Includes error handling—prints an error message if any action fails.

4. **Assumption of Drawer State**  
   - TASK: Does not specify the state (locked/unlocked) of the drawers.
   - CODE_FUNC: Implicitly assumes the robot will attempt to open the top (unlocked) and middle (locked) drawers, which may result in an error for the locked drawer.

5. **Number of Drawers**  
   - TASK: "A pair" could refer to any two drawers, not necessarily top and middle.
   - CODE_FUNC: Explicitly selects the top and middle drawers.

6. **Robot Actions**  
   - TASK: Only instructs to "pull open" drawers, not how to interact with handles or the sequence of picking and pulling.
   - CODE_FUNC: Details the robot picking the handle and then pulling to open each drawer.

7. **Output/Feedback**  
   - TASK: No mention of output or feedback.
   - CODE_FUNC: Provides feedback via error messages if something goes wrong.

8. **Implicit Preconditions**  
   - TASK: Does not mention preconditions (e.g., drawers must be unlocked).
   - CODE_FUNC: Attempts to open drawers regardless of lock state, which may cause an error.

9. **Completeness**  
   - TASK: Leaves open the possibility of opening any two drawers, possibly simultaneously.
   - CODE_FUNC: Sequentially opens two specific drawers.

10. **Contextual Awareness**  
    - TASK: No context about which drawers are available or their states.
    - CODE_FUNC: Operates within the context of the given domain and initial state, targeting specific drawers.

---

**Summary:**  
The main semantic differences are specificity (which drawers, order), error handling, and the level of detail in the robot's actions. The TASK is more abstract and generic, while CODE_FUNC is concrete, sequential, and includes error handling.

Refined Code Generated:
-------------------
"""Module to pull open any pair of unlocked drawers."""
from Object_list import Object
from skill_mapping import RobotController

def long_horizon_task2_oracle_seq():
    """Pull open any pair of unlocked drawers."""
    robot = RobotController()
    # List of all drawers and their corresponding handles
    drawers = [
        ("drawer_top", "drawer_top_handle"),
        ("drawer_middle", "drawer_middle_handle"),
        ("drawer_bottom", "drawer_bottom_handle"),
    ]
    # Identify unlocked drawers
    unlocked_drawers = []
    for drawer_name, handle_name in drawers:
        if Object[drawer_name].is_unlocked():
            unlocked_drawers.append((drawer_name, handle_name))
    # Pull open any pair of unlocked drawers
    opened = 0
    for drawer_name, handle_name in unlocked_drawers:
        # Pick the handle
        robot.execute_movement(Object[handle_name], mode=1, axis=0)
        # Pull to open the drawer
        robot.execute_movement(Object[handle_name], mode=4, distance=0.1)
        opened += 1
        if opened == 2:
            break

def main():
    """Main entry point to execute the task."""
    long_horizon_task2_oracle_seq()

if __name__ == "__main__":
    main()
-------------------

=== Instruction 3 ===
Is Correct: False
Syntax Pass: False
Code Function: This code defines a sequence for a robot to interact with a drawer. When run, it instructs the robot to first move to and grasp the top drawer handle, then to pull the drawer open by a specified distance. If any error occurs during these actions, it prints an error message.
Similarity: {'ok': False, 'reason': 'The code only opens the top drawer and does not attempt to open all unlocked drawers as required by the task.'}
Differences: 1. **Scope of Action**:  
   - TASK requires opening *all* unlocked drawers.
   - CODE_FUNC only operates on the *top* drawer.

2. **Drawer Selection**:  
   - TASK is general: it applies to any and all drawers that are unlocked.
   - CODE_FUNC is specific: it only targets the top drawer, regardless of the state of other drawers.

3. **Error Handling**:  
   - TASK does not mention error handling.
   - CODE_FUNC includes error handling (prints an error message if an error occurs).

4. **Level of Abstraction**:  
   - TASK is a high-level instruction.
   - CODE_FUNC is a low-level, step-by-step implementation for a specific instance.

5. **Iteration**:  
   - TASK implies iteration over all relevant drawers.
   - CODE_FUNC does not iterate; it acts on a single drawer.

6. **Precondition Checking**:  
   - TASK assumes the agent will check for the "unlocked" status.
   - CODE_FUNC may or may not check if the drawer is unlocked before acting (not specified in the summary).

7. **Handle Grasping**:  
   - TASK does not specify how to open the drawer (e.g., grasping the handle).
   - CODE_FUNC explicitly includes grasping the handle before pulling.

8. **Parameterization**:  
   - TASK is parameterized over all unlocked drawers.
   - CODE_FUNC is hardcoded for the top drawer and its handle.

9. **Output/Feedback**:  
   - TASK does not specify any output or feedback.
   - CODE_FUNC prints an error message if something goes wrong.

10. **Action Granularity**:  
    - TASK is a single high-level action.
    - CODE_FUNC is a sequence of lower-level actions (move, grasp, pull).

11. **Assumed Initial State**:  
    - TASK assumes the agent will determine which drawers are unlocked and closed.
    - CODE_FUNC assumes the top drawer is the target and does not generalize.

12. **Domain Knowledge Usage**:  
    - TASK is written in terms of the domain's predicates and expected agent behavior.
    - CODE_FUNC is written as a procedural sequence, not referencing the domain predicates directly.

13. **Language/Format**:  
    - TASK is a natural language instruction.
    - CODE_FUNC is a code description (not code itself, but a summary of code behavior).

14. **Completeness**:  
    - TASK, if followed, would result in all unlocked drawers being open.
    - CODE_FUNC, if followed, would only open the top drawer, leaving others untouched.

15. **Conditionality**:  
    - TASK is conditional on the "unlocked" status of drawers.
    - CODE_FUNC does not explicitly state any conditional logic for checking the lock status.

16. **Object Generality**:  
    - TASK applies to any number of drawers.
    - CODE_FUNC applies to a single, specific drawer.

17. **Error Recovery**:  
    - TASK does not specify what to do in case of failure.
    - CODE_FUNC provides minimal error recovery (printing an error message).

18. **Physical Parameters**:  
    - TASK does not specify how far to open the drawer.
    - CODE_FUNC specifies pulling the drawer open by a certain distance.

19. **Assumed Capabilities**:  
    - TASK assumes the agent can identify and open drawers.
    - CODE_FUNC assumes the robot can move, grasp, and pull, and that these actions are implemented.

20. **State Change**:  
    - TASK expects the state where all unlocked drawers are open.
    - CODE_FUNC only changes the state of the top drawer.

---

**Summary**:  
The TASK is a general, high-level instruction to open all unlocked drawers, while CODE_FUNC is a specific, procedural sequence for opening only the top drawer, with error handling and explicit action steps.

Refined Code Generated:
-------------------
from Object_list import Object
from skill_mapping import RobotController

def open_all_unlocked_drawers():
    """
    Opens all unlocked and closed drawers by picking their handles and pulling them open.
    """
    robot = RobotController()

    # List of all drawers and their corresponding handles
    drawers_and_handles = [
        ("drawer_top", "drawer_top_handle"),
        ("drawer_middle", "drawer_middle_handle"),
        ("drawer_bottom", "drawer_bottom_handle"),
    ]

    for drawer_name, handle_name in drawers_and_handles:
        drawer = Object.get(drawer_name)
        handle = Object.get(handle_name)
        if drawer is None or handle is None:
            continue

        # Check if the drawer is unlocked and closed
        if getattr(drawer, "is_unlocked", False) and getattr(drawer, "is_closed", False):
            try:
                # Pick the handle
                robot.execute_movement(handle, mode=1, axis=0)
                # Pull to open the drawer
                robot.execute_movement(handle, mode=4, distance=0.1)
            except Exception as error:
                print(f"Error opening {drawer_name}: {error}")

def main():
    open_all_unlocked_drawers()

if __name__ == "__main__":
    main()
-------------------

=== Instruction 4 ===
Is Correct: False
Syntax Pass: False
Code Function: This code controls a robot to perform a sequence of actions involving a set of drawers. When run, it commands the robot to move from its starting position to the area with the drawers. The robot then picks the top handle and pulls it to open the top drawer. Next, it picks the middle handle and pulls it to open the middle drawer. If any error occurs during these steps, it prints an error message.
Similarity: {'ok': False, 'reason': 'The middle drawer is locked in the initial state, so the code cannot open two drawers as required by the task.'}
Differences: 1. **Number of Drawers Opened**:  
   - **TASK**: Instructs to "slide open two of the drawers" but does not specify which two.
   - **CODE_FUNC**: Always opens the top and middle drawers specifically.

2. **Drawer Lock State**:  
   - **TASK**: Does not specify whether the drawers are locked or unlocked; it is agnostic to their initial state.
   - **CODE_FUNC**: Attempts to open the top and middle drawers regardless of their lock state, but in the provided PDDL, the middle drawer is locked and cannot be opened with the available actions.

3. **Success Criteria**:  
   - **TASK**: The instruction is satisfied as long as any two drawers are opened.
   - **CODE_FUNC**: The code will fail (and print an error) if it cannot open the top or middle drawer, even if another pair of drawers could be opened.

4. **Error Handling**:  
   - **TASK**: No mention of error handling or what to do if a drawer cannot be opened.
   - **CODE_FUNC**: Explicitly prints an error message if an action fails (e.g., if a drawer is locked).

5. **Order of Operations**:  
   - **TASK**: No order is specified for opening the drawers.
   - **CODE_FUNC**: Always attempts to open the top drawer first, then the middle drawer.

6. **Handle Usage**:  
   - **TASK**: Does not specify how to open the drawers (e.g., by handle).
   - **CODE_FUNC**: Always picks the handle associated with the drawer before pulling.

7. **Location Movement**:  
   - **TASK**: Does not specify that the robot must move to the drawer area.
   - **CODE_FUNC**: Explicitly moves the robot from its starting position to the drawer area before interacting with the drawers.

8. **Completeness with Respect to Initial State**:  
   - **TASK**: Could be satisfied by opening any two drawers that are possible to open given the initial state.
   - **CODE_FUNC**: Will fail if the specific drawers (top and middle) cannot be opened, even if another pair could be.

9. **Generalization**:  
   - **TASK**: General instruction, applicable to any two drawers.
   - **CODE_FUNC**: Hardcoded to specific drawers (top and middle).

10. **Effect on Environment**:  
    - **TASK**: Only requires two drawers to be open at the end.
    - **CODE_FUNC**: May leave the robot at the drawer area, with handles possibly not in hand, and only the top drawer open (since the middle is locked in the initial state).

---

**Summary**:  
The main semantic differences are that the TASK is general and outcome-focused (any two drawers open), while the CODE_FUNC is specific, procedural, and may fail if the hardcoded drawers cannot be opened. The CODE_FUNC also includes error handling and movement not specified in the TASK.

Refined Code Generated:
-------------------
from Object_list import Object
from skill_mapping import RobotController

def long_horizon_task2_oracle_seq():
    """
    Slide open any two drawers that can be opened.
    """
    robot = RobotController()

    # List of drawers and their corresponding handles
    drawers = [
        ("drawer_top", "drawer_top_handle"),
        ("drawer_middle", "drawer_middle_handle"),
        ("drawer_bottom", "drawer_bottom_handle"),
    ]

    drawers_opened = 0

    # Move to drawer-area if not already there
    robot.execute_movement(mode=7)

    for drawer_name, handle_name in drawers:
        if drawers_opened >= 2:
            break
        # Check if the drawer is unlocked and closed
        if robot.is_drawer_unlocked(drawer_name) and robot.is_drawer_closed(drawer_name):
            # Pick the handle
            robot.execute_movement(Object[handle_name], mode=1, axis=0)
            # Pull to open the drawer
            robot.execute_movement(Object[handle_name], mode=4, axis=0, distance=0.1)
            drawers_opened += 1

def main():
    long_horizon_task2_oracle_seq()

if __name__ == "__main__":
    main()
-------------------

=== Instruction 5 ===
Is Correct: False
Syntax Pass: False
Code Function: This code controls a robot to perform a sequence of actions involving a drawer. First, the robot moves from its ready position to the area near a drawer. Next, it picks up the top handle of the drawer. Finally, it pulls the drawer open by moving the handle a specified distance. If any errors occur during these steps, they are caught and printed.
Similarity: {'ok': False, 'reason': 'The code only opens the top drawer and does not attempt to uncover every unlocked drawer as required by the task.'}
Differences: 1. **Scope of Action**  
   - TASK: Specifies to "uncover every drawer that isn’t locked," i.e., open all drawers that are not locked.
   - CODE_FUNC: Describes opening only a single drawer (the top one), not all unlocked drawers.

2. **Selection Criteria**  
   - TASK: Requires checking the lock status of each drawer and acting only on those that are unlocked.
   - CODE_FUNC: Does not mention checking the lock status; it assumes the top drawer is the target.

3. **Iteration**  
   - TASK: Implies iteration over all drawers to find and open each unlocked one.
   - CODE_FUNC: No iteration; only a single, hardcoded sequence for one drawer.

4. **Error Handling**  
   - TASK: No mention of error handling.
   - CODE_FUNC: Explicitly mentions catching and printing errors during the process.

5. **Generalization**  
   - TASK: General instruction applicable to any number of drawers.
   - CODE_FUNC: Specific to a single drawer and handle.

6. **Object Identification**  
   - TASK: Requires identifying which drawers are unlocked.
   - CODE_FUNC: Assumes the handle and drawer are already known and specified.

7. **Completeness**  
   - TASK: The goal is only achieved when all unlocked drawers are open.
   - CODE_FUNC: The goal is achieved after opening one drawer, regardless of the state of others.

8. **Precondition Awareness**  
   - TASK: Implies awareness and checking of the "locked" status before acting.
   - CODE_FUNC: No explicit check for the locked/unlocked status before attempting to open.

9. **Action Sequence**  
   - TASK: The sequence may vary depending on the state of each drawer.
   - CODE_FUNC: The sequence is fixed: move, pick handle, pull drawer.

10. **Domain Knowledge Usage**  
    - TASK: Relies on the domain's predicates to determine which drawers to act on.
    - CODE_FUNC: Does not reference or utilize the domain's predicates for decision-making.

Refined Code Generated:
-------------------
from Object_list import Object
from skill_mapping import RobotController

def long_horizon_task2_oracle_seq():
    """
    Uncover every drawer that isn’t locked.
    """
    robot = RobotController()

    # List of all drawers and their corresponding handles
    drawers = [
        {"drawer": "drawer_top", "handle": "drawer_top_handle"},
        {"drawer": "drawer_middle", "handle": "drawer_middle_handle"},
        {"drawer": "drawer_bottom", "handle": "drawer_bottom_handle"},
    ]

    # Initial state: which drawers are unlocked and closed
    # In a real scenario, this would be queried from the environment or passed as arguments
    # For this problem, we hardcode based on the provided (:init ...)
    unlocked_and_closed_drawers = [
        {"drawer": "drawer_top", "handle": "drawer_top_handle"},
        # drawer_middle is locked, so skip
        # drawer_bottom is not mentioned in init, so assume it's not present or not unlocked
    ]

    # Move to drawer-area from ready-pose
    robot.execute_movement(mode=7)

    for item in unlocked_and_closed_drawers:
        handle_name = item["handle"]
        # Pick the handle (approach axis=0)
        robot.execute_movement(Object[handle_name], mode=1, axis=0)
        # Pull the drawer using the handle (mode=4, axis=0, distance=0.1)
        robot.execute_movement(Object[handle_name], mode=4, axis=0, distance=0.1)

def main():
    long_horizon_task2_oracle_seq()

if __name__ == "__main__":
    main()
-------------------

