// This an adjusted copy of the optimized PIL coming out of `test_data/asm/vm_to_block_different_length.asm`.
// We can remove this once the linker allows us to specify a machine with a variable degree.

namespace std::prover;
    enum Query {
        Hint(fe),
        Input(int, int),
        Output(int, int),
        None,
    }
namespace main(128);
    col witness _operation_id(i) query std::prelude::Query::Hint(6);
    col fixed _block_enforcer_last_step = [0]* + [1];
    (1 - main::_block_enforcer_last_step) * (1 - main::instr_return) * (main::_operation_id' - main::_operation_id) = 0;
    col witness pc;
    col witness X;
    col witness Y;
    col witness reg_write_Z_A;
    col witness A;
    col witness Z;
    col witness instr_add;
    col witness instr_mul;
    col witness instr_assert_eq;
    main::instr_assert_eq * (main::X - main::Y) = 0;
    col witness instr__jump_to_operation;
    col witness instr__reset;
    col witness instr__loop;
    col witness instr_return;
    col witness X_const;
    col witness read_X_A;
    main::X = main::read_X_A * main::A + main::X_const;
    col witness Y_const;
    main::Y = main::Y_const;
    col witness Z_read_free;
    main::Z = main::Z_read_free * main::Z_free_value;
    col fixed first_step = [1] + [0]*;
    main::A' = main::reg_write_Z_A * main::Z + (1 - (main::reg_write_Z_A + main::instr__reset)) * main::A;
    col pc_update = main::instr__jump_to_operation * main::_operation_id + main::instr__loop * main::pc + (1 - (main::instr__jump_to_operation + main::instr__loop + main::instr_return)) * (main::pc + 1);
    main::pc' = (1 - main::first_step') * main::pc_update;
    col witness Z_free_value;
    [main::pc, main::reg_write_Z_A, main::instr_add, main::instr_mul, main::instr_assert_eq, main::instr__jump_to_operation, main::instr__reset, main::instr__loop, main::instr_return, main::X_const, main::read_X_A, main::Y_const, main::Z_read_free] in [main__rom::p_line, main__rom::p_reg_write_Z_A, main__rom::p_instr_add, main__rom::p_instr_mul, main__rom::p_instr_assert_eq, main__rom::p_instr__jump_to_operation, main__rom::p_instr__reset, main__rom::p_instr__loop, main__rom::p_instr_return, main__rom::p_X_const, main__rom::p_read_X_A, main__rom::p_Y_const, main__rom::p_Z_read_free];
    main::instr_add $ [0, main::X, main::Y, main::Z] in [main_arith::operation_id, main_arith::x[0], main_arith::x[1], main_arith::y];
    main::instr_mul $ [1, main::X, main::Y, main::Z] in [main_arith::operation_id, main_arith::x[0], main_arith::x[1], main_arith::y];
    col fixed _linker_first_step = [1] + [0]*;
    main::_linker_first_step * (main::_operation_id - 2) = 0;
namespace main__rom(8);
    col fixed p_line = [0, 1, 2, 3, 4, 5, 6] + [6]*;
    col fixed p_X_const = [0, 0, 2, 0, 0, 0, 0] + [0]*;
    col fixed p_Y_const = [0, 0, 1, 9, 27, 0, 0] + [0]*;
    col fixed p_Z_read_free = [0, 0, 1, 1, 0, 0, 0] + [0]*;
    col fixed p_instr__jump_to_operation = [0, 1, 0, 0, 0, 0, 0] + [0]*;
    col fixed p_instr__loop = [0, 0, 0, 0, 0, 0, 1] + [1]*;
    col fixed p_instr__reset = [1, 0, 0, 0, 0, 0, 0] + [0]*;
    col fixed p_instr_add = [0, 0, 1, 0, 0, 0, 0] + [0]*;
    col fixed p_instr_assert_eq = [0, 0, 0, 0, 1, 0, 0] + [0]*;
    col fixed p_instr_mul = [0, 0, 0, 1, 0, 0, 0] + [0]*;
    col fixed p_instr_return = [0, 0, 0, 0, 0, 1, 0] + [0]*;
    col fixed p_read_X_A = [0, 0, 0, 1, 1, 0, 0] + [0]*;
    col fixed p_reg_write_Z_A = [0, 0, 1, 1, 0, 0, 0] + [0]*;

// CHANGED HERE: The degree of this namespace is a range, meaning that this machine has a variable size.
namespace main_arith(8..64);
    col witness operation_id;
    col witness x[2];
    col witness y;
    main_arith::y = main_arith::operation_id * (main_arith::x[0] * main_arith::x[1]) + (1 - main_arith::operation_id) * (main_arith::x[0] + main_arith::x[1]);
