Detachable element in ensure, Eiffel - hashtable

How can I ensure that an element is in my HASH_TABLE, if it is detachable?
Current = HASH_TABLE[ARRAYED_SET[G], G]
add_edge (src: G; dst: G)
do
if attached Current.at(src) as edges then
edges.put(dst)
end
ensure
in: Current.at (src).has (dst)
end

Have you try that:
add_edge (src: G; dst: G)
do
if attached Current.at(src) as edges then
edges.put(dst)
end
ensure
in: attached Current.at (src) as edges implies edges.has (dst)
end

Related

How to deal with a list of 'Maybe [values]' in Haskell?

I tryied to adapt some exercises of the excelent book "Land of Lisp" of Conrad Barski in order to learn Haskell. The idea is to make a simple text game engine.
Concretely I tried :
type Clau = String
type Descripcio = String
type Valors = [String]
-- NOTE : Ideas of types http://learnyouahaskell.com/making-our-own-types-and-typeclasses
data Lloc = Lloc String String String deriving (Show)
llocSituacio :: Lloc -> String
llocSituacio (Lloc situacio _ _ ) = situacio
llocDireccio :: Lloc -> String
llocDireccio (Lloc _ direccio _) = direccio
llocPas :: Lloc -> String
llocPas ( Lloc _ _ pas) = pas
nodes :: [(Clau,Descripcio)]
nodes = [("living-room","you are in the living-room. a wizard is snoring loudly on the couch.")
,("garden","you are in a beautiful garden. there is a well in front of you.")
, ("attic", "you are in the attic. there is a giant welding torch in the corner.")]
edges :: [([Char], [Lloc])]
edges = [ ("living-room", [(Lloc "garden" "west" "door"), ( Lloc "attic" "upstairs" "ladder") ])
, ("attic", [(Lloc "living-room" "east" "door")])
, ("garden", [(Lloc "living-room" "east" "door")])]
describePath :: Lloc -> String
describePath e = "There is " ++ llocPas e ++ " going " ++ llocDireccio e ++ " from here."
At first, it seems that works well. For example:
*TextGame> describePath (Lloc "living-room" "east" "door")
"There is door going east from here."
But when I try to apply the function to the list I got this error:
situacio = "garden"
map (describePath) (lookup situacio edges)
<interactive>:2:22: error:
• Couldn't match expected **type ‘[Maybe Lloc]’**
with actual **type ‘Maybe [Lloc]’**
• In the second argument of ‘map’, namely ‘(lookup situacio edges)’
In the expression: map (describePath) (lookup situacio edges)
In an equation for ‘it’:
it = map (describePath) (lookup situacio edges)
The error is clear, but I do not manage to solve it. I want to parse the list of Maybe's values and print the path with the function describePath that works well:
Any ideas? Also, if somebody wants to share alternatives or feel that this code could be more in Haskell style, please feel free to talk about it.
There might be some more advanced library helpers, but I think you should first learn how to handle Maybes in the most basic (and general) way: use pattern matching.
case lookup situacio edges of
Nothing -> [] -- not found, how do you want to handle this case?
Just locs -> map describePath locs
Oftentimes, one wants instead to rewrap the result in another Maybe, e.g.:
case lookup situacio edges of
Nothing -> Nothing -- not found
Just locs -> Just (map describePath locs)
and in such case, we can use a library helper function to shorten the code:
map describePath <$> lookup situacio edges
Thanks a lot chi, it works perfectly. I just made a new function:
describePaths situacio edges = case lookup situacio edges of
Nothing -> []
Just locs -> map describePath locs
.. and works pretty well:
*TextGame> situacio = "living-room"
*TextGame> describePaths situacio edges
["There is door going west from here.","There is ladder going upstairs from here."]
But I see that I do not fully understand the <$> operator. I follow the comments of : What does <$> mean in Haskell?
So I follow the suggestion : https://hoogle.haskell.org/?hoogle=%3C$%3E
This is call a Functor:
(<$>) :: Functor f => (a->b) -> f a -> f b
That actually is exactly the same as fmap:
fmap :: Functor f => (a -> b) -> f a -> f b
It seems that are the same:
*TextGame> (*2) <$> [1..3]
[2,4,6]
*TextGame> fmap (*2) [1..3]
[2,4,6]
But, actually they are different:
*TextGame> map describePath <$> lookup situacio edges
Just ["There is door going west from here.","There is ladder going upstairs from here."]
*TextGame> fmap (describePath) (lookup situacio edges)
<interactive>:30:22: error:
• Couldn't match type ‘[Lloc]’ with ‘Lloc’
Expected type: Maybe Lloc
Actual type: Maybe [Lloc]
....
Could someone put a little more light on it ? I do not fully understand why 'fmap (describePath) (lookup situacio edges)' do not work?
(I am playing with Maybe's and Just's but ...)

Write an algorithm to find a path that traverses all edges of directed graph G exactly once

...You may visit nodes multiple times, if necessary. Show the run time complexity of your algorithm. This graph is not necessarily strongly connected, but starting from a node there should exist such a path.
My approach so far was to repeatedly DFS at unvisited nodes to find the node with the highest post number as this will be part of the source node in a meta graph.
Then repeatedly DFS on the reverse graph to find the sink node meta graph.
Then run the Eulerian path algorithm until we exhaust all of the edges, backtracking if a path leads to a dead end.
I cant figure out how to proceed from here.
Hi, I came up with this. Can someone please verify it?
function edge_dfs(vertex u, graph, path, num_edges) {
if num_edges == 0 { // Found a path.
return true;
}
for all neighbors n of u {
if exists((u, n)) == true {
num_edges--
exists((u, n)) = false
path.append((n))
if edge_dfs(n, g, p, num_edges) == true:
return true
else:
num_edges++ // Backtrack if this edge was unsuccessful.
exists((u, n)) = true
path.pop()
}
}
return false // No neighbors or No valid paths from this vertex.
}
repeatedly do dfs and fine a source component
node: call it s.
path = array{s}
exists((u, v)) = true for all edges (u, v) in graph
num_edges = number of edges in graph
if edge_dfs(s, graph, path, num_edges) == true:
Path is the elements in array 'path' in order.
else:
Such a path does not exist.
And this is O(|E| + |V|) as it is just a DFS of all of the edges.

What is the connection between Refs and Broadcasting in Julia

For two objects A and B we could previously get the vector [A*A, A*B] with the code A .* [A, B]. From the deprecation warnings in Julia 0.7, it seems that the new way to do this is to use a reference of the first A. So it becomes Ref(A) .* [A,B].
It doesn't seem that there is a strong link between references and broadcasting operations. What is the link here and why is using a Reference preferred (by the deprecation warnings at least)?
Minimal Working Example
import Base.*
struct example
num::Int
end
function *(lhs::example, rhs::example)
return example(lhs.num * rhs.num)
end
A = example(2)
B = example(4)
# Previously this could be done as follows.
A .* [A, B]
# Now we need to use Refs
Ref(A) .* [A, B]
I will here refer to the main case of Ref, that is when you pass it one argument (there are also other subtypes of Ref but they are not relevant for us here).
Writing Ref(x) creates a mutable wrapper around object x. The wrapper is a very simple RefValue type defined in the following way:
mutable struct RefValue{T} <: Ref{T}
x::T
RefValue{T}() where {T} = new()
RefValue{T}(x) where {T} = new(x)
end
Now why it is useful, because Ref has defined the following utility functions:
eltype(x::Type{<:Ref{T}}) where {T} = #isdefined(T) ? T : Any
size(x::Ref) = ()
axes(x::Ref) = ()
length(x::Ref) = 1
ndims(x::Ref) = 0
ndims(::Type{<:Ref}) = 0
iterate(r::Ref) = (r[], nothing)
iterate(r::Ref, s) = nothing
IteratorSize(::Type{<:Ref}) = HasShape{0}()
which means that it can be used in broadcasting as only objects that have axes defined and support indexing can be used with broadcast.
Fortunately it is easy to avoid writing Ref(A) all the time.
Just define:
Base.broadcastable(e::example) = Ref(e)
and the machinery of broadcast will work again as Base.broadcastable is called on each argument of broadcast.
More details about customizing broadcasting can be found here https://docs.julialang.org/en/v1/manual/interfaces/#man-interfaces-broadcasting.

One processing conduit, 2 IO sources of the same type

In my GHC Haskell application utilizing stm, network-conduit and conduit, I have a strand for each socket which is forked automatically using runTCPServer. Strands can communicate with other strands through the use of a broadcasting TChan.
This showcases how I would like to set up the conduit "chain":
So, what we have here is two sources (each bound to helper conduits which) which produce a Packet object which encoder will accept and turn into ByteString, then send out the socket. I've had a great amount of difficulty with the efficient (performance is a concern) fusing of the two inputs.
I would appreciate if somebody could point me in the right direction.
Since it would be rude of me to post this question without making an attempt, I'll put what I've previously tried here;
I've written/cherrypicked a function which (blocking) produces a Source from a TMChan (closeable channel);
-- | Takes a generic type of STM chan and, given read and close functionality,
-- returns a conduit 'Source' which consumes the elements of the channel.
chanSource
:: (MonadIO m, MonadSTM m)
=> a -- ^ The channel
-> (a -> STM (Maybe b)) -- ^ The read function
-> (a -> STM ()) -- ^ The close/finalizer function
-> Source m b
chanSource ch readCh closeCh = ConduitM pull
where close = liftSTM $ closeCh ch
pull = PipeM $ liftSTM $ readCh ch >>= translate
translate = return . maybe (Done ()) (HaveOutput pull close)
Likewise, a function to transform a Chan into a sink;
-- | Takes a stream and, given write and close functionality, returns a sink
-- which wil consume elements and broadcast them into the channel
chanSink
:: (MonadIO m, MonadSTM m)
=> a -- ^ The channel
-> (a -> b -> STM()) -- ^ The write function
-> (a -> STM()) -- ^ The close/finalizer function
-> Sink b m ()
chanSink ch writeCh closeCh = ConduitM sink
where close = const . liftSTM $ closeCh ch
sink = NeedInput push close
write = liftSTM . writeCh ch
push x = PipeM $ write x >> return sink
Then mergeSources is straightforward; fork 2 threads (which I really don't want to do, but what the heck) which can put their new items into the one list which I then produce a source of;
-- | Merges a list of 'Source' objects, sinking them into a 'TMChan' and returns
-- a source which consumes the elements of the channel.
mergeSources
:: (MonadIO m, MonadBaseControl IO m, MonadSTM m)
=> [Source (ResourceT m) a] -- ^ The list of sources
-> ResourceT m (Source (ResourceT m) a)
mergeSources sx = liftSTM newTMChan >>= liftA2 (>>) (fsrc sx) retn
where push c s = s $$ chanSink c writeTMChan closeTMChan
fsrc x c = mapM_ (\s -> resourceForkIO $ push c s) x
retn c = return $ chanSource c readTMChan closeTMChan
While I was successful in making these functions typecheck, I was unsuccessful in getting any utilization of these functions to typecheck;
-- | Helper which represents a conduit chain for each client connection
serverApp :: Application SessionIO
serverApp appdata = do
use ssBroadcast >>= liftIO . atomically . dupTMChan >>= assign ssBroadcast
-- appSource appdata $$ decoder $= protocol =$= encoder =$ appSink appdata
mergsrc $$ protocol $= encoder =$ appSink appdata
where chansrc = chanSource (use ssBroadcast) readTMChan closeTMChan
mergsrc = mergeSources [appSource appdata $= decoder, chansrc]
-- | Structure which holds mutable information for clients
data SessionState = SessionState
{ _ssBroadcast :: TMChan Packet -- ^ Outbound packet broadcast channel
}
makeLenses ''SessionState
-- | A transformer encompassing both SessionReader and SessionState
type Session m = ReaderT SessionReader (StateT SessionState m)
-- | Macro providing Session applied to an IO monad
type SessionIO = Session IO
I see this method as being flawed anyhow -- there are many intermediate lists and conversions. This can not be good for performance. Seeking guidance.
PS. From what I can understand, this is not a duplicate of; Fusing conduits with multiple inputs , as in my situation both sources produce the same type and I don't care from which source the Packet object is produced, as long as I'm not waiting on one while another has objects ready to be consumed.
PPS. I apologize for the usage (and therefore requirement of knowledge) of Lens in example code.
I don't know if it's any help, but I tried to implement Iain's suggestion and made a variant of mergeSources' that stops as soon as any of the channels does:
mergeSources' :: (MonadIO m, MonadBaseControl IO m)
=> [Source (ResourceT m) a] -- ^ The sources to merge.
-> Int -- ^ The bound of the intermediate channel.
-> ResourceT m (Source (ResourceT m) a)
mergeSources' sx bound = do
c <- liftSTM $ newTBMChan bound
mapM_ (\s -> resourceForkIO $
s $$ chanSink c writeTBMChan closeTBMChan) sx
return $ sourceTBMChan c
(This simple addition is available here).
Some comments to your version of mergeSources (take them with a grain of salt, it can be I didn't understand something well):
Using ...TMChan instead of ...TBMChan seems dangerous. If the writers are faster than the reader, your heap will blow. Looking at your diagram it seems that this can easily happen, if your TCP peer doesn't read data fast enough. So I'd definitely use ...TBMChan with perhaps large but limited bound.
You don't need the MonadSTM m constraint. All STM stuff is wrapped into IO with
liftSTM = liftIO . atomically
Maybe this will help you slightly when using mergeSources' in serverApp.
Just a cosmetic issue, I found
liftSTM newTMChan >>= liftA2 (>>) (fsrc sx) retn
very hard to read due to its use of liftA2 on the (->) r monad. I'd say
do
c <- liftSTM newTMChan
fsrc sx c
retn c
would be longer, but much easier to read.
Could you perhaps create a self-contained project where it would be possible to play with serverApp?

Force node to be directly beneath another node

I have a graph that's laid out from left-to-right. There are some elements of this graph, however, that I want to have positioned relative to another node. For example, if I have this graph:
digraph "Test" {
rankdir = "LR"
A -> B
B -> C
D -> B
note -> B
note [ shape="house" ]
};
It renders like this:
However, I'd like the "note" node to always be positioned directly underneath the node to which it's pointing, like this (manually created) graph:
I've tried experimenting with a subgraph with a different rankdir and fiddling with rank and constraint attributes, but have been unsuccessful in getting this to work, as I've only been playing around with DOT for a couple of days.
You can enumerate the nodes before defining the edges, and then constrain node B to the same rank as node note by putting them in a subgraph:
digraph "Test" {
rankdir = "LR"
A;D;
{rank=same; note; B;}
C;
A -> B
B -> C
D -> B
B -> note [dir=back]
note [ shape="house" ]
};
Please note that in order to have node note below node B, I had to reverse the edge direction and add dir=back to have the arrow drawn correctly.
A general technique for moving nodes around is to create invisible edges. In your case, you could create an edge from A to note, mark it invisible, and then mark the edge from note to B as non-constraining:
A -> note [style="invis"];
note -> B [constraint=false];

Resources