terminator terminal

Date Tags xfce4

Despite the fact I can’t stop talking about xfce4, what I’m have been missing lately is the functionality of gnome-terminal… I know I could install gnome terminal and use it, but this will imply a lot of unwanted dependencies and I prefer not go that way. Chatting on #xfce in IRC it was suggested to give a try to terminator https://launchpad.net/terminator/. I’ve used it for a couple of days now and I feel very comfortable with it. It has a lot of configuration options, the possibility to have multiple profiles and to group windows together, it has tabs and all bells and whistles you can ask.

The only thing I didn’t like from the default settings is the red title bar on top… to remove it you need to edit the config file in ~/.config/terminator/config and add show_titlebar = False . This is my conf file :

[global_config]
  geometry_hinting = False
  dbus = True
  focus = mouse
  borderless = True
[keybindings]
[profiles]
  [[default]]
    scrollbar_position = hidden
    show_titlebar = False
  [[presentation]]
    use_system_font = False
    font = Monospace 13
[layouts]
  [[default]]
    [[[child1]]]
      profile = default
      type = Terminal
      parent = window0
    [[[window0]]]
      type = Window
      parent = ""
[plugins]

Something else I’d like to do is to reduce the size and font of the tab on top of the terminal. Since this is a gtk applications, I should hack my gtk theme in order to style the tab, but I don’t know how to do it only for one application. If somebody has an answer I’m all ears.


mancoosi tools in debian testing

Finally the dose3 libraries and tools landed in testing this weekend. We solved a couple of bugs already and it seems nobody complained too loudly. If you used the edos tools in the past you might be interested to check out our new tools in the package dose-extra.

Actually @mancoosi we will be delighted to ear about you experience with our tools and how to make them better and more useful. Please drop me a line !

The next major release of dose will be multi-arch aware and provide performance improvements and other minor features.

If you missed it, and you are now curious, I delivered a talk at fosdem regarding our tools:

  • QA tools for FOSS distributions (FOSDEM 2012) - Pietro Abate (video)

A big thanks to ralf of course for packaging everything !


Xfce terminal and middle mouse button.

just a quicky. If you use the xfce terminal and you like to have more then one tab-terminal open, you might have niticed the the middle button closes it, without confirmation… I just discovered that this annoying feature can be turned off.

Following the freedesktop spec, you can just edit the file .config/Terminal/terminalrc and set the option MiscTabCloseMiddleClick to False.

There are many other settings . The full list is here : http://docs.xfce.org/apps/terminal/advanced


Mancoosi fosdem talks

A small (and probably not complete) list of videos associated to the mancoosi project @ FOSDEM.

  • QA tools for FOSS distributions (FOSDEM 2012) - Pietro Abate (video)

  • Mancoosi tools for the analysis and quality assurance of FOSS (FOSDEM 2011) - Ralf Treinen (video)

  • Improving Rollback in Linux via DSL approach & distributing (FOSDEM 2011) - John Thomson (video)

  • Cross distro dependency resolution reusing solvers among distros (FOSDEM 2010) - Stefano Zacchiroli (video)

  • The MANCOOSI project (FOSDEM 2008) - Ralf Treinen (video)


Finding all the elementary circuits of a directed graph

Date Tags ocaml

Below you can find an implementation in ocaml of the algorithm described in this paper by D. B. Johnson

Finding all the elementary circuits of a directed graph. D. B. Johnson, SIAM Journal on Computing 4, no. 1, 77-84, 1975. http://dx.doi.org/10.1137/0204007

the idea of this algorithm is to enumerate all cycles in a strongly connected component. Next step will be to implement the [http://en.wikipedia.org/wiki/Feedback_arc_set “feedback arc set”] of this connected component so to find the optimal way to break these loops in a way that the connected component can be partitioned in smaller DAGs.

This is only the main function, you can find everything else in the git repo given below. If I’ve time I’ll also give a shot to implement tarjan algorithm and to compare the two… Johnson is supposed to be better complexity wise, but I’m curious to check the difference on my domain specific input.

let find_all_cycles_johnson g =
  if not G.is_directed then
    assert false;

  (*  stack of nodes in current path *)
  let path = Stack.create () in

  (* main function. return (true, acc) if in the last iteration we find a new cycle *)
  let rec circuit t result thisnode startnode component =

   (* add the node the candate cycles and block it *)
    Stack.push thisnode path;
    block t thisnode;

    let (closed,result) =
      G.fold_succ (fun nextnode (c,r) ->
        if G.V.equal nextnode startnode then
         (* this is a cycle ! *)
          (true,(Stack.copy path)::r)
        else begin
          if not(is_bloked t nextnode) then
            circuit t r nextnode startnode component
          else
            (c,r)
        end
      ) component thisnode (false,result)
    in
    if closed then
      (* this node is part of a cycles, but we don't want to exclude it from subsequent
          iterations. Longer cycles can contain smaller cycles *)
      unblock t thisnode
    else
      (* since it is not part of a cycles, then it must be part of a portion of the graph that
          does not contain any elementary circuits *)
      G.iter_succ (fun nextnode ->
        let l = get_notelem t nextnode in
        if List.mem thisnode l then
          Hashtbl.replace t.notelem nextnode (thisnode::l)
      ) component thisnode;

    ignore(Stack.pop path);
    (closed,result)
  in

  (* Johnson's algorithm requires some ordering of the nodes. 
      We use the order induced by the compare function associated to the
      vertex type. See ocamlgraph Pack.Diagraph  *)
  let vertex_set = G.fold_vertex SV.add g SV.empty in

  SV.fold (fun s result ->
    (* Build the subgraph induced by s and following nodes in the ordering *)
    let subset = SV.add s (partition vertex_set s) in
    let subgraph = extract_subgraph g subset in

    if G.nb_edges subgraph > 0 then begin
      (* Find the strongly connected component in the subgraph
       * that contains the least node according to the ordering *)
      let scc = G.Components.scc_list subgraph in
      let minnode = SV.min_elt subset in
      let mincomp = List.find (fun l -> List.mem minnode l) scc in

      (* smallest node in the component according to the ordering *)
      let startnode = minnode in
      let component = extract_subgraph subgraph (to_set mincomp) in

      (* init the block table for this component *)
      let t = init_block component in

      snd(circuit t result startnode startnode component);
    end else
      result
  ) vertex_set []
;;

You can get the code here : git clone http://mancoosi.org/~abate/repos/cycles.git . There are two versions of the algorithm. One is a translation in ocaml of the imperative algorithm, the other, presented above, adds a bit of functional flavor …

Update 1

the code repository now contains also two implementations of approximate algorithms the feedback arc set problem

Update 2

Since the number of cycles in a graph can be very large, I’ve added a lazy version of the algorithm using ExtLib enums (but can be easily done without). It would be cool to avoid using a global data structure to keep track of which nodes I’ve already visited like the persistent array of filliatr … the code could be further optimized of course as many operations on lists and set can be avoided with a smarter DS to build the connected component of the subgraph at each iteration … Complete code in the git repo above.

let find_all_cycles_enum g =
  let rec circuit path t thisnode startnode component =                                        
     let rec aux = function                                                                    
       |[] -> Enum.empty ()                                                                    
       |nextnode :: rest -> 
         if G.V.equal nextnode startnode then begin                                            
           let e = aux rest in                                                                 
           unblock t thisnode;
           Enum.push e (List.rev (thisnode::path));                                            
           e 
         end else
           if not(is_bloked t nextnode) then begin
             let e = circuit (thisnode::path) t nextnode startnode component in                
             Enum.append e (aux rest)                                                          
           end else begin                                                                      
             aux rest                                                                          
           end                                                                                 
     in
     block t thisnode;
     let e = aux (G.succ component thisnode) in                                                
     G.iter_succ (fun nextnode ->
       let l = get_notelem t nextnode in                                                       
       if List.mem thisnode l then 
         Hashtbl.replace t.notelem nextnode (thisnode::l)                                      
     ) component thisnode;                                                                     
     e                                                                                         
  in                                                                                           

  let vertex_set = G.fold_vertex SV.add g SV.empty in                                          
  let rec aux = function                                                                       
    |[] -> Enum.empty ()                                                                       
    |s :: rest ->  
      let subset = SV.add s (partition vertex_set s) in                                        
      let subgraph = extract_subgraph g subset in                                              
      (* I need only one... not all scc *)
      (* actually I need only the scc that contains the min *)                                 
      let scc = G.Components.scc_list subgraph in                                              
      let minnode = SV.min_elt subset in
      let mincomp = List.find (fun l -> List.mem minnode l) scc in                             
      let startnode = minnode in
      let component = extract_subgraph subgraph (to_set mincomp) in                            
      let t = init_block component in
      let partial = circuit [] t startnode startnode component in                              
      Enum.append partial (aux rest)                                                           
  in
  aux (SV.elements vertex_set)                                                                 
;;