I have a graph like this:

As part of a homework assignment I want to find the triangle (1->2->5). I have no idea how to find this.
In my case, I defined my graph:
type Graph = (Int, Int -> Int -> Bool)
g 2 3 = True
g 3 2 = True
g 1 2 = True
g 2 1 = True
g 1 1 = True
g n m = False
Answer to 2 comment.
I did this and it works, I think.
triangles :: [(Int, Int, Int)]
triangles = [(x, y, z) | x <- [1..3], y <- [1..x], z <- [1..y], isTriangle (x, y, z)]
isTriangle :: (Int, Int, Int) -> Bool
isTriangle (x, y, z) = g x y && g y z && g x z
I removed (_,g) and (n,g) (I dont understand why we need them 🙂
I call trinagles and it return (1,1,1) (2,1,1) (in my case). Is it right?
I guess the first Int of Graph is a bound for your nodes (like, 6 if the nodes are in
[1..6]).Therefore, you would like a function that returns the triangles of a graph, so the type might be:
Now, a triangle exists whenever, for 3 nodes, say
xyandz, all the combinations returnTruethroughg.So, you might want to consider generating all these combinations (possibly avoiding the ones that are equivalent via re-ordering), and filter out only those that validate the criterion:
For this, you could use a list comprehension, or the function filter which has type
(a -> Bool) -> [a] -> [a]Answer to your first comment:
First, you would need to implement the
trianglesfunction, which is the reason of the error. But, as you have done intest, you could simply generate these triangles on the fly.Now, you wrote:
Two things about this:
isTrianglefor what you wrote, but it is incorrect, sinceisTriangleexpects a graph as its first parameterSecond, you are going to obtain a lot of duplicates, and if you want, you can prevent this by not generating them in the first place:
Alternatively, you can dismiss the
filterfunction by providing a guard in the list comprehension syntax, as this:Now, I’ll let you go on with the details. You will want to make this a function that takes a graph, and to replace this
3by the number of nodes in the graph, and yourGraph by said graph.Since you chose to use list comprehension, forget about the generating function that I wrote about earlier, its purpose was just to generate input for
filter, but with the list comprehension approach you won’t necessarily need it.Answer to your second comment:
You want to write a function:
The
...are to be replaced with the correct things, from earlier (ranges for x, y and z, as well as the predicate isTriangle).Alternatively, you can cut this in two functions:
This way, you could potentially reuse
allTrianglesfor something else. If you don’t feel the need, you can stay with the one-shot big comprehensiontriangles, since it’s a homework you probably won’t build up on it.I try not to fill all the
...so that you can do it yourself and hopefully understand 🙂Correcting your solution:
First, my mistake on the ranges, it should be
x <- [1..n], y <- [x+1..n], z <- [y+1..n]wherendenotes the number of nodes in your graph. This way, you only capture triples wherex < y < z, which ensures that you only see one occurence of each set of three points.Second, the reason why I put the graph as a parameter to the functions is that you might want to reuse the same function for another graph. By hardcoding
gand6in your functions, you make them really specific to the particular graph you described, but if you want to computetriangleson a certain number of graphs, you do not want to write one function per graph!