use std::collections::{BTreeMap, HashSet};
use std::convert::Infallible;
use std::hash::Hash;
use super::*;
pub trait LabelJoin<Rhs: ?Sized = Self> {
fn label_join(&mut self, rhs: &Rhs);
}
impl LabelJoin<str> for String {
fn label_join(&mut self, rhs: &str) {
self.push_str(rhs);
}
}
impl<Rhs: ToString> LabelJoin<Rhs> for String {
fn label_join(&mut self, rhs: &Rhs) {
self.push_str(&rhs.to_string());
}
}
impl<T: Clone> LabelJoin<Vec<T>> for Vec<T> {
fn label_join(&mut self, rhs: &Vec<T>) {
self.extend_from_slice(rhs.as_slice());
}
}
impl<T: Clone> LabelJoin<[T]> for Vec<T> {
fn label_join(&mut self, rhs: &[T]) {
self.extend_from_slice(rhs);
}
}
pub trait DefaultSep {
fn default_sep() -> Self;
}
impl DefaultSep for &str {
fn default_sep() -> Self {
":"
}
}
impl DefaultSep for String {
fn default_sep() -> Self {
":".to_string()
}
}
impl<T: DefaultSep> DefaultSep for Vec<T> {
fn default_sep() -> Self {
vec![T::default_sep()]
}
}
pub type LabelPos<Label> = (Label, bool);
pub trait MinInfLabelTrait<Label> {
type Error;
fn add_label<L: Clone + Debug>(&mut self, label: L)
where
Self::Error: Debug,
Label: From<L>,
{
self.try_add_label(label).unwrap();
}
fn try_add_label<L: Clone + Debug>(&mut self, label: L) -> Result<(), Self::Error>
where
Label: From<L>;
fn get_label_map(&self) -> &BTreeMap<Label, usize>;
fn l<L: Clone + Debug>(&mut self, label: L)
where
Self::Error: Debug,
Label: From<L>,
{
self.add_label(label);
}
}
pub trait MinInfBuilderTrait<Label, Instr> {
type Error;
fn add_instr<I>(&mut self, instr: I)
where
Self::Error: Debug,
Instr: From<I>,
{
self.try_add_instr(instr).unwrap();
}
fn try_add_instr<I>(&mut self, instr: I) -> Result<(), Self::Error>
where
Instr: From<I>;
fn i<I>(&mut self, instr: I)
where
Self::Error: Debug,
Instr: From<I>,
{
self.add_instr(instr)
}
}
pub trait MinInfChangeLabelTrait<Label> {
fn change_labels<F: Fn(&Label) -> Label>(&mut self, f: F, only_defined: bool);
}
pub trait MinInfCodeTrait<Label, Instr> {
fn get_code(&self) -> &Vec<Instr>;
}
pub trait MinInfJoinTrait {
type Error;
fn join(&mut self, second: Self) -> Result<(), Self::Error>
where
Self: Sized;
}
pub trait MinInfToCodeTrait<Label, Instr> {
type Error;
fn try_to_code(self) -> Result<(Vec<Instr>, Vec<(Label, usize)>), Self::Error>
where
Self: Sized;
fn to_code(self) -> (Vec<Instr>, Vec<(Label, usize)>)
where
Self: Sized,
Self::Error: Debug,
{
self.try_to_code().unwrap()
}
}
pub trait MinInfStateNumTrait {
fn state_num(&self) -> usize;
fn switch(&mut self, state_num: usize) -> usize;
}
pub trait MinInfMultiAppendTrait {
type Error;
fn try_multi_append<'a, I>(&mut self, appends: I) -> Result<(), Self::Error>
where
I: IntoIterator<Item = (usize, &'a Self)>,
Self: 'a;
fn multi_append<'a, I>(&mut self, appends: I)
where
I: IntoIterator<Item = (usize, &'a Self)>,
Self: 'a,
Self::Error: Debug,
{
self.try_multi_append(appends).unwrap();
}
}
#[derive(Clone, Default, Debug, PartialEq, Eq)]
pub struct MinInfRel<Label> {
pub label: Option<Label>,
pub offset: isize,
}
impl<Label> From<isize> for MinInfRel<Label> {
fn from(o: isize) -> Self {
MinInfRel {
label: None,
offset: o,
}
}
}
impl<'a> From<&'a str> for MinInfRel<String> {
fn from(s: &'a str) -> Self {
MinInfRel {
label: Some(s.into()),
offset: 0,
}
}
}
impl<'a> From<(&'a str, isize)> for MinInfRel<String> {
fn from(s: (&'a str, isize)) -> Self {
MinInfRel {
label: Some(s.0.into()),
offset: s.1,
}
}
}
impl From<String> for MinInfRel<String> {
fn from(s: String) -> Self {
MinInfRel {
label: Some(s),
offset: 0,
}
}
}
impl From<&String> for MinInfRel<String> {
fn from(s: &String) -> Self {
MinInfRel {
label: Some(s.clone()),
offset: 0,
}
}
}
impl<Label> From<(Label, isize)> for MinInfRel<Label> {
fn from(s: (Label, isize)) -> Self {
MinInfRel {
label: Some(s.0),
offset: s.1,
}
}
}
impl<Label> MinInfRel<Label> {
#[inline]
pub fn new(label: Label, offset: isize) -> Self {
Self {
label: Some(label),
offset,
}
}
#[inline]
pub fn cur() -> Self {
Self {
label: None,
offset: 0,
}
}
#[inline]
pub fn next() -> Self {
Self {
label: None,
offset: 1,
}
}
#[inline]
pub fn rel(offset: isize) -> Self {
Self {
label: None,
offset,
}
}
}
#[derive(Clone, Debug, thiserror::Error)]
pub enum MinInfBuildResolveError {
#[error("Offset out of range")]
OutOfRange,
#[error("Conversion error: {0}")]
ConversionError(#[from] std::num::TryFromIntError),
#[error("Label {0} not found")]
LabelNotFound(String),
}
impl<Label> MinInfRel<Label>
where
Label: Clone + PartialEq + Eq + PartialOrd + Ord + ToString,
{
pub fn resolve(
&self,
cur_pos: usize,
map: &[(Label, usize)],
) -> Result<usize, MinInfBuildResolveError> {
if let Some(label) = &self.label {
map.binary_search_by_key(label, |(l, _)| l.clone())
.map(|x| {
usize::try_from(
isize::try_from(map[x].1)
.unwrap()
.checked_add(self.offset)
.unwrap(),
)
.unwrap()
})
.map_err(|_| MinInfBuildResolveError::LabelNotFound(label.to_string()))
} else {
Ok(usize::try_from(
isize::try_from(cur_pos)?
.checked_add(self.offset)
.ok_or(MinInfBuildResolveError::OutOfRange)?,
)?)
}
}
}
pub trait TryIntoInstr<Label> {
type Error;
fn try_resolve_jumps_to_multi_instr(
&self,
cur_pos: usize,
map: &[(Label, usize)],
) -> Result<Vec<usize>, Self::Error>;
fn try_into_instr(
self,
cur_pos: usize,
map: &[(Label, usize)],
) -> Result<MinInfInstr, Self::Error>;
}
pub trait CheckInstrAssertions {
type Error;
fn check_assertions(&self, jump: usize, instr2: &Self) -> Result<(), Self::Error>;
}
pub trait MinInfBuildInstrTrait<Label> {
fn get_func_fr0(&self) -> MinInfFunc;
fn get_func_fr1(&self) -> MinInfFunc;
fn get_next_fr0(&self) -> MinInfRel<Label>;
fn get_next_fr1(&self) -> MinInfRel<Label>;
fn set_next_fr0_label(&mut self, label: Option<Label>);
fn set_next_fr1_label(&mut self, label: Option<Label>);
}
#[derive(Clone, Default, Debug, PartialEq, Eq)]
pub struct MinInfBuildInstr<Label> {
pub func_fr0: MinInfFunc,
pub func_fr1: MinInfFunc,
pub next_fr0: MinInfRel<Label>,
pub next_fr1: MinInfRel<Label>,
}
impl<Label: Clone> MinInfBuildInstr<Label> {
pub fn new<IntoRel1, IntoRel2>(
func0: MinInfFunc,
func1: MinInfFunc,
next0: IntoRel1,
next1: IntoRel2,
) -> Self
where
MinInfRel<Label>: From<IntoRel1>,
MinInfRel<Label>: From<IntoRel2>,
{
Self {
func_fr0: func0,
func_fr1: func1,
next_fr0: next0.into(),
next_fr1: next1.into(),
}
}
pub fn new_01<IntoRel: Clone>(func: MinInfFunc, next: IntoRel) -> Self
where
MinInfRel<Label>: From<IntoRel>,
{
Self {
func_fr0: func,
func_fr1: func,
next_fr0: next.clone().into(),
next_fr1: next.into(),
}
}
pub fn new_next01<IntoRel: Clone>(func0: MinInfFunc, func1: MinInfFunc, next: IntoRel) -> Self
where
MinInfRel<Label>: From<IntoRel>,
{
Self {
func_fr0: func0,
func_fr1: func1,
next_fr0: next.clone().into(),
next_fr1: next.into(),
}
}
pub fn new_func01<IntoRel1, IntoRel2>(
func: MinInfFunc,
next0: IntoRel1,
next1: IntoRel2,
) -> Self
where
MinInfRel<Label>: From<IntoRel1>,
MinInfRel<Label>: From<IntoRel2>,
{
Self {
func_fr0: func,
func_fr1: func,
next_fr0: next0.into(),
next_fr1: next1.into(),
}
}
}
impl<Label: Clone> MinInfBuildInstrTrait<Label> for MinInfBuildInstr<Label> {
fn get_func_fr0(&self) -> MinInfFunc {
self.func_fr0
}
fn get_func_fr1(&self) -> MinInfFunc {
self.func_fr1
}
fn get_next_fr0(&self) -> MinInfRel<Label> {
self.next_fr0.clone()
}
fn get_next_fr1(&self) -> MinInfRel<Label> {
self.next_fr1.clone()
}
fn set_next_fr0_label(&mut self, label: Option<Label>) {
self.next_fr0.label = label;
}
fn set_next_fr1_label(&mut self, label: Option<Label>) {
self.next_fr1.label = label;
}
}
impl<Label> MinInfBuildInstr<Label> {
pub fn newp(func0: MinInfFunc, func1: MinInfFunc) -> Self {
Self {
func_fr0: func0,
func_fr1: func1,
next_fr0: MinInfRel::<Label>::next(),
next_fr1: MinInfRel::<Label>::next(),
}
}
pub fn newp_01(func: MinInfFunc) -> Self {
Self {
func_fr0: func,
func_fr1: func,
next_fr0: MinInfRel::<Label>::next(),
next_fr1: MinInfRel::<Label>::next(),
}
}
}
impl<Label> TryIntoInstr<Label> for MinInfBuildInstr<Label>
where
Label: Clone + PartialEq + Eq + PartialOrd + Ord + ToString,
{
type Error = MinInfBuildResolveError;
fn try_resolve_jumps_to_multi_instr(
&self,
cur_pos: usize,
map: &[(Label, usize)],
) -> Result<Vec<usize>, Self::Error> {
Ok(vec![
self.next_fr0.resolve(cur_pos, map)?,
self.next_fr1.resolve(cur_pos, map)?,
])
}
fn try_into_instr(
self,
cur_pos: usize,
map: &[(Label, usize)],
) -> Result<MinInfInstr, MinInfBuildResolveError> {
Ok(MinInfInstr::new(
self.func_fr0,
self.func_fr1,
self.next_fr0.resolve(cur_pos, map)?,
self.next_fr1.resolve(cur_pos, map)?,
))
}
}
impl<Label> CheckInstrAssertions for MinInfBuildInstr<Label> {
type Error = Infallible;
fn check_assertions(&self, _: usize, _: &Self) -> Result<(), Self::Error> {
Ok(())
}
}
impl<Label> From<MinInfFunc> for MinInfBuildInstr<Label> {
fn from(f: MinInfFunc) -> Self {
Self::newp_01(f)
}
}
impl<Label> From<(MinInfFunc, MinInfFunc)> for MinInfBuildInstr<Label> {
fn from(f: (MinInfFunc, MinInfFunc)) -> Self {
Self::newp(f.0, f.1)
}
}
impl<Label, IntoRel> From<(MinInfFunc, IntoRel)> for MinInfBuildInstr<Label>
where
Label: Clone,
IntoRel: Clone,
MinInfRel<Label>: From<IntoRel>,
{
fn from(f: (MinInfFunc, IntoRel)) -> Self {
Self::new_01(f.0, f.1)
}
}
impl<Label, IntoRel> From<(MinInfFunc, MinInfFunc, IntoRel)> for MinInfBuildInstr<Label>
where
Label: Clone,
IntoRel: Clone,
MinInfRel<Label>: From<IntoRel>,
{
fn from(f: (MinInfFunc, MinInfFunc, IntoRel)) -> Self {
Self::new_next01(f.0, f.1, f.2)
}
}
impl<Label, IntoRel, IntoRel2> From<(MinInfFunc, IntoRel, IntoRel2)> for MinInfBuildInstr<Label>
where
Label: Clone,
MinInfRel<Label>: From<IntoRel>,
MinInfRel<Label>: From<IntoRel2>,
{
fn from(f: (MinInfFunc, IntoRel, IntoRel2)) -> Self {
Self::new_func01(f.0, f.1, f.2)
}
}
impl<Label, IntoRel, IntoRel2> From<(MinInfFunc, MinInfFunc, IntoRel, IntoRel2)>
for MinInfBuildInstr<Label>
where
Label: Clone,
MinInfRel<Label>: From<IntoRel>,
MinInfRel<Label>: From<IntoRel2>,
{
fn from(f: (MinInfFunc, MinInfFunc, IntoRel, IntoRel2)) -> Self {
Self::new(f.0, f.1, f.2, f.3)
}
}
#[derive(Clone, Debug)]
pub struct MinInfBuilder<Label, Instr> {
code: Vec<Instr>,
label_map: BTreeMap<Label, usize>,
}
impl<Label, Instr> Default for MinInfBuilder<Label, Instr> {
fn default() -> Self {
Self::new()
}
}
impl<Label, Instr> MinInfBuilder<Label, Instr> {
pub fn new() -> Self {
Self {
code: vec![],
label_map: BTreeMap::new(),
}
}
}
impl<Label, Instr> MinInfBuilderTrait<Label, Instr> for MinInfBuilder<Label, Instr>
where
Label: Clone,
{
type Error = Infallible;
fn try_add_instr<I>(&mut self, instr: I) -> Result<(), Infallible>
where
Instr: From<I>,
{
self.code.push(instr.into());
Ok(())
}
}
#[derive(Clone, Debug, thiserror::Error)]
pub enum MinInfLabelError<Label> {
#[error("Label {0} already exists")]
LabelAlreadyExists(Label),
}
impl<Label, Instr> MinInfLabelTrait<Label> for MinInfBuilder<Label, Instr>
where
Label: Clone + Debug + PartialEq + Eq + Ord,
{
type Error = MinInfLabelError<Label>;
fn try_add_label<L: Clone + Debug>(&mut self, label: L) -> Result<(), Self::Error>
where
Label: From<L>,
{
if self
.label_map
.insert(label.clone().into(), self.code.len())
.is_some()
{
return Err(Self::Error::LabelAlreadyExists(label.clone().into()));
}
Ok(())
}
fn get_label_map(&self) -> &BTreeMap<Label, usize> {
&self.label_map
}
}
#[derive(Clone, Debug, thiserror::Error)]
pub enum MinInfBuildToCodeError<RError, CAError> {
#[error("Resolve error: {0}")]
Resolve(#[from] RError),
#[error("Assertion error: {0}")]
Assertion(CAError),
#[error("Nexts out of range: {0}: {1}")]
NextOutOfRange(usize, String),
}
impl<Label, Instr> MinInfToCodeTrait<Label, MinInfInstr> for MinInfBuilder<Label, Instr>
where
Label: Clone + Debug + PartialEq + Eq + Hash + PartialOrd + Ord + ToString,
Instr: Debug + TryIntoInstr<Label> + CheckInstrAssertions,
{
type Error = MinInfBuildToCodeError<
<Instr as TryIntoInstr<Label>>::Error,
<Instr as CheckInstrAssertions>::Error,
>;
fn try_to_code(self) -> Result<(Vec<MinInfInstr>, Vec<(Label, usize)>), Self::Error> {
let mut out_map = self.label_map.into_iter().collect::<Vec<_>>();
let code_len = self.code.len();
out_map.sort_by_key(|(k, _)| k.clone());
for (i, instr) in self.code.iter().enumerate() {
let jumps = instr.try_resolve_jumps_to_multi_instr(i, &out_map)?;
for (ji, j) in jumps.into_iter().enumerate() {
if j < code_len {
instr
.check_assertions(ji, &self.code[j])
.map_err(|x| MinInfBuildToCodeError::Assertion(x))?;
}
}
}
let mut out_code = self
.code
.into_iter()
.enumerate()
.map(|(i, x)| x.try_into_instr(i, &out_map))
.collect::<Result<Vec<_>, _>>()?;
let code_len = out_code.len();
for instr in &mut out_code {
if instr.func_fr0.is_stop() {
if instr.next_fr0 >= code_len {
instr.next_fr0 = 0;
}
}
if instr.func_fr1.is_stop() {
if instr.next_fr1 >= code_len {
instr.next_fr1 = 0;
}
}
}
if let Some(p) = out_code
.iter()
.position(|x| !(x.next_fr0 < code_len && x.next_fr1 < code_len))
{
Err(MinInfBuildToCodeError::NextOutOfRange(
p,
format!("{:?}", out_code[p]),
))
} else {
Ok((out_code, out_map))
}
}
}
#[derive(Clone, Debug, thiserror::Error)]
pub enum MinInfMultiAppendError {
#[error("Position duplicates")]
PositionDuplicates,
#[error("Label already exists: {0}")]
LabelAlreadyExists(String),
#[error("Append out of ragne: {0}: {1}")]
AppendOutOfRange(usize, usize),
#[error("Position out of range: {0} {1}")]
OutOfRange(usize, usize),
}
impl<Label, Instr: Clone> MinInfMultiAppendTrait for MinInfBuilder<Label, Instr>
where
Label: Clone + Debug + PartialEq + Eq + Ord + ToString,
{
type Error = MinInfMultiAppendError;
fn try_multi_append<'a, I>(&mut self, appends: I) -> Result<(), Self::Error>
where
I: IntoIterator<Item = (usize, &'a Self)>,
Self: 'a,
{
let appends = {
let mut appends = appends.into_iter().collect::<Vec<_>>();
appends.sort_by_key(|(pos, _)| *pos);
let old_appends_len = appends.len();
appends.dedup_by_key(|(pos, _)| *pos);
if old_appends_len != appends.len() {
return Err(MinInfMultiAppendError::PositionDuplicates);
}
appends
};
let mut labels = {
let mut labels = self
.label_map
.iter()
.map(|(l, p)| (l.clone(), *p))
.collect::<Vec<_>>();
labels.sort_by_key(|(_, pos)| *pos);
labels
};
let code_len = self.code.len();
let mut cur_pos = 0;
let mut shift = 0;
let mut new_code = Vec::<Instr>::new();
let mut lpos = labels
.binary_search_by_key(&0, |(_, pos)| *pos)
.unwrap_or_else(|e| e);
let mut new_shifts = vec![];
for (i, (pos, append)) in appends.iter().enumerate() {
if *pos > code_len {
return Err(MinInfMultiAppendError::AppendOutOfRange(i, *pos));
}
let add = append.code.len();
new_code.extend_from_slice(&self.code[cur_pos..*pos]);
new_shifts.push(new_code.len());
new_code.extend_from_slice(&append.code);
let next_pos = pos
.checked_add(1)
.ok_or(MinInfMultiAppendError::OutOfRange(*pos, 1))?;
let nlpos = labels
.binary_search_by_key(&next_pos, |(_, xpos)| *xpos)
.unwrap_or_else(|e| e);
for (_, pos) in &mut labels[lpos..nlpos] {
*pos = pos
.checked_add(shift)
.ok_or(MinInfMultiAppendError::OutOfRange(*pos, shift))?;
}
cur_pos = *pos;
shift = shift
.checked_add(add)
.ok_or(MinInfMultiAppendError::OutOfRange(shift, add))?;
lpos = nlpos;
}
for (_, pos) in &mut labels[lpos..] {
*pos = pos
.checked_add(shift)
.ok_or(MinInfMultiAppendError::OutOfRange(*pos, shift))?;
}
new_code.extend_from_slice(&self.code[cur_pos..]);
self.code = new_code;
for ((_, append), new_shift) in appends.into_iter().zip(new_shifts.into_iter()) {
for (k, v) in &append.label_map {
if self.label_map.contains_key(k) {
return Err(MinInfMultiAppendError::LabelAlreadyExists(k.to_string()));
}
let new_p = v
.checked_add(new_shift)
.ok_or(MinInfMultiAppendError::OutOfRange(*v, new_shift))?;
labels.push((k.clone(), new_p));
}
}
let new_label_map = labels.into_iter().collect::<BTreeMap<_, _>>();
self.label_map = new_label_map;
Ok(())
}
}
impl<Label, Instr> MinInfCodeTrait<Label, Instr> for MinInfBuilder<Label, Instr> {
fn get_code(&self) -> &Vec<Instr> {
&self.code
}
}
impl<Label, Instr> MinInfChangeLabelTrait<Label> for MinInfBuilder<Label, Instr>
where
Label: Hash + PartialEq + Eq + Ord,
Instr: MinInfBuildInstrTrait<Label>,
{
fn change_labels<F: Fn(&Label) -> Label>(&mut self, f: F, only_defined: bool) {
for instr in self.code.iter_mut() {
let next_fr0 = instr.get_next_fr0();
if let Some(label) = next_fr0.label.as_ref() {
if !only_defined || self.label_map.contains_key(label) {
instr.set_next_fr0_label(Some(f(label)));
}
}
let next_fr1 = instr.get_next_fr1();
if let Some(label) = next_fr1.label.as_ref() {
if !only_defined || self.label_map.contains_key(label) {
instr.set_next_fr1_label(Some(f(label)));
}
}
}
let new_label_map = self
.label_map
.iter()
.map(|(k, v)| (f(&k), *v))
.collect::<BTreeMap<_, _>>();
self.label_map = new_label_map;
}
}
#[derive(Clone, Copy, Debug, thiserror::Error)]
pub enum MinInfBuilderJoinError<Label> {
#[error("Label {0} already exists")]
LabelAlreadyExists(Label),
#[error("Movement of postion {0} causes overflow")]
OverflowAfterMove(Label),
}
impl<Label, Instr> MinInfJoinTrait for MinInfBuilder<Label, Instr>
where
Label: Clone + Debug + PartialEq + Eq + Ord,
{
type Error = MinInfBuilderJoinError<Label>;
fn join(&mut self, second: Self) -> Result<(), Self::Error> {
let cur_size = self.code.len();
self.code.extend(second.code);
for (k, v) in second.label_map {
if !self.label_map.contains_key(&k) {
let sum = v
.checked_add(cur_size)
.ok_or(MinInfBuilderJoinError::OverflowAfterMove(k.clone()))?;
self.label_map.insert(k, sum);
} else {
return Err(MinInfBuilderJoinError::LabelAlreadyExists(k));
}
}
Ok(())
}
}
pub fn exact_label_occurrence_map<Builder, Label, Instr>(
builder: &Builder,
) -> BTreeMap<Label, Vec<MinInfPos>>
where
Builder: MinInfLabelTrait<Label> + MinInfCodeTrait<Label, Instr>,
Label: Clone + Debug + PartialEq + Eq + Hash + PartialOrd + Ord + ToString,
Instr: MinInfBuildInstrTrait<Label>,
{
let mut occur_map = BTreeMap::<Label, Vec<MinInfPos>>::new();
for (i, instr) in builder.get_code().iter().enumerate() {
let next_fr0 = instr.get_next_fr0();
let next_fr1 = instr.get_next_fr1();
if let Some(label_fr0) = next_fr0.label {
if next_fr0.offset == 0 {
if let Some(list) = occur_map.get_mut(&label_fr0) {
list.push((i, false));
} else {
occur_map.insert(label_fr0, vec![(i, false)]);
}
}
}
if let Some(label_fr1) = next_fr1.label {
if next_fr1.offset == 0 {
if let Some(list) = occur_map.get_mut(&label_fr1) {
list.push((i, true));
} else {
occur_map.insert(label_fr1, vec![(i, true)]);
}
}
}
}
occur_map
}
pub fn exact_label_occurence_set<Builder, Label, Instr>(builder: &Builder) -> HashSet<Label>
where
Builder: MinInfLabelTrait<Label> + MinInfCodeTrait<Label, Instr>,
Label: Clone + Debug + PartialEq + Eq + Hash + PartialOrd + Ord + ToString,
Instr: MinInfBuildInstrTrait<Label>,
{
let mut occur_set = HashSet::<Label>::new();
for instr in builder.get_code() {
let next_fr0 = instr.get_next_fr0();
let next_fr1 = instr.get_next_fr1();
if let Some(label_fr0) = next_fr0.label {
if next_fr0.offset == 0 {
occur_set.insert(label_fr0.clone());
}
}
if let Some(label_fr1) = next_fr1.label {
if next_fr1.offset == 0 {
occur_set.insert(label_fr1.clone());
}
}
}
occur_set
}
#[derive(Clone, Default, Debug, PartialEq, Eq)]
pub struct MinInfRelSV<Label> {
pub rel: MinInfRel<Label>,
pub value: Option<usize>, pub next_state_num: Option<usize>, }
impl<Label> MinInfRelSV<Label> {
pub fn new(rel: MinInfRel<Label>, value: usize, next_state_num: usize) -> Self {
MinInfRelSV {
rel,
value: Some(value),
next_state_num: Some(next_state_num),
}
}
pub fn new_default(rel: MinInfRel<Label>, next_state_num: usize) -> Self {
MinInfRelSV {
rel,
value: None,
next_state_num: Some(next_state_num),
}
}
pub fn new_default2(rel: MinInfRel<Label>) -> Self {
MinInfRelSV {
rel,
value: None,
next_state_num: None,
}
}
}
impl<Label> MinInfRelSV<Label>
where
Label: Clone + PartialEq + Eq + PartialOrd + Ord + ToString,
{
pub fn resolve(
&self,
cur_pos: usize,
map: &[(Label, usize)],
cur_value: usize,
) -> Result<usize, MinInfBuildResolveError> {
self.rel.resolve(cur_pos - cur_value, map)
}
}
impl<Label, S> From<S> for MinInfRelSV<Label>
where
MinInfRel<Label>: From<S>,
{
fn from(s: S) -> Self {
Self::new_default2(s.into())
}
}
impl<Label, S> From<(S, usize)> for MinInfRelSV<Label>
where
MinInfRel<Label>: From<S>,
{
fn from(s: (S, usize)) -> Self {
Self::new_default(s.0.into(), s.1)
}
}
impl<Label, S> From<(S, usize, usize)> for MinInfRelSV<Label>
where
MinInfRel<Label>: From<S>,
{
fn from(s: (S, usize, usize)) -> Self {
Self::new(s.0.into(), s.1, s.2)
}
}
#[derive(Clone, Default, Debug, PartialEq, Eq)]
pub struct MinInfBInstrSingleSVInt<Label: Debug> {
func_fr0: MinInfFunc,
func_fr1: MinInfFunc,
next_fr0: MinInfRelSV<Label>,
next_fr1: MinInfRelSV<Label>,
value: usize,
state_num: usize,
}
impl<Label: Debug> MinInfBInstrSingleSVInt<Label> {
pub fn new<IntoRel1, IntoRel2>(
func0: MinInfFunc,
func1: MinInfFunc,
next0: IntoRel1,
next1: IntoRel2,
value: usize,
state_num: usize,
) -> Self
where
MinInfRelSV<Label>: From<IntoRel1>,
MinInfRelSV<Label>: From<IntoRel2>,
{
let next0 = MinInfRelSV::<Label>::from(next0);
let next1 = MinInfRelSV::<Label>::from(next1);
if let Some(value) = next0.value {
if let Some(next_state_num) = next0.next_state_num {
assert!(value < next_state_num);
}
}
if let Some(value) = next1.value {
if let Some(next_state_num) = next1.next_state_num {
assert!(value < next_state_num);
}
}
Self {
func_fr0: func0,
func_fr1: func1,
next_fr0: next0,
next_fr1: next1,
value,
state_num,
}
}
}
impl<Label> TryIntoInstr<Label> for MinInfBInstrSingleSVInt<Label>
where
Label: Clone + Debug + PartialEq + Eq + PartialOrd + Ord + ToString,
{
type Error = MinInfBuildResolveError;
fn try_resolve_jumps_to_multi_instr(
&self,
cur_pos: usize,
map: &[(Label, usize)],
) -> Result<Vec<usize>, Self::Error> {
Ok(vec![
self.next_fr0.resolve(cur_pos, map, self.value)?,
self.next_fr1.resolve(cur_pos, map, self.value)?,
])
}
fn try_into_instr(
self,
cur_pos: usize,
map: &[(Label, usize)],
) -> Result<MinInfInstr, MinInfBuildResolveError> {
let next0 = self
.next_fr0
.resolve(cur_pos, map, self.value)?
.checked_add(self.next_fr0.value.unwrap_or(self.value))
.ok_or(MinInfBuildResolveError::OutOfRange)?;
let next1 = self
.next_fr1
.resolve(cur_pos, map, self.value)?
.checked_add(self.next_fr1.value.unwrap_or(self.value))
.ok_or(MinInfBuildResolveError::OutOfRange)?;
Ok(MinInfInstr::new(self.func_fr0, self.func_fr1, next0, next1))
}
}
impl<Label: Clone + Debug> MinInfBuildInstrTrait<Label> for MinInfBInstrSingleSVInt<Label> {
fn get_func_fr0(&self) -> MinInfFunc {
self.func_fr0
}
fn get_func_fr1(&self) -> MinInfFunc {
self.func_fr1
}
fn get_next_fr0(&self) -> MinInfRel<Label> {
self.next_fr0.rel.clone()
}
fn get_next_fr1(&self) -> MinInfRel<Label> {
self.next_fr1.rel.clone()
}
fn set_next_fr0_label(&mut self, label: Option<Label>) {
self.next_fr0.rel.label = label;
}
fn set_next_fr1_label(&mut self, label: Option<Label>) {
self.next_fr1.rel.label = label;
}
}
#[derive(Clone, Debug, thiserror::Error)]
pub enum MinInfBInstrSingleSVIntCheckError {
#[error("Bad state value: {0} {1}")]
BadStateValue(String, String),
#[error("Next FuncRet=0 state num mismatch: {0} {1}")]
NextFr0StateNumMismatch(String, String),
#[error("Next FuncRet=1 state num mismatch {0} {1}")]
NextFr1StateNumMismatch(String, String),
}
impl<Label: Debug> CheckInstrAssertions for MinInfBInstrSingleSVInt<Label>
where
Self: Debug,
{
type Error = MinInfBInstrSingleSVIntCheckError;
fn check_assertions(&self, jump_id: usize, instr2: &Self) -> Result<(), Self::Error> {
if instr2.value != 0 {
return Err(MinInfBInstrSingleSVIntCheckError::BadStateValue(
format!("{:?}", self),
format!("{:?}", instr2),
));
}
match jump_id {
0 => {
if let Some(next0_state_num) = self.next_fr0.next_state_num {
if next0_state_num != instr2.state_num {
return Err(MinInfBInstrSingleSVIntCheckError::NextFr0StateNumMismatch(
format!("{:?}", self),
format!("{:?}", instr2),
));
}
} else {
if self.state_num != instr2.state_num {
return Err(MinInfBInstrSingleSVIntCheckError::NextFr0StateNumMismatch(
format!("{:?}", self),
format!("{:?}", instr2),
));
}
}
}
1 => {
if let Some(next1_state_num) = self.next_fr1.next_state_num {
if next1_state_num != instr2.state_num {
return Err(MinInfBInstrSingleSVIntCheckError::NextFr1StateNumMismatch(
format!("{:?}", self),
format!("{:?}", instr2),
));
}
} else {
if self.state_num != instr2.state_num {
return Err(MinInfBInstrSingleSVIntCheckError::NextFr1StateNumMismatch(
format!("{:?}", self),
format!("{:?}", instr2),
));
}
}
}
_ => {
panic!("Unexpected jump id");
}
}
Ok(())
}
}
#[derive(Clone, Default, Debug, PartialEq, Eq)]
pub struct MinInfBInstrSingleSV<Label> {
pub func_fr0: MinInfFunc,
pub func_fr1: MinInfFunc,
pub next_fr0: MinInfRelSV<Label>,
pub next_fr1: MinInfRelSV<Label>,
}
impl<Label: Clone> MinInfBInstrSingleSV<Label> {
pub fn new<IntoRel1, IntoRel2>(
func0: MinInfFunc,
func1: MinInfFunc,
next0: IntoRel1,
next1: IntoRel2,
) -> Self
where
MinInfRelSV<Label>: From<IntoRel1>,
MinInfRelSV<Label>: From<IntoRel2>,
{
Self {
func_fr0: func0,
func_fr1: func1,
next_fr0: next0.into(),
next_fr1: next1.into(),
}
}
pub fn new_01<IntoRel: Clone>(func: MinInfFunc, next: IntoRel) -> Self
where
MinInfRelSV<Label>: From<IntoRel>,
{
Self {
func_fr0: func,
func_fr1: func,
next_fr0: next.clone().into(),
next_fr1: next.into(),
}
}
pub fn new_next01<IntoRel: Clone>(func0: MinInfFunc, func1: MinInfFunc, next: IntoRel) -> Self
where
MinInfRelSV<Label>: From<IntoRel>,
{
Self {
func_fr0: func0,
func_fr1: func1,
next_fr0: next.clone().into(),
next_fr1: next.into(),
}
}
pub fn new_func01<IntoRel1, IntoRel2>(
func: MinInfFunc,
next0: IntoRel1,
next1: IntoRel2,
) -> Self
where
MinInfRelSV<Label>: From<IntoRel1>,
MinInfRelSV<Label>: From<IntoRel2>,
{
Self {
func_fr0: func,
func_fr1: func,
next_fr0: next0.into(),
next_fr1: next1.into(),
}
}
}
impl<Label> MinInfBInstrSingleSV<Label> {
pub fn newp(func0: MinInfFunc, func1: MinInfFunc) -> Self {
Self {
func_fr0: func0,
func_fr1: func1,
next_fr0: MinInfRel::<Label>::next().into(),
next_fr1: MinInfRel::<Label>::next().into(),
}
}
pub fn newp_01(func: MinInfFunc) -> Self {
Self {
func_fr0: func,
func_fr1: func,
next_fr0: MinInfRel::<Label>::next().into(),
next_fr1: MinInfRel::<Label>::next().into(),
}
}
}
#[derive(Clone, Debug, thiserror::Error)]
pub enum MinInfIntoInstrError {
#[error("Next state num out of range")]
NextStateNumOutOfRange,
#[error("Overflow while fixing relative offset")]
OverflowWhileFixing,
#[error("Next value out of range: {0} {1} {2} {3}")]
NextValueOutOfRange(usize, String, usize, isize),
#[error("InstrLen and state number mismatch: {0} {1} {2}")]
InstrLenAndStateNumMismatch(String, usize, usize),
}
impl<Label: Clone + Debug> MinInfBInstrSingleSV<Label> {
pub fn try_into_int_instr(
self,
val: usize,
state_num: usize,
) -> Result<MinInfBInstrSingleSVInt<Label>, MinInfIntoInstrError> {
let next0_state_num = isize::try_from(self.next_fr0.next_state_num.unwrap_or(state_num))
.map_err(|_| MinInfIntoInstrError::NextStateNumOutOfRange)?;
let next1_state_num = isize::try_from(self.next_fr1.next_state_num.unwrap_or(state_num))
.map_err(|_| MinInfIntoInstrError::NextStateNumOutOfRange)?;
let mut next0 = self.next_fr0.clone();
let mut next1 = self.next_fr1.clone();
if let Some(value0) = next0.value {
if value0 >= usize::try_from(next0_state_num).unwrap() {
return Err(MinInfIntoInstrError::NextValueOutOfRange(
0,
format!("{:?}", self),
value0,
next0_state_num,
));
}
} else {
if val >= usize::try_from(next0_state_num).unwrap() {
return Err(MinInfIntoInstrError::NextValueOutOfRange(
1,
format!("{:?}", self),
val,
next0_state_num,
));
}
}
if let Some(value1) = next1.value {
if value1 >= usize::try_from(next1_state_num).unwrap() {
return Err(MinInfIntoInstrError::NextValueOutOfRange(
2,
format!("{:?}", self),
value1,
next1_state_num,
));
}
} else {
if val >= usize::try_from(next1_state_num).unwrap() {
return Err(MinInfIntoInstrError::NextValueOutOfRange(
3,
format!("{:?}", self),
val,
next1_state_num,
));
}
}
next0.rel.offset = next0
.rel
.offset
.checked_mul(next0_state_num)
.ok_or(MinInfIntoInstrError::OverflowWhileFixing)?;
next1.rel.offset = next1
.rel
.offset
.checked_mul(next1_state_num)
.ok_or(MinInfIntoInstrError::OverflowWhileFixing)?;
Ok(MinInfBInstrSingleSVInt::new(
self.func_fr0,
self.func_fr1,
next0,
next1,
val,
state_num,
))
}
}
impl<Label> From<MinInfBuildInstr<Label>> for MinInfBInstrSingleSV<Label> {
fn from(s: MinInfBuildInstr<Label>) -> Self {
Self {
func_fr0: s.func_fr0,
func_fr1: s.func_fr1,
next_fr0: s.next_fr0.into(),
next_fr1: s.next_fr1.into(),
}
}
}
impl<Label> From<MinInfFunc> for MinInfBInstrSingleSV<Label> {
fn from(f: MinInfFunc) -> Self {
Self::newp_01(f)
}
}
impl<Label> From<(MinInfFunc, MinInfFunc)> for MinInfBInstrSingleSV<Label> {
fn from(f: (MinInfFunc, MinInfFunc)) -> Self {
Self::newp(f.0, f.1)
}
}
impl<Label, IntoRel> From<(MinInfFunc, IntoRel)> for MinInfBInstrSingleSV<Label>
where
Label: Clone,
IntoRel: Clone,
MinInfRelSV<Label>: From<IntoRel>,
{
fn from(f: (MinInfFunc, IntoRel)) -> Self {
Self::new_01(f.0, f.1)
}
}
impl<Label, IntoRel> From<(MinInfFunc, MinInfFunc, IntoRel)> for MinInfBInstrSingleSV<Label>
where
Label: Clone,
IntoRel: Clone,
MinInfRelSV<Label>: From<IntoRel>,
{
fn from(f: (MinInfFunc, MinInfFunc, IntoRel)) -> Self {
Self::new_next01(f.0, f.1, f.2)
}
}
impl<Label, IntoRel, IntoRel2> From<(MinInfFunc, IntoRel, IntoRel2)> for MinInfBInstrSingleSV<Label>
where
Label: Clone,
MinInfRelSV<Label>: From<IntoRel>,
MinInfRelSV<Label>: From<IntoRel2>,
{
fn from(f: (MinInfFunc, IntoRel, IntoRel2)) -> Self {
Self::new_func01(f.0, f.1, f.2)
}
}
impl<Label, IntoRel, IntoRel2> From<(MinInfFunc, MinInfFunc, IntoRel, IntoRel2)>
for MinInfBInstrSingleSV<Label>
where
Label: Clone,
MinInfRelSV<Label>: From<IntoRel>,
MinInfRelSV<Label>: From<IntoRel2>,
{
fn from(f: (MinInfFunc, MinInfFunc, IntoRel, IntoRel2)) -> Self {
Self::new(f.0, f.1, f.2, f.3)
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct MinInfBInstrSV<Label> {
pub instrs: Vec<MinInfBInstrSingleSV<Label>>,
}
impl<Label: Clone> MinInfBInstrSV<Label> {
pub fn new_many<IntoRel1, IntoRel2>(
func0: MinInfFunc,
func1: MinInfFunc,
next0: IntoRel1,
next1: IntoRel2,
) -> Self
where
MinInfRel<Label>: From<IntoRel1>,
MinInfRel<Label>: From<IntoRel2>,
{
Self {
instrs: vec![MinInfBInstrSingleSV::new(
func0,
func1,
MinInfRelSV::new_default2(next0.into()),
MinInfRelSV::new_default2(next1.into()),
)],
}
}
pub fn new_many_nc<IntoRel1: Clone, IntoRel2: Clone>(
func0: MinInfFunc,
func1: MinInfFunc,
next0: IntoRel1,
next1: IntoRel2,
next_count: usize,
) -> Self
where
MinInfRel<Label>: From<IntoRel1>,
MinInfRel<Label>: From<IntoRel2>,
{
Self {
instrs: (0..next_count)
.map(|x| {
MinInfBInstrSingleSV::new(
func0,
func1,
MinInfRelSV::new(next0.clone().into(), x % next_count, next_count),
MinInfRelSV::new(next1.clone().into(), x % next_count, next_count),
)
})
.collect::<Vec<_>>(),
}
}
pub fn new_many_nc2<IntoRel1: Clone, IntoRel2: Clone>(
func0: MinInfFunc,
func1: MinInfFunc,
next0: IntoRel1,
next1: IntoRel2,
next_count0: usize,
next_count1: usize,
) -> Self
where
MinInfRel<Label>: From<IntoRel1>,
MinInfRel<Label>: From<IntoRel2>,
{
Self {
instrs: (0..std::cmp::max(next_count0, next_count1))
.map(|x| {
MinInfBInstrSingleSV::new(
func0,
func1,
MinInfRelSV::new(next0.clone().into(), x % next_count0, next_count0),
MinInfRelSV::new(next1.clone().into(), x % next_count1, next_count1),
)
})
.collect::<Vec<_>>(),
}
}
pub fn new_01_many<IntoRel: Clone>(func: MinInfFunc, next: IntoRel) -> Self
where
MinInfRel<Label>: From<IntoRel>,
{
Self {
instrs: vec![MinInfBInstrSingleSV::new(
func,
func,
MinInfRelSV::new_default2(next.clone().into()),
MinInfRelSV::new_default2(next.into()),
)],
}
}
pub fn new_01_many_nc<IntoRel: Clone>(
func: MinInfFunc,
next: IntoRel,
next_count: usize,
) -> Self
where
MinInfRel<Label>: From<IntoRel>,
{
Self {
instrs: (0..next_count)
.map(|x| {
MinInfBInstrSingleSV::new(
func,
func,
MinInfRelSV::new(next.clone().into(), x % next_count, next_count),
MinInfRelSV::new(next.clone().into(), x % next_count, next_count),
)
})
.collect::<Vec<_>>(),
}
}
pub fn new_01_many_nc2<IntoRel: Clone>(
func: MinInfFunc,
next: IntoRel,
next_count0: usize,
next_count1: usize,
) -> Self
where
MinInfRel<Label>: From<IntoRel>,
{
Self {
instrs: (0..std::cmp::max(next_count0, next_count1))
.map(|x| {
MinInfBInstrSingleSV::new(
func,
func,
MinInfRelSV::new(next.clone().into(), x % next_count0, next_count0),
MinInfRelSV::new(next.clone().into(), x % next_count1, next_count1),
)
})
.collect::<Vec<_>>(),
}
}
pub fn new_next01_many<IntoRel: Clone>(
func0: MinInfFunc,
func1: MinInfFunc,
next: IntoRel,
) -> Self
where
MinInfRel<Label>: From<IntoRel>,
{
Self {
instrs: vec![MinInfBInstrSingleSV::new(
func0,
func1,
MinInfRelSV::new_default2(next.clone().into()),
MinInfRelSV::new_default2(next.into()),
)],
}
}
pub fn new_next01_many_nc<IntoRel: Clone>(
func0: MinInfFunc,
func1: MinInfFunc,
next: IntoRel,
next_count: usize,
) -> Self
where
MinInfRel<Label>: From<IntoRel>,
{
Self {
instrs: (0..next_count)
.map(|x| {
MinInfBInstrSingleSV::new(
func0,
func1,
MinInfRelSV::new(next.clone().into(), x % next_count, next_count),
MinInfRelSV::new(next.clone().into(), x % next_count, next_count),
)
})
.collect::<Vec<_>>(),
}
}
pub fn new_next01_many_nc2<IntoRel: Clone>(
func0: MinInfFunc,
func1: MinInfFunc,
next: IntoRel,
next_count0: usize,
next_count1: usize,
) -> Self
where
MinInfRel<Label>: From<IntoRel>,
{
Self {
instrs: (0..std::cmp::max(next_count0, next_count1))
.map(|x| {
MinInfBInstrSingleSV::new(
func0,
func1,
MinInfRelSV::new(next.clone().into(), x % next_count0, next_count0),
MinInfRelSV::new(next.clone().into(), x % next_count1, next_count1),
)
})
.collect::<Vec<_>>(),
}
}
pub fn new_func01_many<IntoRel1, IntoRel2>(
func: MinInfFunc,
next0: IntoRel1,
next1: IntoRel2,
) -> Self
where
MinInfRel<Label>: From<IntoRel1>,
MinInfRel<Label>: From<IntoRel2>,
{
Self {
instrs: vec![MinInfBInstrSingleSV::new(
func,
func,
MinInfRelSV::new_default2(next0.into()),
MinInfRelSV::new_default2(next1.into()),
)],
}
}
pub fn new_func01_many_nc<IntoRel1: Clone, IntoRel2: Clone>(
func: MinInfFunc,
next0: IntoRel1,
next1: IntoRel2,
next_count: usize,
) -> Self
where
MinInfRel<Label>: From<IntoRel1>,
MinInfRel<Label>: From<IntoRel2>,
{
Self {
instrs: (0..next_count)
.map(|x| {
MinInfBInstrSingleSV::new(
func,
func,
MinInfRelSV::new(next0.clone().into(), x % next_count, next_count),
MinInfRelSV::new(next1.clone().into(), x % next_count, next_count),
)
})
.collect::<Vec<_>>(),
}
}
pub fn new_func01_many_nc2<IntoRel1: Clone, IntoRel2: Clone>(
func: MinInfFunc,
next0: IntoRel1,
next1: IntoRel2,
next_count0: usize,
next_count1: usize,
) -> Self
where
MinInfRel<Label>: From<IntoRel1>,
MinInfRel<Label>: From<IntoRel2>,
{
Self {
instrs: (0..std::cmp::max(next_count0, next_count1))
.map(|x| {
MinInfBInstrSingleSV::new(
func,
func,
MinInfRelSV::new(next0.clone().into(), x % next_count0, next_count0),
MinInfRelSV::new(next1.clone().into(), x % next_count1, next_count1),
)
})
.collect::<Vec<_>>(),
}
}
pub fn new_rsv<IntoRel1: Clone, IntoRel2: Clone>(
func0: MinInfFunc,
func1: MinInfFunc,
next0: IntoRel1,
next1: IntoRel2,
) -> Self
where
MinInfRelSV<Label>: From<IntoRel1>,
MinInfRelSV<Label>: From<IntoRel2>,
{
Self {
instrs: vec![MinInfBInstrSingleSV::new(func0, func1, next0, next1)],
}
}
pub fn new_func01_rsv<IntoRel1: Clone, IntoRel2: Clone>(
func: MinInfFunc,
next0: IntoRel1,
next1: IntoRel2,
) -> Self
where
MinInfRelSV<Label>: From<IntoRel1>,
MinInfRelSV<Label>: From<IntoRel2>,
{
Self {
instrs: vec![MinInfBInstrSingleSV::new(func, func, next0, next1)],
}
}
pub fn new_next01_rsv<IntoRel1: Clone>(
func0: MinInfFunc,
func1: MinInfFunc,
next: IntoRel1,
) -> Self
where
MinInfRelSV<Label>: From<IntoRel1>,
{
Self {
instrs: vec![MinInfBInstrSingleSV::new(func0, func1, next.clone(), next)],
}
}
pub fn new_01_rsv<IntoRel1: Clone>(func: MinInfFunc, next: IntoRel1) -> Self
where
MinInfRelSV<Label>: From<IntoRel1>,
{
Self {
instrs: vec![MinInfBInstrSingleSV::new(func, func, next.clone(), next)],
}
}
pub fn new_binstrs<I, It>(instrs: I) -> Self
where
MinInfBuildInstr<Label>: From<It>,
I: IntoIterator<Item = It>,
{
Self {
instrs: instrs
.into_iter()
.map(|instr| {
let instr: MinInfBuildInstr<Label> = instr.into();
MinInfBInstrSingleSV::new(
instr.func_fr0,
instr.func_fr1,
MinInfRelSV::new_default2(instr.next_fr0.clone()),
MinInfRelSV::new_default2(instr.next_fr1.clone()),
)
})
.collect::<Vec<_>>(),
}
}
pub fn new_binstrs_nextstate<I, It>(instrs: I, val: usize, next_state_num: usize) -> Self
where
MinInfBuildInstr<Label>: From<It>,
I: IntoIterator<Item = It>,
{
Self {
instrs: instrs
.into_iter()
.map(|instr| {
let instr: MinInfBuildInstr<Label> = instr.into();
MinInfBInstrSingleSV::new(
instr.func_fr0,
instr.func_fr1,
MinInfRelSV::new(instr.next_fr0.clone(), val, next_state_num),
MinInfRelSV::new(instr.next_fr1.clone(), val, next_state_num),
)
})
.collect::<Vec<_>>(),
}
}
pub fn new_binstr_nextvals<It, Iv>(instr: It, vals: Iv, next_state_num: usize) -> Self
where
Iv: IntoIterator<Item = usize>,
MinInfBuildInstr<Label>: From<It>,
{
let instr: MinInfBuildInstr<Label> = instr.into();
Self {
instrs: vals
.into_iter()
.map(|val| {
MinInfBInstrSingleSV::new(
instr.func_fr0,
instr.func_fr1,
MinInfRelSV::new(instr.next_fr0.clone(), val, next_state_num),
MinInfRelSV::new(instr.next_fr1.clone(), val, next_state_num),
)
})
.collect::<Vec<_>>(),
}
}
pub fn new_binstr_nextstates<It, Iv>(instr: It, nextstates: Iv) -> Self
where
Iv: IntoIterator<Item = (usize, usize)>,
MinInfBuildInstr<Label>: From<It>,
{
let instr: MinInfBuildInstr<Label> = instr.into();
Self {
instrs: nextstates
.into_iter()
.map(|(val, next_state_num)| {
MinInfBInstrSingleSV::new(
instr.func_fr0,
instr.func_fr1,
MinInfRelSV::new(instr.next_fr0.clone(), val, next_state_num),
MinInfRelSV::new(instr.next_fr1.clone(), val, next_state_num),
)
})
.collect::<Vec<_>>(),
}
}
pub fn new<I, It>(instrs: I) -> Self
where
MinInfBInstrSingleSV<Label>: From<It>,
I: IntoIterator<Item = It>,
{
Self {
instrs: instrs.into_iter().map(|x| x.into()).collect::<Vec<_>>(),
}
}
}
impl<Label: Clone + Debug> MinInfBInstrSV<Label> {
pub fn try_to_instrs(
self,
state_num: usize,
) -> Result<Vec<MinInfBInstrSingleSVInt<Label>>, MinInfIntoInstrError> {
let instr_len = self.instrs.len();
if instr_len > state_num {
return Err(MinInfIntoInstrError::InstrLenAndStateNumMismatch(
format!("{:?}", self),
instr_len,
state_num,
));
}
(0..state_num)
.map(|i| {
self.instrs[i % instr_len]
.clone()
.try_into_int_instr(i, state_num)
})
.collect::<Result<Vec<_>, _>>()
}
}
impl<Label: Clone> MinInfBInstrSV<Label> {
pub fn newp_many(func0: MinInfFunc, func1: MinInfFunc) -> Self {
Self {
instrs: vec![MinInfBInstrSingleSV::new(
func0,
func1,
MinInfRelSV::new_default2(MinInfRel::next()),
MinInfRelSV::new_default2(MinInfRel::next()),
)],
}
}
pub fn newp_many_nc(func0: MinInfFunc, func1: MinInfFunc, next_count: usize) -> Self {
Self {
instrs: (0..next_count)
.map(|x| {
MinInfBInstrSingleSV::new(
func0,
func1,
MinInfRelSV::new(MinInfRel::next(), x % next_count, next_count),
MinInfRelSV::new(MinInfRel::next(), x % next_count, next_count),
)
})
.collect::<Vec<_>>(),
}
}
pub fn newp_many_nc2(
func0: MinInfFunc,
func1: MinInfFunc,
next_count0: usize,
next_count1: usize,
) -> Self {
Self {
instrs: (0..std::cmp::max(next_count0, next_count1))
.map(|x| {
MinInfBInstrSingleSV::new(
func0,
func1,
MinInfRelSV::new(MinInfRel::next(), x % next_count0, next_count0),
MinInfRelSV::new(MinInfRel::next(), x % next_count1, next_count1),
)
})
.collect::<Vec<_>>(),
}
}
pub fn newp_01_many(func: MinInfFunc) -> Self {
Self {
instrs: vec![MinInfBInstrSingleSV::new(
func,
func,
MinInfRelSV::new_default2(MinInfRel::next()),
MinInfRelSV::new_default2(MinInfRel::next()),
)],
}
}
pub fn newp_01_many_nc(func: MinInfFunc, next_count: usize) -> Self {
Self {
instrs: (0..next_count)
.map(|x| {
MinInfBInstrSingleSV::new(
func,
func,
MinInfRelSV::new(MinInfRel::next(), x % next_count, next_count),
MinInfRelSV::new(MinInfRel::next(), x % next_count, next_count),
)
})
.collect::<Vec<_>>(),
}
}
pub fn newp_01_many_nc2(func: MinInfFunc, next_count0: usize, next_count1: usize) -> Self {
Self {
instrs: (0..std::cmp::max(next_count0, next_count1))
.map(|x| {
MinInfBInstrSingleSV::new(
func,
func,
MinInfRelSV::new(MinInfRel::next(), x % next_count0, next_count0),
MinInfRelSV::new(MinInfRel::next(), x % next_count1, next_count1),
)
})
.collect::<Vec<_>>(),
}
}
}
impl<Label: Clone> From<MinInfBuildInstr<Label>> for MinInfBInstrSV<Label> {
fn from(s: MinInfBuildInstr<Label>) -> Self {
Self::new_many(s.func_fr0, s.func_fr1, s.next_fr0, s.next_fr1)
}
}
impl<Label: Clone> From<(MinInfBuildInstr<Label>, usize)> for MinInfBInstrSV<Label> {
fn from(s: (MinInfBuildInstr<Label>, usize)) -> Self {
Self::new_many_nc(s.0.func_fr0, s.0.func_fr1, s.0.next_fr0, s.0.next_fr1, s.1)
}
}
impl<Label: Clone> From<MinInfFunc> for MinInfBInstrSV<Label> {
fn from(s: MinInfFunc) -> Self {
Self::newp_01_many(s)
}
}
impl<Label: Clone> From<(MinInfFunc, usize)> for MinInfBInstrSV<Label> {
fn from(s: (MinInfFunc, usize)) -> Self {
Self::newp_01_many_nc(s.0, s.1)
}
}
impl<Label: Clone> From<(MinInfFunc, MinInfFunc)> for MinInfBInstrSV<Label> {
fn from(s: (MinInfFunc, MinInfFunc)) -> Self {
Self::newp_many(s.0, s.1)
}
}
impl<Label: Clone> From<(MinInfFunc, MinInfFunc, usize)> for MinInfBInstrSV<Label> {
fn from(s: (MinInfFunc, MinInfFunc, usize)) -> Self {
Self::newp_many_nc(s.0, s.1, s.2)
}
}
impl<Label: Clone, IntoRel: Clone> From<(MinInfFunc, IntoRel)> for MinInfBInstrSV<Label>
where
MinInfRel<Label>: From<IntoRel>,
{
fn from(s: (MinInfFunc, IntoRel)) -> Self {
Self::new_01_many(s.0, s.1)
}
}
impl<Label: Clone, IntoRel: Clone> From<(MinInfFunc, IntoRel, usize)> for MinInfBInstrSV<Label>
where
MinInfRel<Label>: From<IntoRel>,
{
fn from(s: (MinInfFunc, IntoRel, usize)) -> Self {
Self::new_01_many_nc(s.0, s.1, s.2)
}
}
impl<Label, IntoRel> From<(MinInfFunc, MinInfFunc, IntoRel)> for MinInfBInstrSV<Label>
where
Label: Clone,
IntoRel: Clone,
MinInfRel<Label>: From<IntoRel>,
{
fn from(s: (MinInfFunc, MinInfFunc, IntoRel)) -> Self {
Self::new_next01_many(s.0, s.1, s.2)
}
}
impl<Label, IntoRel> From<(MinInfFunc, MinInfFunc, IntoRel, usize)> for MinInfBInstrSV<Label>
where
Label: Clone,
IntoRel: Clone,
MinInfRel<Label>: From<IntoRel>,
{
fn from(s: (MinInfFunc, MinInfFunc, IntoRel, usize)) -> Self {
Self::new_next01_many_nc(s.0, s.1, s.2, s.3)
}
}
impl<Label, IntoRel1, IntoRel2> From<(MinInfFunc, IntoRel1, IntoRel2)> for MinInfBInstrSV<Label>
where
Label: Clone,
IntoRel1: Clone,
IntoRel2: Clone,
MinInfRel<Label>: From<IntoRel1>,
MinInfRel<Label>: From<IntoRel2>,
{
fn from(s: (MinInfFunc, IntoRel1, IntoRel2)) -> Self {
Self::new_func01_many(s.0, s.1, s.2)
}
}
impl<Label, IntoRel1, IntoRel2> From<(MinInfFunc, IntoRel1, IntoRel2, usize)>
for MinInfBInstrSV<Label>
where
Label: Clone,
IntoRel1: Clone,
IntoRel2: Clone,
MinInfRel<Label>: From<IntoRel1>,
MinInfRel<Label>: From<IntoRel2>,
{
fn from(s: (MinInfFunc, IntoRel1, IntoRel2, usize)) -> Self {
Self::new_func01_many_nc(s.0, s.1, s.2, s.3)
}
}
impl<Label, IntoRel1, IntoRel2> From<(MinInfFunc, MinInfFunc, IntoRel1, IntoRel2)>
for MinInfBInstrSV<Label>
where
Label: Clone,
IntoRel1: Clone,
IntoRel2: Clone,
MinInfRel<Label>: From<IntoRel1>,
MinInfRel<Label>: From<IntoRel2>,
{
fn from(s: (MinInfFunc, MinInfFunc, IntoRel1, IntoRel2)) -> Self {
Self::new_many(s.0, s.1, s.2, s.3)
}
}
impl<Label, IntoRel1, IntoRel2> From<(MinInfFunc, MinInfFunc, IntoRel1, IntoRel2, usize)>
for MinInfBInstrSV<Label>
where
Label: Clone,
IntoRel1: Clone,
IntoRel2: Clone,
MinInfRel<Label>: From<IntoRel1>,
MinInfRel<Label>: From<IntoRel2>,
{
fn from(s: (MinInfFunc, MinInfFunc, IntoRel1, IntoRel2, usize)) -> Self {
Self::new_many_nc(s.0, s.1, s.2, s.3, s.4)
}
}
impl<Label: Clone, I, It> From<(I,)> for MinInfBInstrSV<Label>
where
MinInfBInstrSingleSV<Label>: From<It>,
I: IntoIterator<Item = It>,
{
fn from(s: (I,)) -> Self {
Self::new(s.0)
}
}
#[derive(Clone, Debug)]
pub struct MinInfWithStateVar<Builder> {
builder: Builder,
state_num: usize,
}
impl<Builder: Default> Default for MinInfWithStateVar<Builder> {
fn default() -> Self {
Self::new(Builder::default(), 1)
}
}
impl<Builder> MinInfWithStateVar<Builder> {
pub fn new(builder: Builder, state_num: usize) -> Self {
assert_ne!(state_num, 0);
Self { builder, state_num }
}
pub fn free(self) -> Builder {
self.builder
}
}
impl<Builder> MinInfStateNumTrait for MinInfWithStateVar<Builder> {
fn state_num(&self) -> usize {
self.state_num
}
fn switch(&mut self, state_num: usize) -> usize {
let old_state_num = self.state_num;
if self.state_num != state_num {
self.state_num = state_num;
}
old_state_num
}
}
#[derive(Debug, thiserror::Error)]
pub enum MinInfWithStateVarError<IError> {
#[error("IntoInstr: {0}")]
IntoInstr(#[from] MinInfIntoInstrError),
#[error("Internal builder: {0}")]
InternalBuilder(IError),
}
impl<Builder, Label> MinInfBuilderTrait<Label, MinInfBInstrSV<Label>>
for MinInfWithStateVar<Builder>
where
Label: Clone + Debug,
Builder: MinInfBuilderTrait<Label, MinInfBInstrSingleSVInt<Label>>,
Builder::Error: Debug,
{
type Error = MinInfWithStateVarError<Builder::Error>;
fn try_add_instr<I>(&mut self, instr: I) -> Result<(), Self::Error>
where
MinInfBInstrSV<Label>: From<I>,
{
for instr in MinInfBInstrSV::<Label>::from(instr).try_to_instrs(self.state_num)? {
self.builder
.try_add_instr(instr)
.map_err(|e| MinInfWithStateVarError::InternalBuilder(e))?;
}
Ok(())
}
}
impl<Builder, Label> MinInfLabelTrait<Label> for MinInfWithStateVar<Builder>
where
Label: Clone + Debug,
Builder: MinInfLabelTrait<Label>,
<Builder as MinInfLabelTrait<Label>>::Error: Debug,
{
type Error = <Builder as MinInfLabelTrait<Label>>::Error;
fn try_add_label<L: Clone + Debug>(&mut self, label: L) -> Result<(), Self::Error>
where
Label: From<L>,
{
self.builder.try_add_label(label)
}
fn get_label_map(&self) -> &BTreeMap<Label, usize> {
self.builder.get_label_map()
}
}
impl<Builder, Label, Instr> MinInfCodeTrait<Label, Instr> for MinInfWithStateVar<Builder>
where
Label: Clone + Debug,
Builder: MinInfCodeTrait<Label, Instr>,
{
fn get_code(&self) -> &Vec<Instr> {
&self.builder.get_code()
}
}
impl<Builder, Label> MinInfToCodeTrait<Label, MinInfInstr> for MinInfWithStateVar<Builder>
where
Builder: MinInfToCodeTrait<Label, MinInfInstr>,
{
type Error = <Builder as MinInfToCodeTrait<Label, MinInfInstr>>::Error;
fn try_to_code(self) -> Result<(Vec<MinInfInstr>, Vec<(Label, usize)>), Self::Error> {
self.builder.try_to_code()
}
}
impl<Builder> MinInfMultiAppendTrait for MinInfWithStateVar<Builder>
where
Builder: MinInfMultiAppendTrait,
{
type Error = <Builder as MinInfMultiAppendTrait>::Error;
fn try_multi_append<'a, I>(&mut self, appends: I) -> Result<(), Self::Error>
where
I: IntoIterator<Item = (usize, &'a Self)>,
Self: 'a,
{
self.builder
.try_multi_append(appends.into_iter().map(|(pos, b)| (pos, &b.builder)))
}
}
impl<Builder> MinInfJoinTrait for MinInfWithStateVar<Builder>
where
Builder: MinInfJoinTrait,
{
type Error = <Builder as MinInfJoinTrait>::Error;
fn join(&mut self, second: Self) -> Result<(), Self::Error> {
self.builder.join(second.builder)
}
}
pub struct LocalLabels<'a, Builder, Label> {
name: Label,
sep: Label,
pub b: &'a mut Builder,
}
impl<'a, Builder, Label> LocalLabels<'a, Builder, Label> {
pub fn new<L>(b: &'a mut Builder, name: L) -> Self
where
Label: From<L> + DefaultSep,
{
Self {
name: name.into(),
sep: Label::default_sep(),
b,
}
}
pub fn new_with_sep<L, L2>(b: &'a mut Builder, name: L, sep: L2) -> Self
where
Label: From<L> + From<L2>,
{
Self {
name: name.into(),
sep: sep.into(),
b,
}
}
}
impl<'a, Builder, Label> LocalLabels<'a, Builder, Label>
where
Label: Clone + LabelJoin<Label>,
Label: From<Label>,
{
pub fn t<L>(&self, label: L) -> Label
where
Label: From<L>,
{
let mut l = self.name.clone();
l.label_join(&self.sep);
l.label_join(&label.into());
l
}
}
impl<'a, Builder, Label> MinInfLabelTrait<Label> for LocalLabels<'a, Builder, Label>
where
Builder: MinInfLabelTrait<Label>,
Label: Clone + Debug + PartialEq + Eq + Ord + LabelJoin<Label>,
Label: From<Label>,
{
type Error = <Builder as MinInfLabelTrait<Label>>::Error;
fn try_add_label<L: Clone + Debug>(&mut self, label: L) -> Result<(), Self::Error>
where
Label: From<L>,
{
self.b.try_add_label(self.t(label))
}
fn get_label_map(&self) -> &BTreeMap<Label, usize> {
self.b.get_label_map()
}
}
impl<'a, Builder, Label, Instr> MinInfBuilderTrait<Label, Instr> for LocalLabels<'a, Builder, Label>
where
Builder: MinInfBuilderTrait<Label, Instr>,
{
type Error = <Builder as MinInfBuilderTrait<Label, Instr>>::Error;
fn try_add_instr<I>(&mut self, instr: I) -> Result<(), Self::Error>
where
Instr: From<I>,
{
self.b.try_add_instr(instr)
}
}
impl<'a, Builder, Label, Instr> MinInfCodeTrait<Label, Instr> for LocalLabels<'a, Builder, Label>
where
Builder: MinInfCodeTrait<Label, Instr>,
{
fn get_code(&self) -> &Vec<Instr> {
self.b.get_code()
}
}
impl<'a, Builder, Label> MinInfStateNumTrait for LocalLabels<'a, Builder, Label>
where
Builder: MinInfStateNumTrait,
{
fn state_num(&self) -> usize {
self.b.state_num()
}
fn switch(&mut self, state_num: usize) -> usize {
self.b.switch(state_num)
}
}
pub type MISimpleBuilder = MinInfBuilder<String, MinInfBuildInstr<String>>;
pub type MIStdSVRootBuilder = MinInfBuilder<String, MinInfBInstrSingleSVInt<String>>;
pub type MIStdSVBuilder = MinInfWithStateVar<MIStdSVRootBuilder>;
pub fn mi_std_sv_builder_new(state_num: usize) -> MIStdSVBuilder {
MIStdSVBuilder::new(MIStdSVRootBuilder::new(), state_num)
}