I created a model of a tree. See below. Is there a better model? By "better" I mean simpler.
sig Node {
tree: set Node
}
one sig root extends Node {}
fact {
// No node above root (no node maps to root)
no tree.root
// Can reach all nodes from root
all n: Node - root | n in root.^tree
// No node maps to itself (irreflexive)
no iden & tree
// No cycles
no n: Node | Node in n.^tree
// All nodes are distinct (injective)
tree.~tree in iden
}
What's not simple about this? You could simplify the constraints:
sig Node {
tree: set Node
}
one sig root extends Node {}
pred CostelloTree {
// No node above root (no node maps to root)
no tree.root
// Can reach all nodes from root
all n: Node - root | n in root.^tree
// No node maps to itself (irreflexive)
no iden & tree
// No cycles
no n: Node | Node in n.^tree
// All nodes are distinct (injective)
tree.~tree in iden
}
pred DJTree {
Node in root.*tree // all reachable
no iden & ^tree // no cycles
tree in Node lone -> Node // at most one parent
}
check {CostelloTree iff DJTree}
Related
I was trying to change some of vector elements, while itering over the vector.
for operator in operators {
// add left side
let node = nodes[operator.index-1].clone();
nodes[operator.index].children.push(node);
// add right side
let node = nodes[operator.index+1].clone();
nodes[operator.index].children.push(node);
// remove used nodes
nodes.remove(operator.index+1);
nodes.remove(operator.index-1);
// two items were removed, so every index higher than the current one needs to be lowered by 2
for operator2 in &mut operators {
if operator2.index > operator.index {
operator2.index -= 2;
}
}
}
Sadly this isn't possible in rust, because error says that 'operators' was moved. I tried to change for to look like this:
for operator in &operators, but then it has problem getting 'operators' as mutable and immutable at the same time. What can I do to make it work?
Use simple loops with indices:
for operator_idx in 0..operators.len() {
let operator = &operators[operator_idx];
// add left side
let node = nodes[operator.index-1].clone();
nodes[operator.index].children.push(node);
// add right side
let node = nodes[operator.index+1].clone();
nodes[operator.index].children.push(node);
// remove used nodes
nodes.remove(operator.index+1);
nodes.remove(operator.index-1);
// two items were removed, so every index higher than the current one needs to be lowered by 2
for operator2 in &mut operators {
if operator2.index > operator.index {
operator2.index -= 2;
}
}
}
I am trying to implement, through Gun, a tree structure that allows to express relationships between companies, subsidiaries of these companies and their products.
The structure that I have done is as follows:
there is a root node: this is the main seller of some product (for example, sensors) and all its children (depth nodes 1) are its customers;
there are children nodes, not leaves, from level depth 1 on: these are the customers of the root knot; they can have different branches; there can be sub-sub-sub-branches of a branch and so on, there are no limits to the number of sub-subbranches;
there are leaf knots: these are the products contained in a branch, a sub-branch, a sub-sub-branch...
Here's how I thought of this:
create a client set;
put clients nodes inside client set;
create a branch set;
put branches nodes inside branch set;
link branches set to client set;
create a sensor set;
put sensors nodes inside sensor set;
link sensors set to branches set.
Somethink like this:
[clients]
/\
/ \
(MecDoland) (FrankMirros)
| |
[branches] [branches]
/ | \ |
(NY) (CA) (DA) ...
| | |
| [sensors]...
| |
| ...
[sensors]
/|\
......
Here's my implementation
const Gun = require('gun')
const gun = new Gun()
// Just a util function
function printError(ack) {
if (ack.err) {
console.log(ack.err)
}
}
// [clients]
const clients = gun.get('clients') // group
// (MecDoland)
const mac = clients.get('MecDoland').put({ data: 12 })
// (FrankMirros)
const pm = clients.get('FrankMirros').put({ data: 13 })
console.log('Adding to "clients" set MecDoland...')
// [clients] -> (MecDoland)
clients.set(mac, printError)
console.log('Adding to "clients" set philip morris...')
// [clients] -> (FrankMirros)
clients.set(pm, printError)
// [branches]
const branches = gun.get('branches') // group
// (MecDolandNY)
const macny = gun.get('MacDonaldNY').put({ data: 1 }, printError)
// (MecDolandCA)
const macca = gun.get('MecDolandCA').put({ data: 2 }, printError)
// [branches] -> (MecDolandNY)
branches.set(macny, printError)
// [branches] -> (MecDolandCA)
branches.set(macca, printError)
// [MecDoland] -> [branches]
mac.set(branches, printError)
//clients.map().once(v => console.log('CLIENT:',v))
//branches.map().once(v => console.log('BRANCH:',v._))
const sensors = gun.get('sensorsMecDolandNY') // group
const temp = gun.get('temperatue').put({ measure: 'celsius', value: 37 })
const press = gun.get('pressure').put({ measure: 'Bar', value: 2 })
sensors.set(temp)
sensors.set(press)
macny.set(sensors)
// Show all clients
gun
.get('clients')
.map()
.once(v => console.log(v))
There are two points that I haven't been able to clarify:
1 - I don't know if I am using Gun sets well: I tried to add some relationships but didn't work out; consider the following instructions:
macDoland.get('client').put(rootNode)
frankMirrors.get('client').put(rootNode)
I tried to put a client relationship for both customer nodes, but printing rootNode showed me that rootNode had client relationship only with frankMirrors node! The first relationship with macDoland node disappeared so I started using Gun sets.
My code works (more or less) but I don't know if I am using Gun set properly and if this is the right way to do it, given the kind of relationship I want to build between main vendors, customers, customers' branches and sensors in each branch.
2 - I'd like to make this approach more generic and scalable: for now there are clients, branches and sensors; this may change in future and the number of levels between clients and sensors may increase.
This means that there may be an arbitrary number of levels between client nodes (depth 1) and sensors (max depth): for example, a very small client may be without branches and thus its client node smallCompany would directly be linked to its sensors; for another example, a gigantic client may have (say) five level of depths and I don't want to hard-code Gun set names such as macDolandNySubSubSubSubBranch.
How could I provide scalability for an arbitrary number of sub-branches?
I am using IGtree.
I have data in tree till 4 levels in tree.
Initially all nodes are collapsed.
On expanding any particular node, all its child nodes should get expanded also till the last level
One of the options is to handle nodeExpanding event to distinguish the root nodes and find their children which are parents. Then expand every node and all the nodes up to the root node. Here as a code snippet:
$(document).on("igtreenodeexpanding", "#tree", function (evt, ui) {
// this ensures the expanding node is on root level.
if (ui.node.path.indexOf(ui.owner.options.pathSeparator) <= -1) {
// Select all the nodes whcih contain children
// Here you can play with the path if you want to limit expanding to a certain level
var nodes = $(ui.node.element).find("li[data-role='node'].ui-igtree-parentnode");
for (var i = 0; i < nodes.length ; i++) {
var node = $(nodes[i]);
ui.owner.expand(node);
ui.owner.expandToNode(node);
// or you can use:
// $("#tree").igTree("expand", node);
// $("#tree").igTree("expandToNode", node);
}
}
});
Hope that helps.
let nodes = $("#configTree").igTree("children", event.element);
if(nodes) {
nodes.forEach((node1)=>{
$("#configTree").igTree("expand", node1.element);
})
}
I have a tree of elements. I harvest data from some of the elements and use that data to create a set of nodes. I want an assert to check that, given access to only the set of nodes, there is no possibility of accessing other data, such as data in other elements of the tree. That is, I want to ensure no data leakage.
Here is my tree of elements:
sig Element {
data: Data,
children: set Element
}
I harvest data from some elements. I stuff the data into nodes:
sig Node {
data: Data
}
If someone has access to just the set of nodes, then there is no data leakage because the nodes contain just the data that was deliberately harvested from elements in the tree.
However, for debugging purposes I added a field to Node to reference the Element that was the source of the Node's data:
sig Node {
data: Data,
represents: Element
}
Through accidental oversight, the represents field was not removed. Now a person with access to the set of Node also has access to the tree and therefore can see more data than the person should. Thus, there is the potential for data leakage.
I want to create an assert that checks the model for potential data leakage:
assert No_data_leakage { ??? }
Intuitively, I want the assert to say something like this: Of the universe (univ) of values in this model, a person with access to only the set of Nodes just has access to the data values in the set of Nodes and nothing else. How do I express that?
Below is a simplified version of my model.
open util/ordering[Element]
open util/ordering[Node]
sig Element {
data: Data,
children: set Element
}
one sig Root extends Element {}
sig Data {}
sig Node {
data: Data,
represents: Element
}
fact No_disconnected_elements {
all e: Element |
(e = Root) or (e in Root.^children)
}
fact Each_element_has_one_parent {
no disj e, e', e'': Element |
(e in e'.children) and (e in e''.children)
}
fact No_loops {
no e: Element | e in e.^children
}
fact First_Node_data_is_first_Element_data {
(Node <: first).data = (Element <: first).data
(Node <: first).represents = (Element <: first)
}
fact Last_Node_data_is_last_Element_data {
(Node <: last).data = (Element <: last).data
(Node <: last).represents = (Element <: last)
}
fact Every_element_has_different_data {
no disj e, e': Element | e.data = e'.data
}
run {} for 3 but 2 Node
assert No_data_leaks {
// How to express this?
}
See http://alloytools.org/quickguide/meta.html
There is a meta capability that allows you to 'iterate' over the fields of an Atom.
assert no_data_leaks {
all f : Node$.subfields| f.value[Node] in Data
}
Having a graph, actually it is a tree: vertexes are nodes, edges are labeled as "subnode" and directed from child to parent.
I need to make gremlin query to get recursive structure as this:
node_info = [properties: node.map(),
subnodes: [...list of node_info items...]]
Groovy function describes more precisely what I need to get:
def get_node_hierarchy(node_id) {
def get_hierarchy(node) {
def hierarchy_list = []
for (subnode in node.in('subnode')) {
sub_hierarchy = get_hierarchy(subnode)
hierarchy_list.add(sub_hierarchy)
}
[properties: node.map(), subnodes: hierarchy_list]
}
node = g.V('node_id', node_id).next()
get_hierarchy(node)
}
result = get_node_hierarchy(1)
Is it possible to implement this using a single Gremlin query?