=== Instruction 1 ===
Is Correct: False
Syntax Pass: False
Code Function: The code defines a function to run a simulation task involving picking and placing an object, specifically a tomato, on a plate. It begins by setting up the environment and resetting the task to its initial state. Video recording is initialized to capture the simulation. The positions of the objects are retrieved, and the task consists of a series of steps: first, it picks the tomato from the table, then places it on the plate. If the task is completed successfully, it prints a success message. If needed, the process is repeated, picking the tomato again and placing it on the plate once more. The function ensures that the environment is properly shut down at the end of the task, regardless of whether it was completed successfully or not.
Similarity: {'ok': False, 'reason': 'LLM JSON parsing failed.'}
Differences: 1. **Purpose**: 
   - TASK describes a high-level instruction for a robot to perform ("put all tomatoes on the plate").
   - CODE_FUNC outlines a specific implementation of a simulation task that executes the instruction in a programming context.

2. **Level of Abstraction**:
   - TASK is an abstract directive without implementation details.
   - CODE_FUNC provides concrete steps and logic for executing the task, including environment setup and handling of success/failure.

3. **Environment Setup**:
   - TASK does not specify how the environment is set up or what initial conditions are required.
   - CODE_FUNC includes details about initializing the environment and resetting it to a specific state.

4. **Execution Flow**:
   - TASK does not detail the sequence of actions or how to handle multiple tomatoes.
   - CODE_FUNC describes a specific sequence of actions (picking and placing) and includes logic for repeating the process if necessary.

5. **Success Handling**:
   - TASK does not mention how to determine if the task is completed successfully.
   - CODE_FUNC includes a success message and logic for handling task completion.

6. **Error Handling**:
   - TASK does not address error handling or what to do if the task cannot be completed.
   - CODE_FUNC implies a mechanism for repeating the task if it fails.

7. **Recording**:
   - TASK does not mention any form of monitoring or recording the task.
   - CODE_FUNC includes video recording to capture the simulation.

8. **Shutdown Procedure**:
   - TASK does not specify any shutdown or cleanup procedures.
   - CODE_FUNC ensures that the environment is properly shut down at the end of the task.

9. **Object Specificity**:
   - TASK refers generically to "tomatoes" without specifying how many or which ones.
   - CODE_FUNC specifically mentions picking and placing a "tomato" and implies a singular focus on that object.

10. **Implementation Context**:
    - TASK is a directive that could be interpreted in various contexts (e.g., robotics, cooking).
    - CODE_FUNC is specifically tailored for a simulation environment involving a robot.

In summary, the semantic differences between TASK and CODE_FUNC are significant, as TASK is a high-level instruction while CODE_FUNC provides a detailed implementation of that instruction in a specific context.

Refined Code Generated:
-------------------
import numpy as np
from pyrep.objects.shape import Shape
from pyrep.objects.proximity_sensor import ProximitySensor

from env import setup_environment, shutdown_environment

from skill_code import pick, place
from video import init_video_writers, recording_step, recording_get_observation
from object_positions import get_object_positions


def run_skeleton_task():
    '''Generic skeleton for running any task in your simulation.'''
    print("===== Starting Skeleton Task =====")
    
    # === Environment Setup ===
    env, task = setup_environment()
    try:
        # Reset the task to its initial state
        descriptions, obs = task.reset()

        # (Optional) Initialize video writers for capturing your simulation
        init_video_writers(obs)

        # Wrap the task steps for recording (if needed)
        original_step = task.step
        task.step = recording_step(original_step)
        original_get_obs = task.get_observation
        task.get_observation = recording_get_observation(original_get_obs)

        # === Retrieve Object Positions ===
        positions = get_object_positions()

        # Define object positions based on the provided object list
        tomato1_pos = positions['tomato1']
        plate_pos = positions['plate']

        # === Execute the Plan ===
        # Step 1: Pick tomato1 from the table
        print("[Task] Picking tomato1 from the table.")
        obs, reward, done = pick(
            env,
            task,
            target_pos=tomato1_pos,
            approach_distance=0.15,
            max_steps=100,
            threshold=0.01,
            approach_axis='z',
            timeout=10.0
        )
        if done:
            print("[Task] Task ended after picking tomato1!")
            return

        # Step 2: Place tomato1 on the plate
        print("[Task] Placing tomato1 on the plate.")
        obs, reward, done = place(
            env,
            task,
            target_pos=plate_pos,
            approach_distance=0.15,
            max_steps=100,
            threshold=0.01,
            approach_axis='z',
            timeout=10.0
        )
        if done:
            print("[Task] Task completed successfully! Reward:", reward)
            return

        # Repeat for any additional tomatoes if needed
        # Assuming there are more tomatoes to pick
        for i in range(2, 4):  # Adjust range based on number of tomatoes
            tomato_key = f'tomato{i}'
            if tomato_key in positions:
                tomato_pos = positions[tomato_key]
                
                # Step 3: Pick the next tomato from the table
                print(f"[Task] Picking {tomato_key} from the table.")
                obs, reward, done = pick(
                    env,
                    task,
                    target_pos=tomato_pos,
                    approach_distance=0.15,
                    max_steps=100,
                    threshold=0.01,
                    approach_axis='z',
                    timeout=10.0
                )
                if done:
                    print(f"[Task] Task ended after picking {tomato_key}!")
                    return

                # Step 4: Place the next tomato on the plate
                print(f"[Task] Placing {tomato_key} on the plate.")
                obs, reward, done = place(
                    env,
                    task,
                    target_pos=plate_pos,
                    approach_distance=0.15,
                    max_steps=100,
                    threshold=0.01,
                    approach_axis='z',
                    timeout=10.0
                )
                if done:
                    print(f"[Task] Task completed successfully for {tomato_key}! Reward:", reward)
                    return

    finally:
        # Always ensure the environment is properly shutdown
        shutdown_environment(env)

    print("===== End of Skeleton Task =====")
-------------------

=== Instruction 2 ===
Is Correct: False
Syntax Pass: False
Code Function: The code defines a function to run a simulation task involving picking and placing objects. It begins by setting up the environment and resetting the task to its initial state. It initializes video recording capabilities and retrieves the positions of specific objects, namely two tomatoes and a plate. 

The task consists of four main steps: first, it picks the first tomato from the table; second, it places that tomato onto the plate; third, it picks the second tomato from the table; and finally, it places the second tomato onto the plate. After each action, it checks if the task is completed and prints appropriate messages. 

Regardless of the outcome, the environment is ensured to be properly shut down at the end of the task. The function is executed when the script is run as the main program.
Similarity: {'ok': False, 'reason': 'LLM JSON parsing failed.'}
Differences: 1. **Purpose**: 
   - TASK describes a specific instruction for a robot to perform (dropping tomatoes onto a plate).
   - CODE_FUNC outlines a function that simulates the entire process of picking and placing objects, including setup and teardown.

2. **Structure**: 
   - TASK is presented in a PDDL format, which is a formal language for defining planning problems.
   - CODE_FUNC is described in a narrative format, detailing the steps of a function without formal syntax.

3. **Detail Level**: 
   - TASK provides a high-level instruction without implementation details.
   - CODE_FUNC includes specific steps and actions taken during the simulation, such as initializing the environment and checking task completion.

4. **Execution Context**: 
   - TASK is a standalone instruction meant for a planning system.
   - CODE_FUNC is part of a program that runs a simulation, indicating a broader context of execution.

5. **Outcome Handling**: 
   - TASK does not specify how to handle outcomes or errors.
   - CODE_FUNC includes checks for task completion and prints messages based on the outcome.

6. **Environment Management**: 
   - TASK does not mention any setup or teardown processes.
   - CODE_FUNC explicitly states that the environment is reset and properly shut down after the task.

7. **Object Interaction**: 
   - TASK focuses solely on the action of dropping tomatoes.
   - CODE_FUNC details the sequential actions of picking and placing each tomato, indicating a more complex interaction with the environment.

8. **Initialization**: 
   - TASK assumes an initial state without detailing it.
   - CODE_FUNC describes the initialization of video recording and object positions.

9. **Functionality**: 
   - TASK is a single instruction.
   - CODE_FUNC encompasses multiple actions and checks, indicating a more complex functionality.

10. **Language**: 
    - TASK uses PDDL, which is specific to planning domains.
    - CODE_FUNC uses a more general programming narrative, likely intended for a specific programming language context. 

In summary, the semantic differences between TASK and CODE_FUNC are significant, as they serve different purposes and are structured differently.

Refined Code Generated:
-------------------
import numpy as np
from pyrep.objects.shape import Shape
from pyrep.objects.proximity_sensor import ProximitySensor

from env import setup_environment, shutdown_environment

from skill_code import pick, place
from video import init_video_writers, recording_step, recording_get_observation
from object_positions import get_object_positions

def run_skeleton_task():
    '''Generic skeleton for running any task in your simulation.'''
    print("===== Starting Skeleton Task =====")
    
    # === Environment Setup ===
    env, task = setup_environment()
    try:
        # Reset the task to its initial state
        _, obs = task.reset()

        # (Optional) Initialize video writers for capturing your simulation
        init_video_writers(obs)

        # Wrap the task steps for recording (if needed)
        original_step = task.step
        task.step = recording_step(original_step)
        original_get_obs = task.get_observation
        task.get_observation = recording_get_observation(original_get_obs)

        # === Retrieve Object Positions ===
        positions = get_object_positions()

        # Define object positions
        tomato1_pos = positions['tomato1']
        plate_pos = positions['plate']

        # === Execute the Plan ===
        # Step 1: Pick the first tomato
        print("[Task] Picking tomato1 from the table.")
        obs, reward, done = pick(
            env,
            task,
            target_pos=tomato1_pos,
            approach_distance=0.15,
            max_steps=100,
            threshold=0.01,
            approach_axis='z',
            timeout=10.0
        )
        if done:
            print("[Task] Task ended after picking tomato1!")
            return

        # Step 2: Place the first tomato onto the plate
        print("[Task] Placing tomato1 onto the plate.")
        obs, reward, done = place(
            env,
            task,
            target_pos=plate_pos,
            approach_distance=0.15,
            max_steps=100,
            threshold=0.01,
            approach_axis='z',
            timeout=10.0
        )
        if done:
            print("[Task] Task ended after placing tomato1!")
            return

        # Step 3: Pick the second tomato (assuming it's also on the table)
        print("[Task] Picking tomato2 from the table.")
        obs, reward, done = pick(
            env,
            task,
            target_pos=positions['tomato2'],
            approach_distance=0.15,
            max_steps=100,
            threshold=0.01,
            approach_axis='z',
            timeout=10.0
        )
        if done:
            print("[Task] Task ended after picking tomato2!")
            return

        # Step 4: Place the second tomato onto the plate
        print("[Task] Placing tomato2 onto the plate.")
        obs, reward, done = place(
            env,
            task,
            target_pos=plate_pos,
            approach_distance=0.15,
            max_steps=100,
            threshold=0.01,
            approach_axis='z',
            timeout=10.0
        )
        if done:
            print("[Task] Task completed successfully! Reward:", reward)
        else:
            print("[Task] Task not completed yet (done=False).")

    finally:
        # Always ensure the environment is properly shutdown
        shutdown_environment(env)

    print("===== End of Skeleton Task =====")

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

=== Instruction 3 ===
Is Correct: False
Syntax Pass: False
Code Function: The code defines a function to run a simulation task involving picking up an object and placing it on another object. It begins by setting up the environment and resetting the task to its initial state. It optionally initializes video recording for the simulation. The function retrieves the positions of specific objects, namely a tomato and a plate. It then attempts to pick up the tomato, checking if the task is completed after this action. If successful, it proceeds to place the tomato on the plate, again checking for task completion. Finally, the environment is shut down properly, and the function concludes.
Similarity: {'ok': False, 'reason': 'LLM JSON parsing failed.'}
Differences: 1. **Purpose**: TASK defines a specific instruction for a robot to follow, while CODE_FUNC describes a function that implements a simulation of that instruction.
2. **Structure**: TASK is structured in PDDL (Planning Domain Definition Language) format, which is used for defining planning problems, whereas CODE_FUNC is a description of a programming function that executes the task.
3. **Components**: TASK includes domain definitions, predicates, and actions, while CODE_FUNC focuses on the procedural steps to execute the task in a simulation environment.
4. **Execution**: TASK outlines the logical conditions and effects of actions in a planning context, while CODE_FUNC describes the procedural execution of those actions in a programming context.
5. **Environment Setup**: TASK specifies the initial state and conditions for the robot's actions, while CODE_FUNC includes steps for setting up the simulation environment and resetting it to an initial state.
6. **Object Interaction**: TASK defines the interactions in terms of predicates and effects, while CODE_FUNC describes the procedural logic for checking and executing these interactions.
7. **Completion Check**: TASK does not explicitly mention how to check for task completion, while CODE_FUNC includes steps to verify if the task is completed after each action.
8. **Recording**: CODE_FUNC mentions the optional initialization of video recording, which is not present in TASK. 

Overall, the two serve different purposes and are written in different formats, leading to these semantic differences.

Refined Code Generated:
-------------------
import numpy as np
from pyrep.objects.shape import Shape
from pyrep.objects.proximity_sensor import ProximitySensor

from env import setup_environment, shutdown_environment
from skill_code import pick, place
from video import init_video_writers, recording_step, recording_get_observation
from object_positions import get_object_positions

def run_skeleton_task():
    '''Generic skeleton for running any task in your simulation.'''
    print("===== Starting Skeleton Task =====")
    
    # === Environment Setup ===
    env, task = setup_environment()
    try:
        # Reset the task to its initial state
        descriptions, obs = task.reset()

        # (Optional) Initialize video writers for capturing your simulation
        init_video_writers(obs)

        # Wrap the task steps for recording (if needed)
        original_step = task.step
        task.step = recording_step(original_step)
        original_get_obs = task.get_observation
        task.get_observation = recording_get_observation(original_get_obs)

        # === Retrieve Object Positions ===
        positions = get_object_positions()

        # Define object positions based on the provided object list
        tomato1_pos = positions['tomato1']
        plate_pos = positions['plate']

        # === Execute the Plan ===
        print("[Task] Picking up tomato1...")
        obs, reward, done = pick(
            env,
            task,
            target_pos=tomato1_pos,
            approach_distance=0.15,
            max_steps=100,
            threshold=0.01,
            approach_axis='z',
            timeout=10.0
        )
        if done:
            print("[Task] Task ended after picking tomato1!")
            return

        print("[Task] Placing tomato1 on the plate...")
        obs, reward, done = place(
            env,
            task,
            target_pos=plate_pos,
            approach_distance=0.15,
            max_steps=100,
            threshold=0.01,
            approach_axis='z',
            timeout=10.0
        )
        if done:
            print("[Task] Task completed successfully! Reward:", reward)
        else:
            print("[Task] Task not completed yet (done=False).")

    finally:
        # Always ensure the environment is properly shutdown
        shutdown_environment(env)

    print("===== End of Skeleton Task =====")

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

=== Instruction 4 ===
Is Correct: False
Syntax Pass: False
Code Function: The code defines a function to run a simulation task involving picking and placing objects. It begins by setting up the environment and resetting the task to its initial state. Video recording is optionally initialized to capture the simulation. The positions of objects, specifically two tomatoes and a plate, are retrieved.

The task consists of four main steps: first, it picks the first tomato from the table; second, it places that tomato onto the plate; third, it picks the second tomato from the table; and finally, it places the second tomato onto the plate. After each action, the code checks if the task is completed and prints appropriate messages. Regardless of the outcome, the environment is shut down at the end of the task. The function is executed when the script is run as the main program.
Similarity: {'ok': False, 'reason': 'LLM JSON parsing failed.'}
Differences: 1. **Purpose**: 
   - TASK defines a planning problem in PDDL format, specifying the actions and conditions for a robot to transfer tomatoes.
   - CODE_FUNC describes a procedural implementation of a simulation task that executes the actions defined in the TASK.

2. **Format**: 
   - TASK is written in a declarative format (PDDL) focusing on the definition of actions, predicates, and the problem setup.
   - CODE_FUNC is written in an imperative programming style, detailing step-by-step instructions for executing the task.

3. **Execution**: 
   - TASK does not execute any actions; it merely defines what actions can be taken and under what conditions.
   - CODE_FUNC actively performs the actions of picking and placing the tomatoes, including checking for task completion.

4. **Environment Setup**: 
   - TASK includes a static definition of the initial state and the actions available to the robot.
   - CODE_FUNC involves dynamic interaction with the environment, including resetting the state and potentially recording the simulation.

5. **Feedback Mechanism**: 
   - TASK does not provide any feedback or output regarding the success or failure of actions.
   - CODE_FUNC includes print statements to inform the user about the progress and completion of the task.

6. **Action Sequence**: 
   - TASK defines actions in a general sense without specifying the order of execution.
   - CODE_FUNC explicitly outlines the sequence of actions to be performed (pick first tomato, place first tomato, pick second tomato, place second tomato).

7. **Completion Check**: 
   - TASK does not include any mechanism for checking if the task is completed.
   - CODE_FUNC includes checks after each action to determine if the task has been completed.

8. **Shutdown Procedure**: 
   - TASK does not include any shutdown or cleanup procedures.
   - CODE_FUNC specifies that the environment is shut down at the end of the task, regardless of the outcome.

9. **Optional Features**: 
   - TASK does not mention any optional features like video recording.
   - CODE_FUNC includes an optional video recording feature to capture the simulation.

10. **Context**: 
    - TASK is context-free and can be applied to any similar problem in the defined domain.
    - CODE_FUNC is context-specific, tailored to the particular simulation of transferring tomatoes onto a plate. 

In summary, the semantic differences between TASK and CODE_FUNC are significant, as they serve different purposes and are structured in different ways.

Refined Code Generated:
-------------------
import numpy as np
from pyrep.objects.shape import Shape
from pyrep.objects.proximity_sensor import ProximitySensor

from env import setup_environment, shutdown_environment

from skill_code import pick, place  # Importing specific skills
from video import init_video_writers, recording_step, recording_get_observation
from object_positions import get_object_positions

def run_skeleton_task():
    '''Generic skeleton for running any task in your simulation.'''
    print("===== Starting Skeleton Task =====")
    
    # === Environment Setup ===
    env, task = setup_environment()
    try:
        # Reset the task to its initial state
        _, obs = task.reset()

        # (Optional) Initialize video writers for capturing your simulation
        init_video_writers(obs)

        # Wrap the task steps for recording (if needed)
        original_step = task.step
        task.step = recording_step(original_step)
        original_get_obs = task.get_observation
        task.get_observation = recording_get_observation(original_get_obs)

        # === Retrieve Object Positions ===
        positions = get_object_positions()

        # Define object positions
        tomato1_pos = positions['tomato1']
        plate_pos = positions['plate']

        # === Execute the Plan ===
        # Step 1: Pick tomato1 from the table
        print("[Task] Picking tomato1 from the table.")
        obs, reward, done = pick(
            env,
            task,
            target_pos=tomato1_pos,
            approach_distance=0.15,
            max_steps=100,
            threshold=0.01,
            approach_axis='z',
            timeout=10.0
        )
        if done:
            print("[Task] Task ended after picking tomato1!")
            return

        # Step 2: Place tomato1 onto the plate
        print("[Task] Placing tomato1 onto the plate.")
        obs, reward, done = place(
            env,
            task,
            target_pos=plate_pos,
            approach_distance=0.15,
            max_steps=100,
            threshold=0.01,
            approach_axis='z',
            timeout=10.0
        )
        if done:
            print("[Task] Task ended after placing tomato1!")
            return

        # Step 3: Pick tomato2 from the table
        print("[Task] Picking tomato2 from the table.")
        obs, reward, done = pick(
            env,
            task,
            target_pos=positions['tomato2'],
            approach_distance=0.15,
            max_steps=100,
            threshold=0.01,
            approach_axis='z',
            timeout=10.0
        )
        if done:
            print("[Task] Task ended after picking tomato2!")
            return

        # Step 4: Place tomato2 onto the plate
        print("[Task] Placing tomato2 onto the plate.")
        obs, reward, done = place(
            env,
            task,
            target_pos=plate_pos,
            approach_distance=0.15,
            max_steps=100,
            threshold=0.01,
            approach_axis='z',
            timeout=10.0
        )
        if done:
            print("[Task] Task completed successfully! Reward:", reward)
        else:
            print("[Task] Task not completed yet (done=False).")

    finally:
        # Always ensure the environment is properly shutdown
        shutdown_environment(env)

    print("===== End of Skeleton Task =====")

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

=== Instruction 5 ===
Is Correct: False
Syntax Pass: False
Code Function: The code defines a function to run a simulation task involving picking and placing objects. It begins by setting up the environment and resetting the task to its initial state. It initializes video recording capabilities to capture the simulation. The function retrieves the positions of two tomatoes and a plate. 

The task consists of four main steps: first, it picks the first tomato from the table; second, it places that tomato onto the plate; third, it picks the second tomato from the table; and finally, it places the second tomato onto the plate. After each action, it checks if the task is completed and prints appropriate messages. 

Regardless of the outcome, the environment is shut down at the end of the task. The function is executed when the script is run as the main program.
Similarity: {'ok': False, 'reason': 'LLM JSON parsing failed.'}
Differences: 1. **Purpose**: TASK defines a planning problem in PDDL format, while CODE_FUNC describes a procedural function for simulating the task.
2. **Format**: TASK is structured in a declarative format (PDDL), whereas CODE_FUNC is written in an imperative programming style.
3. **Components**: TASK includes definitions of actions, predicates, and initial states, while CODE_FUNC focuses on the execution of actions in a sequence.
4. **Execution**: TASK does not specify how the actions are executed, only the conditions and effects, while CODE_FUNC explicitly describes the steps taken to perform the actions.
5. **Environment Setup**: TASK defines the environment and objects in a static manner, while CODE_FUNC includes dynamic elements like video recording and task completion checks.
6. **Output**: TASK does not produce output messages, while CODE_FUNC includes print statements to indicate progress and completion.
7. **Termination**: TASK does not specify how the task ends, while CODE_FUNC explicitly shuts down the environment at the end of the task.

Refined Code Generated:
-------------------
import numpy as np
from pyrep.objects.shape import Shape
from pyrep.objects.proximity_sensor import ProximitySensor

from env import setup_environment, shutdown_environment

from skill_code import pick, place
from video import init_video_writers, recording_step, recording_get_observation
from object_positions import get_object_positions

def run_skeleton_task():
    '''Generic skeleton for running any task in your simulation.'''
    print("===== Starting Skeleton Task =====")
    
    # === Environment Setup ===
    env, task = setup_environment()
    try:
        # Reset the task to its initial state
        descriptions, obs = task.reset()

        # (Optional) Initialize video writers for capturing your simulation
        init_video_writers(obs)

        # Wrap the task steps for recording (if needed)
        original_step = task.step
        task.step = recording_step(original_step)
        original_get_obs = task.get_observation
        task.get_observation = recording_get_observation(original_get_obs)

        # === Retrieve Object Positions ===
        positions = get_object_positions()

        # Define object positions
        tomato1_pos = positions['tomato1']
        plate_pos = positions['plate']

        # === Execute Task Plan ===
        # Step 1: Pick the first tomato
        print("[Task] Picking tomato1 from the table.")
        obs, reward, done = pick(
            env,
            task,
            target_pos=tomato1_pos,
            approach_distance=0.15,
            max_steps=100,
            threshold=0.01,
            approach_axis='z',
            timeout=10.0
        )
        if done:
            print("[Task] Task ended after picking tomato1!")
            return

        # Step 2: Place the first tomato onto the plate
        print("[Task] Placing tomato1 onto the plate.")
        obs, reward, done = place(
            env,
            task,
            target_pos=plate_pos,
            approach_distance=0.15,
            max_steps=100,
            threshold=0.01,
            approach_axis='z',
            timeout=10.0
        )
        if done:
            print("[Task] Task ended after placing tomato1!")
            return

        # Step 3: Pick the second tomato
        print("[Task] Picking tomato2 from the table.")
        obs, reward, done = pick(
            env,
            task,
            target_pos=positions['tomato2'],
            approach_distance=0.15,
            max_steps=100,
            threshold=0.01,
            approach_axis='z',
            timeout=10.0
        )
        if done:
            print("[Task] Task ended after picking tomato2!")
            return

        # Step 4: Place the second tomato onto the plate
        print("[Task] Placing tomato2 onto the plate.")
        obs, reward, done = place(
            env,
            task,
            target_pos=plate_pos,
            approach_distance=0.15,
            max_steps=100,
            threshold=0.01,
            approach_axis='z',
            timeout=10.0
        )
        if done:
            print("[Task] Task completed successfully! Reward:", reward)
        else:
            print("[Task] Task not completed yet (done=False).")

    finally:
        # Always ensure the environment is properly shutdown
        shutdown_environment(env)

    print("===== End of Skeleton Task =====")

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

