Skip to content

Commit

Permalink
#49: check for inconsistencies
Browse files Browse the repository at this point in the history
  • Loading branch information
yegor256 committed Sep 28, 2022
1 parent b1e07e5 commit d6f2a7d
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 31 deletions.
20 changes: 1 addition & 19 deletions src/universe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ mod i_atom;
mod i_bind;
mod i_copy;
mod i_data;
mod inconsistencies;
mod inspect;
mod serialization;

use crate::data::Data;
use anyhow::Result;
use log::error;
use serde::{Deserialize, Serialize};
use std::collections::{HashMap, HashSet};
use std::fmt;
Expand Down Expand Up @@ -226,24 +226,6 @@ impl Universe {
latest_e: self.latest_e,
})
}

/// Validate the Universe and return all found data
/// inconsistencies. This is mostly used for testing.
pub fn inconsistencies(&self) -> Vec<String> {
let mut errors = Vec::new();
for (e, edge) in self.edges.iter() {
if !self.vertices.contains_key(&edge.to) {
errors.push(format!("Edge ε{} arrives to lost ν{}", e, edge.to));
}
if !self.vertices.contains_key(&edge.from) {
errors.push(format!("Edge ε{} departs from lost ν{}", e, edge.from));
}
}
for e in errors.to_vec() {
error!("{}", e)
}
errors
}
}

#[cfg(test)]
Expand Down
21 changes: 10 additions & 11 deletions src/universe/dataize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ impl Universe {
break;
}
let k = next.unwrap().to_string();
trace!("#find: at ν{}, going to .{}", v, k);
if k.is_empty() {
return Err(anyhow!("System error, the locator is empty"));
}
Expand All @@ -84,7 +83,7 @@ impl Universe {
));
}
if k == "Δ" && self.vertices.get(&v).unwrap().data.is_some() {
trace!("#find: data is right here at ν{}", v);
trace!("#find: ν{}.Δ is found!", v);
break;
}
if k.starts_with("ν") {
Expand All @@ -95,26 +94,26 @@ impl Universe {
}
if k == "ξ" {
v = v;
trace!("#find: staying at ν{}", v);
trace!("#find: ν{}.ξ -> {}", v, v);
continue;
}
if k == "Φ" || k == "Q" {
v = 0;
trace!("#find: going to Φ/ν{}", v);
trace!("#find: Φ/ν{}", v);
continue;
}
if let Some(to) = self.edge(v, k.as_str()) {
trace!("#find: .{} found in ν{}, pointing to ν{}", k, v, to);
trace!("#find: ν{}.{} -> ν{}", v, k, to);
v = to;
continue;
};
// if let Some(to) = self.edge(v, "π") {
// trace!("#find: .π found in ν{}, pointing to ν{}", v, to);
// v = to;
// continue;
// }
if let Some(to) = self.edge(v, "π") {
trace!("#find: ν{}-> ν{} (.{} not found)", v, to, k);
v = to;
continue;
}
if let Some(to) = self.edge(v, "φ") {
trace!("#find: .φ found in ν{}, pointing to ν{}", v, to);
trace!("#find: ν{}-> ν{} (.{} not found)", v, to, k);
v = to;
locator.push_front(k);
continue;
Expand Down
2 changes: 2 additions & 0 deletions src/universe/i_copy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,9 @@ impl Universe {
}
}

#[cfg(test)]
use crate::data::Data;

#[cfg(test)]
use crate::{add, bind, copy};

Expand Down
103 changes: 103 additions & 0 deletions src/universe/inconsistencies.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
// Copyright (c) 2022 Yegor Bugayenko
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

use crate::universe::Universe;
use log::error;

impl Universe {
/// Validate the Universe and return all found data
/// inconsistencies. This is mostly used for testing.
pub fn inconsistencies(&self) -> Vec<String> {
let mut errors = Vec::new();
for e in self.lost_edges() {
errors.push(e);
}
for e in self.exclusive_trio() {
errors.push(e);
}
for e in errors.to_vec() {
error!("{}", e)
}
errors
}

/// Finds all edges that have lost ends.
fn lost_edges(&self) -> Vec<String> {
let mut errors = Vec::new();
for (e, edge) in self.edges.iter() {
if !self.vertices.contains_key(&edge.to) {
errors.push(format!("Edge ε{} arrives to lost ν{}", e, edge.to));
}
if !self.vertices.contains_key(&edge.from) {
errors.push(format!("Edge ε{} departs from lost ν{}", e, edge.from));
}
}
errors
}

/// Finds all vertices that violate this rule: `π`, `φ`, or `λ` are
/// mutually exclusive.
fn exclusive_trio(&self) -> Vec<String> {
let mut errors = Vec::new();
for (v, vtx) in self.vertices.iter() {
let attrs = self
.edges
.iter()
.filter(|(_, e)| e.from == *v && (e.a == "π" || e.a == "φ"))
.count();
if vtx.lambda.is_some() && attrs > 0 {
errors.push(format!("ν{} already has λ, can't have π or φ", v));
continue;
}
if attrs > 1 {
errors.push(format!("ν{} can't have both π and φ", v));
}
}
errors
}
}

#[cfg(test)]
use crate::{add, bind};

#[cfg(test)]
use anyhow::Result;

#[test]
fn finds_lost_edge() -> Result<()> {
let mut uni = Universe::empty();
uni.add(0)?;
let v1 = add!(uni);
bind!(uni, 0, v1, "foo");
uni.vertices.remove(&v1);
assert_eq!(3, uni.inconsistencies().len());
Ok(())
}

#[test]
fn pi_and_phi_together() -> Result<()> {
let mut uni = Universe::empty();
let v1 = add!(uni);
let v2 = add!(uni);
bind!(uni, v1, v2, "π");
bind!(uni, v1, v2, "φ");
assert_eq!(1, uni.inconsistencies().len());
Ok(())
}
2 changes: 1 addition & 1 deletion tests/snippets_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ fn deploys_and_runs_all_apps() -> Result<()> {
.assert()
.success();
let mut uni = Universe::load(relf)?;
assert!(uni.inconsistencies().is_empty());
for app in all_apps()? {
println!("{}", uni.inspect(format!("Q.{}", app).as_str())?);
println!("{}", uni.slice(format!("Q.{}", app))?.to_graph()?);
let expected = da!(uni, format!("Φ.{}.expected", app));
let actual = da!(uni, format!("Φ.{}", app));
assert_eq!(expected, actual);
Expand Down

0 comments on commit d6f2a7d

Please sign in to comment.