open_hypergraphs/lax/var/
var.rs1use crate::lax::hypergraph::*;
2use crate::lax::open_hypergraph::*;
3
4use std::cell::RefCell;
5use std::rc::Rc;
6
7pub trait HasVar {
12 fn var() -> Self;
14}
15
16#[derive(Clone, Debug)]
17pub struct Var<O, A> {
18 pub state: Rc<RefCell<OpenHypergraph<O, A>>>,
19 pub edge_id: EdgeId,
20 pub label: O,
21}
22
23impl<O: Clone, A: HasVar> Var<O, A> {
25 pub fn new(state: Rc<RefCell<OpenHypergraph<O, A>>>, default_node_label: O) -> Self {
26 let (edge_id, _) = state.borrow_mut().new_operation(A::var(), vec![], vec![]);
27 Var {
28 state,
29 edge_id,
30 label: default_node_label,
31 }
32 }
33
34 pub fn new_source(&self) -> NodeId {
36 self.state
37 .borrow_mut()
38 .add_edge_source(self.edge_id, self.label.clone())
39 }
40
41 pub fn new_target(&self) -> NodeId {
43 self.state
44 .borrow_mut()
45 .add_edge_target(self.edge_id, self.label.clone())
46 }
47}
48
49pub type BuildResult<O, A> = Result<OpenHypergraph<O, A>, Rc<RefCell<OpenHypergraph<O, A>>>>;
50
51pub fn build<F, O: Clone, A: HasVar>(f: F) -> BuildResult<O, A>
54where
55 F: Fn(&Rc<RefCell<OpenHypergraph<O, A>>>) -> (Vec<Var<O, A>>, Vec<Var<O, A>>),
56{
57 let state = Rc::new(RefCell::new(OpenHypergraph::<O, A>::empty()));
58 {
59 let (s, t) = f(&state);
60 state.borrow_mut().sources = s.iter().map(|x| x.new_source()).collect();
61 state.borrow_mut().targets = t.iter().map(|x| x.new_target()).collect();
62 }
63 Rc::try_unwrap(state).map(|f| f.into_inner())
64}