neo4j: how to eliminate subpaths from the result - neo4j

i want to return paths of size 0..4 starting from node a. but i want to return only the longest paths (skip subpaths). For graph:
a -> b - > c
|
| -> d
i'd like to return only a -> b -> c and a -> d but not a nor a -> b
edit
it means that if there is a path longer than 4, i still need the longest paths of size 0..4. so for:
a -> b -> c -> d -> e -> f
i'd like to get a -> b -> c -> d -> e

To get all paths up to length 4 that start at a root node and either end at a leaf node or have a length of 4:
MATCH path = (a)-[*0..4]->(b)
WHERE NOT ()-->(a) AND (LENGTH(path) = 4 OR NOT (b)-->())
RETURN path;

Reproducing with your sample data set:
CREATE (a:Node {name:"A"})-[:RELATION]->(b:Node {name:"B"})-[:RELATION]->(c:Node {name:"C"}),
(a)-[:RELATION]->(d:Node {name:"D"})
You can restrict the returned paths doing a WHERE this way:
match path = (a)-[*0..4]->(b)
where not ()-->(a) and not (b)-->()
return path
The output will be:
╒═══════════════════════════════════════════════════════════╕
│"path" │
╞═══════════════════════════════════════════════════════════╡
│[{"name":"A"},{},{"name":"B"},{"name":"B"},{},{"name":"C"}]│
├───────────────────────────────────────────────────────────┤
│[{"name":"A"},{},{"name":"D"}] │
└───────────────────────────────────────────────────────────┘

Related

Parse error when using case expression inside guards haskell

I am new to Haskell and I am having issues with syntax. What I want to do is given data and a tree of this datatype, find the path to the corresponding node in the tree. I believe my logic for the function is correct but I am not sure how to make it valid Haskell. I have tried changing tabs to spaces.
-- | Binary trees with nodes labeled by values of an arbitrary type.
data Tree a
= Node a (Tree a) (Tree a)
| End
deriving (Eq,Show)
-- | One step in a path, indicating whether to follow the left subtree (L)
-- or the right subtree (R).
data Step = L | R
deriving (Eq,Show)
-- | A path is a sequence of steps. Each node in a binary tree can be
-- identified by a path, indicating how to move down the tree starting
-- from the root.
type Path = [Step]
pathTo :: Eq a => a -> Tree a -> Maybe Path
pathTo a End = Nothing
pathTo a (Node b l r)
| a == b = Just []
| case (pathTo a l) of
Just p -> Just [L:p]
Nothing -> case (pathTo a r) of
Just p -> Just [R:p]
Nothing -> Nothing
This is the error:
parse error (possibly incorrect indentation or mismatched brackets)
The underlying problem here is that this does not look like a guard: a guard is an expression with type Bool, this determines if the guard "fires" or not. Here this is likely `otherwise:
pathTo :: Eq a => a -> Tree a -> Maybe Path
pathTo a End = Nothing
pathTo a (Node b l r)
| a == b = Just []
| otherwise = case (pathTo a l) of
Just p -> Just (L:p)
Nothing -> case (pathTo a r) of
Just p -> Just (R:p)
Nothing -> Nothing
This also revealed some extra mistakes: Just [L:p] is a Maybe [[Step]], you likely wanted to use Just (L:p), the same applies for Just [R:p].
You furthermore do not need to use nested cases, you can work with the Alternative typeclass:
import Control.Applicative((<|>))
pathTo :: Eq a => a -> Tree a -> Maybe Path
pathTo a End = Nothing
pathTo a (Node b l r)
| a == b = Just []
| otherwise = ((L:) <$> pathTo a l) <|> ((R:) <$> pathTo a r)
Here x <|> y will take x if it is a Just …, and y otherwise. We use (L:) <$> … to prepend the list wrapped in the Just data constructor, or return Nothing in case … is Nothing.

How to solve issue with insert function of f# trees

Please, I need some help with creating an insert function for a tree. The value in a given string list should be inserted to every branch and leaf in a tree. I have tried to solve this issue and have a very close answer but I am not able to write the function correctly to insert all the string values.
Code:
type Tree = Leaf of string | Branch of (string * Tree) list
let rec insertTree (lst : string list) (tree : Tree) : Tree =
match lst, tree with
| a::b::c::[], y ->
match y with
| Leaf(n) -> Branch[(a, Branch[(n, Leaf(c))])]
| Branch[(x, p)] -> Branch[(x, Branch[(a, Branch[(b, insertTree (c::[]) p)])])]
| _ -> insertTree (b::c::[]) y
| _ , y -> tree
Test: insertTree ["4"; "5";"6"] (Branch [("1", (Branch[("2", Leaf("3"))]))])
Gives: Branch [("1", Branch [("4", Branch [("5", Branch [("2", Leaf "3")])])])]
I want this instead:
(Branch [("1", (Branch[("2", (Branch[("3",(Branch[("4",(Branch[("5", Leaf("6"))]))]))]))]))])
I'm going to assume you just want to append the list in order to the final leaf and that all branches will have at most a single element in its list.
let insertTree (lst : string list) (tree : Tree) : Tree =
let rec insertSingleIntotree x t =
match t with
| Leaf(n) -> Branch[(n,Leaf x)]
| Branch[(n,p)] -> Branch[(n, insertSingleIntotree x p)]
| _ -> failwith "no idea what should happen here!"
lst
|> List.fold (fun acc x -> insertSingleIntotree x acc) tree

Creating tree from given path of string list in f#

I have a type defination:
type FsTree = Node of (string * FsTree) list
I create an empty node:
let createEmptyFsTree () : FsTree = Node[]
I would love to build a tree from a path of string list, for example:
let fs1 = create ["MainNode";"nodeA";"nodeB"] (createEmptyFsTree())
let fs2 = create ["MainNode";"nodeC";"nodeD"] fs1
let fs3 = create ["MainNode";"nodeC";"nodeE"] fs2
The result will be:
Node [("MainNode", Node [
("nodeA", Node [("nodeB", Node [])]);
("nodeC", Node [
("nodeD", Node[]);
("nodeE", Node[])])])]
This is my code so far. I have been stuck for 2 days. Please help.
let create (p : string list) (fs : FsTree) =
let rec create (p : string list) (fs : FsTree) =
match fs with
| Node n -> match p, n with
| h :: t, (name, rsNode) :: rsTree when name = h -> Node([(h, (create t rsNode))] # rsTree)
| _, lNode :: rsTree -> Node([lNode]#rsTree)
| h :: t, [] -> Node ([h, (create t (createEmptyFsTree()))])
| [],[] -> Node[]
create p fs
I am only able to create the tree from the first path passed:
Node [("MainNode", Node [("nodeA", Node [("nodeB", Node [])])])]
The difficulty of this problem is that there are several structures (the path is a list, each node is a list and a subtree) that need to be traversed recursively at the same time in order for it to work. Doing so in just one function becomes very hard to figure out.
That is why I like to simplify the problem by breaking it down into smaller parts. Here we are going to use 2 mutually recursive functions (notice the syntax). First I am going to rename the functions so that I understand better what they do. I also avoid repeating the same name for functions and variables as it is confusing. My first function will only deal with traversing the path p:
let rec addPath (p : string list) (Node ns) =
match p with
| [] -> Node ns
| hp :: tp -> Node (addHeadPath hp tp ns)
I use pattern matching on the second parameter (Node ns) to get the list of subnodes, that is because the next function will traverse that list.
In my match expression I like to take care first of the empty list case which is the end of the recursion. The second case separates the head and tail and sends them to another function to deal with it:
and addHeadPath hp tp ns =
match ns with
| [] -> [hp, addPath tp (Node[]) ]
| (nn, st) :: tn when nn = hp -> (nn, addPath tp st ) :: tn
| hn :: tn -> hn :: addHeadPath hp tp tn
addHeadPathTo is mutually recursive with addPathTo so I tie them together with and instead of another let rec.
Again the empty case is dealt with first which returns a list with one node and calls addPathTo to add the rest of the path. The second case is when the node already exists in which case we add the rest of the path to the subtree st. The third case keeps looking into the list of nodes by calling itself recursively.
You invoke it this way:
createEmptyFsTree()
|> addPath ["MainNode";"nodeA";"nodeB"]
|> addPath ["MainNode";"nodeC";"nodeD"]
|> addPath ["MainNode";"nodeC";"nodeE"]
|> printfn "%A"

match the first two elements of a list

I have a list :
[objA;objB;objC;objD]
I need to do the following reduction :
obj -> obj -> obj
ie :
objA objB -> objB'
and then take back the original list so that I get :
[objB';objC;objD]
I am trying to do the following :
let rec resolveConflicts = function
| [] -> []
| [c] -> resolveConflict c
| [x;y] -> resolveConflict x
|> List.filter getMovesRelatedtoY
|> List.append y
|> resolveConflict
| [x;y::tail] ->
let y' = resolveConflict x
|> List.filter getMovesRelatedtoY
|> List.append y
resolveConflicts y'::tail
This syntax is not correct, may be I am not even using the correct tool... I am open to any well suited solution so that I can learn.
As to why, I filter the list and append one to another, it is just that every conflict is a list of moves.
To match first element, second element and the rest of the list, use this pattern:
| fst::snd::rest ->
You can match any constant number of first elements using this styling:
| fst::snd::thrd:: ... ::rest ->

i think i got infinite loop for this BST

this code i got is from Alexander Battisti about how to make a tree from a list of data:
let data = [4;3;8;7;10;1;9;6;5;0;2]
type Tree<'a> =
| Node of Tree<'a> * 'a * Tree<'a>
| Leaf
let rec insert tree element =
match element,tree with
| x,Leaf -> Node(Leaf,x,Leaf)
| x,Node(l,y,r) when x <= y -> Node((insert l x),y,r)
| x,Node(l,y,r) when x > y -> Node(l,y,(insert r x))
| _ -> Leaf
let makeTree = List.fold insert Leaf data
then i want to implement this code to my binary search tree code
let rec BinarySearch tree element =
match element,tree with
| x,Leaf -> BinarySearch (Node(Leaf,x,Leaf)) x
| x,Node(l,y,r) when x<=y ->
BinarySearch l y
| x,Node(l,y,r) when x>y ->
BinarySearch r y
| x,Node(l,y,r) when x=y ->
true
| _ -> false
then i use my search code like this:
> BinarySearch makeTree 5;;
and the result is none because it's like i got an infinite looping
can someone help me? if my code is wrong, please help me to correct it, thank you
The solution by Yin is how I would write it too.
Anyway, here is a solution that is closer to your version and (hopefully) explains what went wrong:
let rec BinarySearch tree element =
match element,tree with
| x, Leaf ->
// You originally called 'BinarySearch' here, but that's wrong - if we reach
// the leaf of the tree (on the path from root to leaf) then we know that the
// element is not in the tree so we return false
false
| x, Node(l,y,r) when x<y ->// This needs to be 'x<y', otherwise the clause would be
// matched when 'x=y' and we wouldn't find the element!
BinarySearch l element // Your recursive call was 'BinarySearch l y' but
// that's wrong - you want to search for 'element'
| x, Node(l,y,r) when x>y ->
BinarySearch r element
| x,Node(l,y,r) -> // You can simplify the code by omitting the 'when'
true // clause (because this will only be reached when
// x=y. Then you can omit the last (unreachable) case
let rec BinarySearch tree element =
match tree with
| Leaf -> false
| Node(l, v, r) ->
if v = element then
true
elif v < element then
BinarySearch r element
else
BinarySearch l element
BinarySearch makeTree 5

Resources