#![cfg_attr(docsrs, feature(doc_cfg))]
use gate_calc_log_bits::*;
use gategen::boolvar::*;
use gategen::dynintvar::*;
use gategen::generic_array::typenum::*;
use gategen::intvar::*;
use gategen::*;
use infmachine_config::*;
use std::fmt::Debug;
use std::ops::Neg;
pub use gategen;
pub use gategen::gatesim;
pub use gategen::gateutil;
pub use infmachine_config;
pub const DPMOVE_NOTHING: u8 = 0;
pub const DPMOVE_FORWARD: u8 = 1;
pub const DPMOVE_BACKWARD: u8 = 2;
pub const DPMOVE_BACKWARD_2: u8 = 3;
pub const DKIND_MEM_ADDRESS: u8 = 0;
pub const DKIND_TEMP_BUFFER: u8 = 1;
pub const DKIND_PROC_ID: u8 = 2;
pub const DKIND_PROC_ID_2: u8 = 3;
pub struct InfParInput<T: VarLit> {
pub state: DynIntVar<T, false>,
pub memval: DynIntVar<T, false>,
pub dpval: DynIntVar<T, false>,
pub dp_move_done: BoolVar<T>,
}
impl<T: VarLit> InfParInput<T>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
{
pub fn config(&self) -> InfParInterfaceConfig {
InfParInterfaceConfig {
cell_len_bits: u32::try_from(calc_log_bits(self.memval.bitnum())).unwrap(),
data_part_len: u32::try_from(self.dpval.bitnum()).unwrap(),
}
}
}
pub struct InfParMachineObject<T: VarLit> {
config: InfParInterfaceConfig,
env_config: InfParEnvConfig,
pub in_state: Option<DynIntVar<T, false>>,
pub in_memval: DynIntVar<T, false>,
pub in_dpval: DynIntVar<T, false>,
pub in_dp_move_done: BoolVar<T>,
pub out_state: Option<DynIntVar<T, false>>,
pub out_memval: Option<DynIntVar<T, false>>,
pub out_dpval: Option<DynIntVar<T, false>>,
pub memr: Option<BoolVar<T>>,
pub memw: Option<BoolVar<T>>,
pub dpr: Option<BoolVar<T>>,
pub dpw: Option<BoolVar<T>>,
pub dpmove: Option<IntVar<T, U2, false>>,
pub dkind: Option<IntVar<T, U2, false>>,
pub stop: Option<BoolVar<T>>,
}
impl<T> InfParMachineObject<T>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
{
pub fn from_dynintvar(&mut self, var: DynIntVar<T, false>) {
let cell_len = 1 << self.config.cell_len_bits;
let state_len = var.bitnum() - cell_len - (self.config.data_part_len as usize) - 9;
let vars = var.subvalues(
0,
[
state_len,
cell_len,
self.config.data_part_len as usize,
2,
2,
2,
2,
1,
],
);
self.out_state = Some(vars[0].clone());
self.out_memval = Some(vars[1].clone());
self.out_dpval = Some(vars[2].clone());
self.memr = Some(vars[3].bit(0));
self.memw = Some(vars[3].bit(1));
self.dpr = Some(vars[4].bit(0));
self.dpw = Some(vars[4].bit(1));
self.dpmove = Some(vars[5].clone().try_into().unwrap());
self.dkind = Some(vars[6].clone().try_into().unwrap());
self.stop = Some(vars[7].bit(0));
}
pub fn from_output(&mut self, output: InfParOutput<T>) {
assert_eq!(output.memval.bitnum(), 1 << self.config.cell_len_bits);
assert_eq!(output.dpval.bitnum(), self.config.data_part_len as usize);
self.out_state = Some(output.state);
self.out_memval = Some(output.memval);
self.out_dpval = Some(output.dpval);
self.memr = Some(output.memr);
self.memw = Some(output.memw);
self.dpr = Some(output.dpr);
self.dpw = Some(output.dpw);
self.dpmove = Some(output.dpmove);
self.dkind = Some(output.dkind);
self.stop = Some(output.stop);
}
pub fn input(&self) -> InfParInput<T> {
InfParInput {
state: self.in_state.clone().unwrap(),
memval: self.in_memval.clone(),
dpval: self.in_dpval.clone(),
dp_move_done: self.in_dp_move_done.clone(),
}
}
}
macro_rules! inf_par_machine_object_impl {
($tp:ty, $tp2:ty) => {
impl InfParMachineObject<$tp> {
pub fn new(config: InfParInterfaceConfig, env_config: InfParEnvConfig) -> Self {
config.valid().unwrap();
env_config.valid().unwrap();
Self {
config,
env_config,
in_state: None,
in_memval: DynIntVar::<$tp, false>::var(1 << config.cell_len_bits),
in_dpval: DynIntVar::<$tp, false>::var(config.data_part_len as usize),
in_dp_move_done: BoolVar::<$tp>::var(),
out_state: None,
out_memval: None,
out_dpval: None,
memr: None,
memw: None,
dpr: None,
dpw: None,
dpmove: None,
dkind: None,
stop: None,
}
}
pub fn to_machine(self) -> InfParMachineData<$tp2> {
let in_state_len = u32::try_from(self.in_state.as_ref().unwrap().bitnum()).unwrap();
let out_state_len =
u32::try_from(self.out_state.as_ref().unwrap().bitnum()).unwrap();
assert_eq!(in_state_len, out_state_len);
InfParMachineData {
config: (self.config, out_state_len).into(),
env_config: self.env_config,
circuit: self
.out_state
.unwrap()
.concat(self.out_memval.unwrap())
.concat(self.out_dpval.unwrap())
.concat(DynIntVar::<$tp, false>::from_iter([
self.memr.unwrap(),
self.memw.unwrap(),
self.dpr.unwrap(),
self.dpw.unwrap(),
self.dpmove.as_ref().unwrap().bit(0),
self.dpmove.as_ref().unwrap().bit(1),
self.dkind.as_ref().unwrap().bit(0),
self.dkind.as_ref().unwrap().bit(1),
self.stop.unwrap(),
]))
.to_translated_and_filled_circuit(
self.in_state
.unwrap()
.concat(self.in_memval)
.concat(self.in_dpval)
.concat(DynIntVar::<$tp, false>::filled(1, self.in_dp_move_done))
.iter(),
),
}
}
}
};
}
inf_par_machine_object_impl!(i16, u16);
inf_par_machine_object_impl!(i32, u32);
inf_par_machine_object_impl!(isize, usize);
#[derive(Clone)]
pub struct InfParOutput<T: VarLit> {
pub state: DynIntVar<T, false>,
pub memval: DynIntVar<T, false>,
pub dpval: DynIntVar<T, false>,
pub memr: BoolVar<T>,
pub memw: BoolVar<T>,
pub dpr: BoolVar<T>,
pub dpw: BoolVar<T>,
pub dpmove: IntVar<T, U2, false>,
pub dkind: IntVar<T, U2, false>,
pub stop: BoolVar<T>,
}
macro_rules! inf_par_output_impl {
($tp:ty) => {
impl InfParOutput<$tp> {
pub fn new(config: InfParInterfaceConfig) -> Self {
config.valid().unwrap();
Self {
state: DynIntVar::<$tp, false>::from_n(0u32, 1),
memval: DynIntVar::<$tp, false>::from_n(0u32, 1 << config.cell_len_bits),
dpval: DynIntVar::<$tp, false>::from_n(0u32, config.data_part_len as usize),
memr: BoolVar::<$tp>::from(false),
memw: BoolVar::<$tp>::from(false),
dpr: BoolVar::<$tp>::from(false),
dpw: BoolVar::<$tp>::from(false),
dpmove: IntVar::<$tp, U2, false>::from(0u32),
dkind: IntVar::<$tp, U2, false>::from(0u32),
stop: BoolVar::<$tp>::from(false),
}
}
pub fn fix_state_len(list: &mut [Self]) {
let max = list
.iter()
.map(|po| po.state.bitnum())
.max()
.unwrap_or_default();
for po in list {
if po.state.bitnum() < max {
po.state = po.state.clone().concat(DynIntVar::<$tp, false>::filled(
max - po.state.bitnum(),
BoolVar::from(false),
));
}
}
}
pub fn new_from_dynintvar(
config: InfParInterfaceConfig,
var: DynIntVar<$tp, false>,
) -> Self {
let cell_len = 1 << config.cell_len_bits;
let state_len = var.bitnum() - cell_len - (config.data_part_len as usize) - 9;
let vars = var.subvalues(
0,
[
state_len,
cell_len,
config.data_part_len as usize,
2,
2,
2,
2,
1,
],
);
Self {
state: vars[0].clone(),
memval: vars[1].clone(),
dpval: vars[2].clone(),
memr: vars[3].bit(0),
memw: vars[3].bit(1),
dpr: vars[4].bit(0),
dpw: vars[4].bit(1),
dpmove: vars[5].clone().try_into().unwrap(),
dkind: vars[6].clone().try_into().unwrap(),
stop: vars[7].bit(0),
}
}
}
};
}
inf_par_output_impl!(i16);
inf_par_output_impl!(i32);
inf_par_output_impl!(isize);
impl<T> InfParOutput<T>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
{
pub fn to_dynintvar(self) -> DynIntVar<T, false> {
self.state
.concat(self.memval)
.concat(self.dpval)
.concat(DynIntVar::<T, false>::from_iter([
self.memr,
self.memw,
self.dpr,
self.dpw,
self.dpmove.bit(0),
self.dpmove.bit(1),
self.dkind.bit(0),
self.dkind.bit(1),
self.stop,
]))
}
}
pub type InfParInput16 = InfParInput<i16>;
pub type InfParInput32 = InfParInput<i32>;
pub type InfParInputSys = InfParInput<isize>;
pub type InfParMachineObject16 = InfParMachineObject<i16>;
pub type InfParMachineObject32 = InfParMachineObject<i32>;
pub type InfParMachineObjectSys = InfParMachineObject<isize>;
pub type InfParOutput16 = InfParOutput<i16>;
pub type InfParOutput32 = InfParOutput<i32>;
pub type InfParOutputSys = InfParOutput<isize>;