DMF/KMF switch

This commit is contained in:
Arne Keller 2021-03-19 18:14:41 +01:00
parent 6b4c6d9c22
commit 8dff087377
4 changed files with 57 additions and 19 deletions

View File

@ -16,4 +16,4 @@ itertools = "0.10.0"
log = "0.4.14"
svg_fmt = { path = "../rust_debug/svg_fmt" }
wasm-bindgen = "0.2.71"
web-sys = { version = "0.3.48", features = ["Window", "Document", "Location", "HtmlCollection", "HtmlElement", "CssStyleDeclaration", "HtmlTextAreaElement", "HtmlInputElement"] }
web-sys = { version = "0.3.48", features = ["Window", "Document", "Location", "HtmlCollection", "HtmlElement", "HtmlSelectElement", "CssStyleDeclaration", "HtmlTextAreaElement", "HtmlInputElement"] }

View File

@ -32,15 +32,19 @@
<body>
<div id="main">
<div id="settings">
<label>Number of variables: <input type="number" value="3" id="variables"></label><button id="apply-variables">Apply</button>
<label>Number of variables: <input type="number" min="1" value="3" id="variables"></label><button id="apply-variables">Apply</button>
</div>
<p id="hints">
Change cells by scrolling (up => 1, down => 0), typing (=> 1, 0) or deleting (=> -).
Change output specification by scrolling (up => 1, down => 0), typing (=> 1, 0) or deleting (=> -).
</p>
<p id="examples">
Load <a href="#--111100">example 1</a>, <a href="#-1111000-1-01---">example 2</a>, <a href="#11101111111111111111101111111101">example 3</a>.
</p>
<div id="input-container"></div>
<div><label>Generate: <select id="mode-select">
<option value="dmf">DMF</option>
<option value="kmf">KMF</option>
</select></label></div>
<button id="calculate">Run</button>
<div id="output-help"></div>
<div id="output-container"></div>

View File

@ -3,7 +3,7 @@ use wasm_bindgen::JsCast;
use log::{Level, info};
use kv::*;
use web_sys::{EventTarget, HtmlElement, HtmlInputElement, HtmlTextAreaElement};
use web_sys::{EventTarget, HtmlElement, HtmlInputElement, HtmlSelectElement, HtmlTextAreaElement};
macro_rules! web {
($($x:ident)*) => {
@ -77,15 +77,16 @@ fn span(text: &str) -> HtmlElement {
pub fn run() {
let document = web!(document);
let mode = get_mode();
let var_count = get_var_number();
let vars = (0..var_count).map(|x| 2usize.pow(x as u32)).collect::<Vec<_>>();
let function: FunctionSpec = (0..2usize.pow(var_count as u32)).map(|idx| get_input(idx)).collect();
info!("function: {:?}", function);
let hash = Some('#').into_iter().chain(function.iter().map::<char, _>(|&x| x.into())).collect::<String>();
web2!(location).set_hash(&hash).unwrap();
let groups = find_groups(&function, &vars, One);
let (prime, other) = find_core(&function, &vars, One, &groups);
let solutions = real_solutions_idxed(function.clone(), &vars, One, &prime, &other);
let groups = find_groups(&function, &vars, mode);
let (prime, other) = find_core(&function, &vars, mode, &groups);
let solutions = real_solutions_idxed(function.clone(), &vars, mode, &prime, &other);
let output_container = get_output_container();
if output_container.children().length() == 0 {
@ -106,13 +107,7 @@ pub fn run() {
let svg = svg_container.children().item(0).unwrap().unchecked_into::<HtmlElement>();
svg.style().set_property("width", &format!("{}px", w * 80)).unwrap();
svg.style().set_property("height", &format!("{}px", h * 80)).unwrap();
let mut text = String::new();
for x in $sol {
if !text.is_empty() {
text += " ";
}
text += &print_implicant(x);
}
let mut text = if mode == Output::One { print_df($sol) } else { print_mf($sol) };
if text.is_empty() {
text += ".";
}
@ -124,13 +119,13 @@ pub fn run() {
let mut block_masks: Vec<_> = prime.iter()
.map(block_to_mask)
.collect();
render_svg!(&prime, &block_masks);
render_svg!(prime.iter().map(|x| *x), &block_masks);
block_masks = prime.iter()
.map(block_to_mask)
.chain(other.iter().map(block_to_mask)) // also display non-core
.collect();
render_svg!(prime.iter().chain(other.iter()), &block_masks);
render_svg!(prime.iter().chain(other.iter()).map(|x| *x), &block_masks);
let mut size = usize::MAX;
for sol in &solutions {
@ -148,8 +143,8 @@ pub fn run() {
}
}))
.collect();
let blocks = prime.iter()
.chain(sol.iter().map(|&i| &other[i]));
let blocks = prime.iter().map(|x| *x)
.chain(sol.iter().map(|&i| other[i]));
render_svg!(blocks, &block_masks);
}
@ -180,6 +175,17 @@ fn get_var_number() -> usize {
get_var_number_el().value().parse().unwrap()
}
fn get_mode_el() -> HtmlSelectElement {
web!(document).get_element_by_id("mode-select").unwrap().unchecked_into()
}
fn get_mode() -> Output {
match &*get_mode_el().value() {
"kmf" => Output::Zero,
"dmf" | _ => Output::One,
}
}
fn get_input_container() -> HtmlElement {
web!(document).get_element_by_id("input-container").unwrap().unchecked_into::<HtmlElement>()
}

View File

@ -289,6 +289,21 @@ pub fn block_to_mask<T: AsRef<[(Variable, Output)]>>(block: T) -> (Variable, Var
pub fn check_mask(input: usize, mask: usize, inv_mask: usize) -> bool {
input | mask == input && input & inv_mask == input
}
pub fn print_mf<'a, I>(x: I) -> String
where I: IntoIterator<Item = &'a[(Variable, Output)]>
{
let mut text = String::new();
for x in x {
if !text.is_empty() {
text += ") ∧ (";
} else {
text.push('(');
}
text += &print_implicate(x);
}
text.push(')');
text
}
pub fn print_implicate(vars: &[(Variable, Output)]) -> String {
let mut s = String::new();
@ -299,12 +314,25 @@ pub fn print_implicate(vars: &[(Variable, Output)]) -> String {
s += "̅";
}
if i != vars.len() - 1 {
s += " v ";
s += " ";
}
}
s
}
pub fn print_df<'a, I>(x: I) -> String
where I: IntoIterator<Item = &'a[(Variable, Output)]>
{
let mut text = String::new();
for x in x {
if !text.is_empty() {
text += " ";
}
text += &print_implicant(x);
}
text
}
pub fn print_implicant(vars: &[(Variable, Output)]) -> String {
let mut s = String::new();
for i in 0..vars.len() {