Skip to content

Commit

Permalink
Add API endpoint for automatic expansion of decision tree nodes.
Browse files Browse the repository at this point in the history
  • Loading branch information
daemontus committed Mar 12, 2021
1 parent 854bd3c commit 2adcfa1
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 5 deletions.
6 changes: 3 additions & 3 deletions src/bdt/_impl_bdt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,17 +231,17 @@ impl Bdt {
/// up to the given `depth`.
///
/// Returns the list of changed node ids.
pub fn auto_expand(&mut self, node: BdtNodeId, depth: usize) -> Vec<BdtNodeId> {
pub fn auto_expand(&mut self, node: BdtNodeId, depth: u32) -> HashSet<BdtNodeId> {
let mut changed = HashSet::new();
self.auto_expand_recursive(&mut changed, node, depth);
changed.into_iter().collect()
changed
}

fn auto_expand_recursive(
&mut self,
changed: &mut HashSet<BdtNodeId>,
node: BdtNodeId,
depth: usize,
depth: u32,
) {
if depth == 0 {
return;
Expand Down
17 changes: 15 additions & 2 deletions src/bdt/_impl_bdt_json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::util::functional::Functional;
use crate::util::index_type::IndexType;
use biodivine_lib_param_bn::symbolic_async_graph::GraphColors;
use json::JsonValue;
use std::collections::HashMap;
use std::collections::{HashMap, HashSet};

impl BdtNode {
/// Convert this BDT node to json value with all available information stored in the node.
Expand Down Expand Up @@ -66,6 +66,17 @@ impl BdtNode {
impl Bdt {
/// Convert the whole tree into one json array.
pub fn to_json(&self) -> JsonValue {
let ids = self
.storage
.keys()
.map(|id| BdtNodeId(*id))
.collect::<HashSet<_>>();
self.to_json_partial(&ids)
}

/// A variant of `to_json` which allows to specify a subset of IDs that are considered during
/// export. Other nodes are not included in the result.
pub fn to_json_partial(&self, ids: &HashSet<BdtNodeId>) -> JsonValue {
// The order of nodes is irrelevant, but we only want to include nodes that are relevant
// with the selected precision.
let mut json_array = JsonValue::Array(vec![]);
Expand All @@ -82,7 +93,9 @@ impl Bdt {
let right_id = BdtNodeId::try_from(right, &self).unwrap();
stack.push(right_id);
}
json_array.push(node_json).unwrap();
if ids.contains(&top) {
json_array.push(node_json).unwrap();
}
}
json_array
}
Expand Down
29 changes: 29 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,34 @@ fn revert_decision(node_id: String) -> BackendResponse {
};
}

#[post("/auto_expand/<node_id>/<depth>")]
fn auto_expand(node_id: String, depth: String) -> BackendResponse {
let depth: u32 = {
let parsed = depth.parse::<u32>();
if let Ok(depth) = parsed {
depth
} else {
return BackendResponse::err(&format!("Invalid tree depth: {}", depth));
}
};
if depth > 10 {
return BackendResponse::err(&"Maximum allowed depth is 10.".to_string());
}
let tree = TREE.clone();
let mut tree = tree.write().unwrap();
if let Some(tree) = tree.as_mut() {
let node_id: BdtNodeId = if let Some(node_id) = BdtNodeId::try_from_str(&node_id, tree) {
node_id
} else {
return BackendResponse::err(&format!("Invalid node id {}.", node_id));
};
let changed = tree.auto_expand(node_id, depth);
BackendResponse::ok(&tree.to_json_partial(&changed).to_string())
} else {
BackendResponse::err(&"Cannot modify decision tree.".to_string())
}
}

#[post("/apply_tree_precision/<precision>")]
fn apply_tree_precision(precision: String) -> BackendResponse {
if let Ok(precision) = precision.parse::<u32>() {
Expand Down Expand Up @@ -1260,6 +1288,7 @@ fn main() {
revert_decision,
apply_tree_precision,
get_tree_precision,
auto_expand,
],
)
.launch();
Expand Down

0 comments on commit 2adcfa1

Please sign in to comment.