# Boolean Circuit Family Implementation Task

## Definitions and Background

In our task:
- A **boolean circuit** is an acyclic computational structure with fixed 0/1 bit inputs, composed of AND/OR/NOT logic gates. Each gate receives inputs either from input wires or from outputs of other gates.
- The task is to write the code of the game platform. The player will use the platform to gain information with the circuit, and try to guess the function of the circuit.

## Task Overview

Your objective is to formalize a player-blackbox interaction process into runnable Python code. Focus on implementing three key components:

1. **Circuit Function**: Implement a function that constructs the circuit according to the language description, given the input wires and returns the output of each gate.

2. **Main Function**: Implement the core interaction loop between the LLM player and the blackbox.

## Detailed Coding Instructions

### Required Imports
Begin by importing these packages:
```python
import os
import sys
current_path = os.path.abspath(__file__)
oracle_path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(current_path))))
if oracle_path not in sys.path:
    sys.path.insert(0, oracle_path)
from ckpt import simulate_circuit
from eva_models import ReasoningLLM
import re
```

### Circuit Generator Function
Implement `blackbox(circuit_input)` where:
- `circuit_input` are the 0/1 bits of the input wires
- Returns `gate_output` describing the 0/1 bits of each gate output
- The circuit's purpose is {algorithm}
- Construction details: {description}
- In `blackbox`, you should construct `gates`, and then use `simulate_circuit` to generate the response (see Interface Details section)
- **Important**: Verify that your gate construction achieves the stated goal and follows the description exactly

### Main Function
Implement `main(model_family, model_name, task, eva_mode, n_runs, difficulty, task_id, failure_num, output_dir, max_turns, version, mode, thinking_mode)` where:
1. Instantiate the `ReasoningLLM` class:
   ```python
   player = ReasoningLLM(model_family, model_name, task, eva_mode, n_runs, difficulty, task_id, thinking_mode, mode)
   ```

2. Create an interaction loop for `max_turns` iterations:
   - Call `player_output = player.normal_output(blackbox_output)` to send the message `blackbox_output` to the player, and get the player's output.
   - `blackbox_output` should append the remain rounds for interaction.
   - For the first iteration, `blackbox_output` should be a prompt telling player the game begin.
   - For every `player_output`, try to parse it into a 0/1 list as `circuit_input`
   - If the parsing succeeds, `blackbox_output = platform(circuit_input)` in the next iteration, otherwise `blackbox_output` should remind the player follows the format.

3. After the loop completes:
   - `player_output = player.normal_output(blackbox_output)` to give the last answer of the player. 
   - Call `player.evaluate(failure_num, version)`
   - Call `player.save_history(output_dir, version)`

4. Add an entry point at the end of the program:
   ```python
   if __name__ == "__main__":
       args = sys.argv[1:]
       main(args[0], args[1], args[2], args[3], int(args[4]), args[5], args[6], int(args[7]), 
            args[8], int(args[9]), int(args[10]), args[11], bool(eval(args[12])))
   ```

## Circuit Details

- `AND` and `OR` gates always require exactly two inputs
- `NOT` gates always require exactly one input
- A gate's output or an input wire can be used as input to multiple other gates without restriction
- Circuits must be acyclic: for the i-th gate, all inputs must come from either input wires or outputs of gates with indices smaller than i
- The index of the gate is from $1$ to $m$, where $m$ is the number of gates.

## Interface Details

Use `simulate_circuit(n, m, input, gates)` as follows:

```python
'''
    Returns a list of the gates' outputs, or a string containing an error message
    Parameters:
    n: number of input wires
    m: number of gates
    input: list of input values (0 or 1)
    gates: list of tuples, each tuple contains gate type and its inputs
           - gate type: 'AND', 'OR', 'NOT'
           - inputs: (0, i) means the input wire i
                    (1, j) means the output of gate j
                    Note that every index begins from 1 (i, j>=1)

    Examples:
    - ('AND', (0, 1), (0, 2)) means AND gate taking input wires 1 and 2
    - ('NOT', (1, 3)) means NOT gate taking the output of gate 3

    Example usage:

    gates = [
        ('AND', (0, 1), (0, 2)),
        ('AND', (0, 3), (1, 1)),
        ('OR', (0, 4), (1, 2)),
        ('NOT', (1, 3)),
        ('NOT', (0, 5))
    ]

    input = [1, 1, 0, 1, 0]

    simulate_circuit(5, 5, input, gates) # Returns [1, 0, 1, 0, 1]
'''
def simulate_circuit(n, m, input_wires, gates) -> str | list:
    # Implementation details omitted
```

## Development Tips
- Focus only on producing runnable code without additional text output
- Verify your implementation step-by-step
- Ensure the circuit generator correctly implements the specified algorithm
- Validate that the platform function properly handles all input formats