**ParaSail**, as promised in the EETimes.com article

*ParaSail : Less is More with Multicore.*

*[ see*

*http://www.eetimes.com/design/embedded/4375616/ParaSail--Less-is-more-with-multicore ]*

// Example ParaSail program -- Directed Graph module// Copyright (C) 2011-2012, AdaCore, New York, NY// To be used only for Personal, Academic, or Evaluation Purposes;// Not for Commercial Production Use.// Report errors at http://groups.google.com/group/parasail-programming-languageinterfaceDGraph<ElementisAssignable<>>is// Interface to a Directed-Graph moduletypeNode_IdisnewInteger<1..10**6>;// A unique id for each node in the graphtypeNode_SetisCountable_Set<Node_Id>;// A set of nodesfuncCreate() -> DGraph;// Create an empty graphfuncAdd_Node(varDGraph; Element) -> Node_Id;// Add a node to a graph, and return its node idop"indexing"(refDGraph; Node_Id){Node_Id->inDGraph.All_Nodes()}refElement;// Return a reference to an element of the graphfuncAdd_Edge(varDGraph; From, To : Node_Id){From;inDGraph.All_Nodes(); ToinDGraph.All_Nodes()}// Add an edge in the graphfuncSuccessors(refconstDGraph; Node_Id) ->refconstNode_Set{Node_Id;inDGraph.All_Nodes()}// The set of successors of a given nodefuncPredecessors(refconstDGraph; Node_Id) ->refconstNode_Set{Node_Id;inDGraph.All_Nodes()}// The set of predecessors of a given nodefuncAll_Nodes(DGraph) -> Node_Set;// The set of all nodesfuncRoots(DGraph) -> Node_Set;// The set of all nodes with no predecessorfuncLeaves(DGraph) -> Node_Set;// The set of all nodes with no successorendinterfaceDGraph;classDGraphis// Class defining the Directed-Graph moduleinterfaceNode<>is// Local definition of Node structurevarElem : Element;varSuccs : Node_Set;varPreds : Node_Set;endinterfaceNode;varG : Vector<Node>;// The vector of nodes, indexed by Node_IdconstDebug : Boolean := #false;funcBoundary_Set(DGraph; Nodes : Countable_Range<Node_Id>; Want_Roots : Boolean) -> Node_Setis// Recursive helper for exported Roots and Leaves functionsifDebugthenPrintln("Boundary_Set for " | Nodes.First | ".." | Nodes.Last);endif;constLen := Length(Nodes);caseLenof[0] =>return[]; [1] =>ifWant_Roots? Is_Empty(Predecessors(DGraph, Nodes.First)): Is_Empty(Successors(DGraph, Nodes.First))then// This is on the desired boundaryreturn[Nodes.First];else// This is not on the desired boundaryreturn[];endif; [..] =>// Divide and conquerconstHalf_Way := Nodes.First + Len / 2;returnBoundary_Set(DGraph, Nodes.First ..< Half_Way, Want_Roots) | Boundary_Set(DGraph, Half_Way .. Nodes.Last, Want_Roots);endcase;endfuncBoundary_Set;exportsfuncCreate() -> DGraphis// Create an empty graphreturn(G => []);endfuncCreate;funcAdd_Node(varDGraph; Element) -> Node_Idis// Add a node to a graph, and return its node idDGraph.G |= (Elem => Element, Succs => [], Preds => []);returnLength(DGraph.G);endfuncAdd_Node;op"indexing"(refDGraph; Node_Id) ->refElementis// Return a reference to an element of the graphreturnDGraph.G[ [[Node_Id]] ].Elem;endop"indexing";funcAdd_Edge(varDGraph; From, To : Node_Id)is// Add an edge in the graphDGraph.G[ [[From]] ].Succs |= To; DGraph.G[ [[To]] ].Preds |= From;endfuncAdd_Edge;funcSuccessors(refconstDGraph; Node_Id) ->refconstNode_Setis// The set of successors of a given nodereturnDGraph.G[ [[Node_Id]] ].Succs;endfuncSuccessors;funcPredecessors(refconstDGraph; Node_Id) ->refconstNode_Setis// The set of predecessors of a given nodereturnDGraph.G[ [[Node_Id]] ].Preds;endfuncPredecessors;funcAll_Nodes(DGraph) -> Node_Setis// The set of all nodesreturn1 .. Length(DGraph.G);endfuncAll_Nodes;funcRoots(DGraph) -> Node_Setis// The set of all nodes with no predecessorreturnBoundary_Set (DGraph, 1 .. Length(DGraph.G), Want_Roots => #true);endfuncRoots;funcLeaves(DGraph) -> Node_Setis// The set of all nodes with no successorreturnBoundary_Set (DGraph, 1 .. Length(DGraph.G), Want_Roots => #false);endfuncLeaves;endclassDGraph;funcTest_Graph()is// A test program that manipulates a directed graph of univ-enumstypeDGEisDGraph<Univ_Enumeration>;funcBuild_Graph() -> New_G : DGEis// A function that builds up a graph of Univ_EnumerationsNew_G := Create();// Create the empty graphconstHello := New_G.Add_Node(#hello);constThere := New_G.Add_Node(#there);constStranger := New_G.Add_Node(#stranger); New_G.Add_Edge(Hello, There); New_G.Add_Edge(There, Stranger); New_G.Add_Edge(Hello, Stranger);endfuncBuild_Graph;funcPrint_Nodes(DGE; Nodes : DGE::Node_Set; Indent : Univ_String := " ")// Display the elements of a node set, with the given indentisforSinNodesloopPrintln(Indent | DGE[S]);endloop;endfuncPrint_Nodes;funcPrint_Succs(DGE; N : DGE::Node_Id)is// Display the successors of a given nodePrintln("Successors of " | DGE[N] | " (node " | N | ")"); Print_Nodes(DGE, DGE.Successors(N));endfuncPrint_Succs;// Now build the graph and display some info on the graphvarGr : DGE := Build_Graph(); Println("Roots of graph:"); Gr.Print_Nodes(Gr.Roots()); Println("Leaves of graph:"); Gr.Print_Nodes(Gr.Leaves()); Println("All nodes, and their successors:");forNinAll_Nodes(Gr)forwardloopGr.Print_Succs(N);endloop;endfuncTest_Graph;

## No comments:

## Post a Comment