Basic SVG output

This commit is contained in:
Arne Keller 2021-03-15 16:42:00 +01:00
parent d5e3da78f9
commit 900541c05f
6 changed files with 125 additions and 4 deletions

5
Cargo.lock generated
View File

@ -20,4 +20,9 @@ name = "kv"
version = "0.0.1"
dependencies = [
"itertools",
"svg_fmt",
]
[[package]]
name = "svg_fmt"
version = "0.4.0"

View File

@ -8,3 +8,4 @@ edition = "2018"
[dependencies]
itertools = "0.10.0"
svg_fmt = { path = "../rust_debug/svg_fmt" }

73
src/bin/svg.rs Normal file
View File

@ -0,0 +1,73 @@
use svg_fmt::*;
use kv::*;
const SIZE_FACTOR: usize = 64;
const SIZE_FONT: f32 = 20.0;
const SIZE4: usize = SIZE_FACTOR / 4;
const COLORS: &'static [Color] = &[
rgb(0, 0, 255),
rgb(255, 0, 0),
rgb(0, 255, 0),
rgb(255, 255, 0),
];
fn main() {
let function = vec![0, 0, 1, 1, 1, 1, 1, 0].into_iter().map(Into::into).collect();
let groups = find_groups(&function, &[A, B, C], One);
eprintln!("all:");
for x in &groups {
eprintln!("{}", print_implicant(x));
}
eprintln!("prime:");
let prime = find_prime(&function, &[A, B, C], One, &groups);
for x in &prime {
eprintln!("{}", print_implicant(x));
}
eprintln!("solutions:");
let solutions = all_solutions(function.clone(), &[A, B, C], One, &prime, &groups);
for sol in solutions {
for x in &prime {
eprint!("{} | ", print_implicant(x));
}
for x in &sol {
eprint!("{} | ", print_implicant(x));
}
eprintln!();
}
let block_masks = groups.iter()
.map(block_to_mask)
.collect::<Vec<_>>();
let (grid, w, h) = grid(3);
println!("{}", BeginSvg { w: w * SIZE_FACTOR + 3, h: h * SIZE_FACTOR + 3 });
for (i, (x, y)) in grid.iter().enumerate() {
println!("{}",
rectangle(1 + x * SIZE_FACTOR, 1 + y * SIZE_FACTOR, SIZE_FACTOR, SIZE_FACTOR)
.fill(white())
.stroke(Stroke::Color(black(), 2.0))
);
let mut rect = rectangle(1 + x * SIZE_FACTOR, 1 + y * SIZE_FACTOR, SIZE_FACTOR, SIZE_FACTOR)
.fill(white())
.stroke_opacity(0.7);
for (idx, &(mask, inv_mask)) in block_masks.iter().enumerate() {
rect = rect.inflate(-2, -2);
if check_mask(i, mask, inv_mask) {
println!("{}", rect.stroke(Stroke::Color(COLORS[idx], 2.0)));
}
}
println!("{}",
text((x+1) * SIZE_FACTOR - SIZE4, (y+1) * SIZE_FACTOR - SIZE4 / 3, i.to_string())
.size(SIZE_FONT)
.color(black())
);
println!("{}",
text(x * SIZE_FACTOR + SIZE4, (y+1) * SIZE_FACTOR - SIZE4, function[i].to_string())
.size(SIZE_FONT * 2.0)
.color(black())
);
}
println!("{}", EndSvg);
}

View File

@ -1,5 +1,10 @@
use std::fmt::{self, Display};
use itertools::Itertools;
mod ui;
pub use ui::*;
pub type Variable = usize;
pub type Block = Vec<(Variable, Output)>;
pub type BlockRef<'a> = &'a [(Variable, Output)];
@ -15,7 +20,7 @@ pub enum Output {
Any
}
use Output::*;
pub use Output::*;
impl Output {
fn to_num(self) -> usize {
@ -45,6 +50,16 @@ impl From<usize> for Output {
}
}
impl fmt::Display for Output {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Zero => write!(f, "0"),
One => write!(f, "1"),
Any => write!(f, "-")
}
}
}
pub type FunctionSpec = Vec<Output>;
pub fn find_groups(func: &FunctionSpec, vars: &[Variable], typ: Output) -> Vec<Vec<(Variable, Output)>> {
@ -175,7 +190,7 @@ fn subset_of<T: Eq>(a: &[T], b: &[T]) -> bool {
a.iter().all(|x| b.contains(x))
}
fn block_to_mask<T: AsRef<[(Variable, Output)]>>(block: T) -> (Variable, Variable) {
pub fn block_to_mask<T: AsRef<[(Variable, Output)]>>(block: T) -> (Variable, Variable) {
let mut mask = 0;
let mut inv_mask = !0;
for &(var, out) in block.as_ref() {
@ -186,7 +201,7 @@ fn block_to_mask<T: AsRef<[(Variable, Output)]>>(block: T) -> (Variable, Variabl
}
#[inline(always)]
fn check_mask(input: usize, mask: usize, inv_mask: usize) -> bool {
pub fn check_mask(input: usize, mask: usize, inv_mask: usize) -> bool {
input | mask == input && input & inv_mask == input
}

View File

@ -1,5 +1,4 @@
use kv::*;
use kv::Output::*;
fn main() {
let function = vec![0, 0, 1, 1, 1, 1, 1, 0].into_iter().map(Into::into).collect();

28
src/ui.rs Normal file
View File

@ -0,0 +1,28 @@
/// Returns grid coordinates, width, height
pub fn grid(var_count: usize) -> (Vec<(usize, usize)>, usize, usize) {
let mut grid = vec![(0, 0), (1, 0)];
let mut h = 1;
let mut w = 2;
for _ in 1..var_count {
if w > h {
h *= 2;
let prev_grid_size = grid.len();
for i in 0..prev_grid_size {
let mut cell = grid[i];
cell.1 = h - 1 - cell.1;
grid.push(cell);
}
} else {
w *= 2;
let prev_grid_size = grid.len();
for i in 0..prev_grid_size {
let mut cell = grid[i];
cell.0 = w - 1 - cell.0;
grid.push(cell);
}
}
}
(grid, w, h)
}