Something not working
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -1,6 +1,6 @@
|
|||||||
use std::{rc::Rc};
|
use std::{rc::Rc};
|
||||||
|
|
||||||
use crate::configotron::fsm::{builder::elimate_unused_states, masking::{MaskPresets, TransitionMask}, new_state_ref, transition::FSMTranistion, FSMState, FSMStateAction, FSMStateRef};
|
use crate::{configotron::fsm::{builder::elimate_unused_states, masking::{MaskPresets, TransitionMask}, new_state_ref, transition::FSMTranistion, FSMState, FSMStateAction, FSMStateRef}, main};
|
||||||
|
|
||||||
use super::super::FSM;
|
use super::super::FSM;
|
||||||
|
|
||||||
@@ -27,8 +27,8 @@ fn nth_decimal_digit(num: u32, n: u32) -> u32 {
|
|||||||
(num / divisor) % 10
|
(num / divisor) % 10
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_fsm_number_upperbound(max: u32) -> FSM {
|
fn create_fsm_number_scafold(n: u32) -> (Vec<FSMStateRef>, Vec<FSMStateRef>, FSMStateRef, FSMStateRef) {
|
||||||
let length_of_number = number_of_digits(max as i32);
|
let length_of_number = number_of_digits(n as i32);
|
||||||
|
|
||||||
// Creating All states
|
// Creating All states
|
||||||
let error_state = new_state_ref(FSMState::new("e".to_string(), FSMStateAction::Error));
|
let error_state = new_state_ref(FSMState::new("e".to_string(), FSMStateAction::Error));
|
||||||
@@ -39,15 +39,22 @@ fn create_fsm_number_upperbound(max: u32) -> FSM {
|
|||||||
|
|
||||||
// Create and Link Main to side
|
// Create and Link Main to side
|
||||||
for i in 0..length_of_number {
|
for i in 0..length_of_number {
|
||||||
let digit = nth_decimal_digit(max, i);
|
let digit = nth_decimal_digit(n, i);
|
||||||
|
|
||||||
let new_main_state = new_state_ref(FSMState::new(
|
let new_main_state = new_state_ref(FSMState::new(
|
||||||
format!("m{}", i), FSMStateAction::Terminal));
|
format!("m{}", i), FSMStateAction::None));
|
||||||
let new_side_state = new_state_ref(FSMState::new(
|
let new_side_state = new_state_ref(FSMState::new(
|
||||||
format!("s{}", i), FSMStateAction::Terminal));
|
format!("s{}", i), FSMStateAction::None));
|
||||||
|
|
||||||
|
// Main -> Error
|
||||||
let mut main_state_transition = FSMTranistion::new(Rc::downgrade(&error_state));
|
let mut main_state_transition = FSMTranistion::new(Rc::downgrade(&error_state));
|
||||||
|
|
||||||
|
// Side -> Error
|
||||||
|
new_side_state.borrow_mut().set_transitions(
|
||||||
|
FSMTranistion::new(Rc::downgrade(&error_state))
|
||||||
|
);
|
||||||
|
|
||||||
|
// Main -> Side (-) Transition [0..n-1]
|
||||||
if digit > 0 {
|
if digit > 0 {
|
||||||
main_state_transition.apply(TransitionMask::from(MaskPresets::NumberRange(0..=(digit as u8 - 1))), Rc::downgrade(&new_side_state));
|
main_state_transition.apply(TransitionMask::from(MaskPresets::NumberRange(0..=(digit as u8 - 1))), Rc::downgrade(&new_side_state));
|
||||||
}
|
}
|
||||||
@@ -56,14 +63,11 @@ fn create_fsm_number_upperbound(max: u32) -> FSM {
|
|||||||
main_state_transition
|
main_state_transition
|
||||||
);
|
);
|
||||||
|
|
||||||
new_side_state.borrow_mut().set_transitions(
|
|
||||||
FSMTranistion::new(Rc::downgrade(&error_state))
|
|
||||||
);
|
|
||||||
|
|
||||||
main_line.push(new_main_state.clone());
|
main_line.push(new_main_state.clone());
|
||||||
side_line.push(new_side_state.clone());
|
side_line.push(new_side_state.clone());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Link Main to main, side to side
|
// Link Main to main, side to side
|
||||||
for (i,
|
for (i,
|
||||||
(
|
(
|
||||||
@@ -74,19 +78,20 @@ fn create_fsm_number_upperbound(max: u32) -> FSM {
|
|||||||
main_line.iter().zip(main_line.iter().skip(1))
|
main_line.iter().zip(main_line.iter().skip(1))
|
||||||
.zip(side_line.iter().zip(side_line.iter().skip(1)))
|
.zip(side_line.iter().zip(side_line.iter().skip(1)))
|
||||||
.enumerate() {
|
.enumerate() {
|
||||||
let digit = nth_decimal_digit(max, i as u32);
|
let digit = nth_decimal_digit(n, i as u32);
|
||||||
|
|
||||||
match &mut prev_main.borrow_mut().transition {
|
match &mut prev_main.borrow_mut().transition {
|
||||||
None => {},
|
None => {},
|
||||||
Some(t) => {
|
Some(t) => {
|
||||||
|
|
||||||
|
// prev_main -> next_side (+) Transition
|
||||||
if digit < 9 {
|
if digit < 9 {
|
||||||
t.apply(
|
t.apply(
|
||||||
TransitionMask::from(MaskPresets::NumberRange((digit as u8 + 1)..=9)),
|
TransitionMask::from(MaskPresets::NumberRange((digit as u8 + 1)..=9)),
|
||||||
Rc::downgrade(next_side)
|
Rc::downgrade(next_side)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
// prev_main -> next_main (=) Transition
|
||||||
t.apply(
|
t.apply(
|
||||||
TransitionMask::from(MaskPresets::Char(std::char::from_digit(digit, 10).unwrap())),
|
TransitionMask::from(MaskPresets::Char(std::char::from_digit(digit, 10).unwrap())),
|
||||||
Rc::downgrade(next_main)
|
Rc::downgrade(next_main)
|
||||||
@@ -94,6 +99,7 @@ fn create_fsm_number_upperbound(max: u32) -> FSM {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// prev_side -> next_side
|
||||||
match &mut prev_side.borrow_mut().transition {
|
match &mut prev_side.borrow_mut().transition {
|
||||||
None => {},
|
None => {},
|
||||||
Some(t) => {
|
Some(t) => {
|
||||||
@@ -105,16 +111,30 @@ fn create_fsm_number_upperbound(max: u32) -> FSM {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Link last main to side, goal
|
(main_line, side_line, goal_state, error_state)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_fsm_number_upper_bound(max: u32) -> FSM {
|
||||||
|
let (
|
||||||
|
mut main_line,
|
||||||
|
mut side_line,
|
||||||
|
goal_state,
|
||||||
|
error_state
|
||||||
|
) = create_fsm_number_scafold(max);
|
||||||
|
|
||||||
|
// Setting main/side line as Terminal states
|
||||||
|
for (side, main) in side_line.iter_mut().zip(&mut main_line) {
|
||||||
|
side.borrow_mut().action = FSMStateAction::Terminal;
|
||||||
|
main.borrow_mut().action = FSMStateAction::Terminal;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Link last main to goal
|
||||||
match &mut main_line.last() {
|
match &mut main_line.last() {
|
||||||
Some(main_last) => {
|
Some(main_last) => {
|
||||||
let last_digit = max % 10;
|
let last_digit = max % 10;
|
||||||
match &mut main_last.borrow_mut().transition {
|
match &mut main_last.borrow_mut().transition {
|
||||||
Some(t) => {
|
Some(t) => {
|
||||||
t.apply(TransitionMask::from(MaskPresets::Char(
|
// Main -> Goal (=) or (+)
|
||||||
std::char::from_digit(last_digit, 10).unwrap()
|
|
||||||
)), Rc::downgrade(&goal_state));
|
|
||||||
|
|
||||||
t.apply(TransitionMask::from(MaskPresets::NumberRange(0..=(last_digit as u8))),
|
t.apply(TransitionMask::from(MaskPresets::NumberRange(0..=(last_digit as u8))),
|
||||||
Rc::downgrade(&goal_state)
|
Rc::downgrade(&goal_state)
|
||||||
);
|
);
|
||||||
@@ -153,21 +173,84 @@ fn create_fsm_number_upperbound(max: u32) -> FSM {
|
|||||||
fsm
|
fsm
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn create_fsm_number_lower_bound(min: u32) -> FSM {
|
||||||
|
let (
|
||||||
|
mut main_line,
|
||||||
|
mut side_line,
|
||||||
|
goal_state,
|
||||||
|
error_state
|
||||||
|
) = create_fsm_number_scafold(min);
|
||||||
|
|
||||||
|
// Setting main/side line as Error states
|
||||||
|
for (side, main) in side_line.iter_mut().zip(&mut main_line) {
|
||||||
|
side.borrow_mut().action = FSMStateAction::Error;
|
||||||
|
main.borrow_mut().action = FSMStateAction::Error;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Link last main to goal,error,side
|
||||||
|
match &mut main_line.last() {
|
||||||
|
Some(main_last) => {
|
||||||
|
let last_digit = min % 10;
|
||||||
|
match &mut main_last.borrow_mut().transition {
|
||||||
|
Some(t) => {
|
||||||
|
// Main -> Goal (=)
|
||||||
|
t.apply(TransitionMask::from(MaskPresets::NumberRange(0..=(last_digit as u8))),
|
||||||
|
Rc::downgrade(&goal_state)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Main -> Error (+)
|
||||||
|
t.apply(TransitionMask::from(MaskPresets::NumberRange(0..=(last_digit as u8))),
|
||||||
|
Rc::downgrade(&goal_state)
|
||||||
|
);
|
||||||
|
|
||||||
|
},
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Link goal to error
|
||||||
|
goal_state.borrow_mut().set_transitions(FSMTranistion::new(Rc::downgrade(&error_state)));
|
||||||
|
|
||||||
|
// Linking error to error
|
||||||
|
error_state.borrow_mut().set_transitions(FSMTranistion::new(Rc::downgrade(&error_state)));
|
||||||
|
|
||||||
|
// Combinding in one array
|
||||||
|
let mut states: Vec<Rc<std::cell::RefCell<FSMState>>> = vec![error_state, goal_state];
|
||||||
|
let first_state: Option<FSMStateRef> = match main_line.first() {
|
||||||
|
None => None,
|
||||||
|
Some(first) => {
|
||||||
|
Some(first.clone())
|
||||||
|
}
|
||||||
|
};
|
||||||
|
states.append(&mut main_line);
|
||||||
|
states.append(&mut side_line);
|
||||||
|
|
||||||
|
let mut fsm = FSM {
|
||||||
|
name: format!("FSM_LowerBound_{}", min),
|
||||||
|
states: states,
|
||||||
|
start: first_state
|
||||||
|
};
|
||||||
|
|
||||||
|
elimate_unused_states(&mut fsm);
|
||||||
|
|
||||||
|
fsm
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use graphviz_rust::cmd::Format;
|
use graphviz_rust::cmd::Format;
|
||||||
|
|
||||||
use crate::configotron::fsm::{builder::numbers::{create_fsm_number_upperbound, number_of_digits}, run::run_fsm, test::debug_file_dump, FSMStateAction};
|
use crate::configotron::fsm::{builder::numbers::{create_fsm_number_upper_bound, number_of_digits}, run::run_fsm, test::debug_file_dump, FSMStateAction};
|
||||||
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn build_upper_bound() {
|
fn build_upper_bound() {
|
||||||
|
|
||||||
for max in vec![4026, 124, 9999, 1000, 0, 42398] {
|
for max in vec![4026, 124, 9999, 1000, 0, 42398] {
|
||||||
let fsm = create_fsm_number_upperbound(max);
|
let fsm = create_fsm_number_upper_bound(max);
|
||||||
let data = fsm.render_graph(Format::Svg).unwrap();
|
let data = fsm.render_graph(Format::Svg).unwrap();
|
||||||
println!("Testing Lower Bound FSM {}", max);
|
println!("Testing upper Bound FSM {}", max);
|
||||||
|
|
||||||
for i in 0..=(if max == 0 {10} else {max * 10} ) {
|
for i in 0..=(if max == 0 {10} else {max * 10} ) {
|
||||||
|
|
||||||
@@ -175,7 +258,7 @@ mod test {
|
|||||||
FSMStateAction::Terminal
|
FSMStateAction::Terminal
|
||||||
} else {
|
} else {
|
||||||
FSMStateAction::Error
|
FSMStateAction::Error
|
||||||
});
|
}, "{} yield the wrong final state", i);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Testing against refernce machine
|
// Testing against refernce machine
|
||||||
@@ -185,6 +268,29 @@ mod test {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn build_lower_bound() {
|
||||||
|
for max in vec![4026, 124, 9999, 1000, 0, 42398] {
|
||||||
|
let fsm = create_fsm_number_upper_bound(max);
|
||||||
|
let data = fsm.render_graph(Format::Svg).unwrap();
|
||||||
|
println!("Testing Lower Bound FSM {}", max);
|
||||||
|
|
||||||
|
for i in 0..=(if max == 0 {10} else {max * 10} ) {
|
||||||
|
|
||||||
|
assert_eq!(run_fsm(&i.to_string(), &fsm), if i >= max {
|
||||||
|
FSMStateAction::Terminal
|
||||||
|
} else {
|
||||||
|
FSMStateAction::Error
|
||||||
|
}, "{} yield the wrong final state", i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Testing against refernce machine
|
||||||
|
let file_name = format!("build_number_lower_bound_{}.svg", max);
|
||||||
|
debug_file_dump(data.clone(), format!("/tmp/{}", file_name).to_string());
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn number_of_digits_test() {
|
fn number_of_digits_test() {
|
||||||
assert_eq!(number_of_digits(0), 1);
|
assert_eq!(number_of_digits(0), 1);
|
||||||
|
|||||||
Reference in New Issue
Block a user