Skip to content

Commit

Permalink
- Added a basic priority queue
Browse files Browse the repository at this point in the history
git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@10671 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
sjoelund committed Dec 7, 2011
1 parent ac13eb0 commit 6c5d843
Show file tree
Hide file tree
Showing 3 changed files with 259 additions and 3 deletions.
9 changes: 6 additions & 3 deletions Compiler/BackEnd/SimCode.mo
Expand Up @@ -64,6 +64,7 @@ public import HashTableExpToIndex;
public import HashTableStringToPath;
public import Inline;
public import Interactive;
public import PriorityQueue;
public import SCode;
public import Tpl;
public import Types;
Expand Down Expand Up @@ -12301,6 +12302,8 @@ algorithm
then l::{};
case (lst,i)
equation
/* TODO: Use priorityqueue for greedy algorithm here */
_ = PriorityQueue.empty;
n = listLength(lst);
n = intDiv(n,i) + Util.if_(intMod(n,i)>0,1,0);
then makeEqualLengthLists2(lst,n,n,{},{});
Expand Down Expand Up @@ -12545,12 +12548,12 @@ end setSimCodeLiterals;

protected function eqSystemWCET
"Calculate the estimated worst-case execution time of the system for partitioning"
input list<SimEqSystem> eqs;
output tuple<list<SimEqSystem>,Integer> tpl;
input SimEqSystem eqs;
output tuple<SimEqSystem,Integer> tpl;
protected
Integer i;
algorithm
(_,i) := traverseExpsEqSystems(eqs, Expression.complexityTraverse, 0, {});
(_,i) := traverseExpsEqSystems({eqs}, Expression.complexityTraverse, 0, {});
tpl := (eqs,i);
end eqSystemWCET;

Expand Down
1 change: 1 addition & 0 deletions Compiler/Makefile.common
Expand Up @@ -164,6 +164,7 @@ IOStream.mo \
List.mo \
Util.mo \
Pool.mo \
PriorityQueue.mo \
Name.mo \
Scope.mo \
Relation.mo \
Expand Down
252 changes: 252 additions & 0 deletions Compiler/Util/PriorityQueue.mo
@@ -0,0 +1,252 @@
/*
* This file is part of OpenModelica.
*
* Copyright (c) 1998-CurrentYear, Linköping University,
* Department of Computer and Information Science,
* SE-58183 Linköping, Sweden.
*
* All rights reserved.
*
* THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3
* AND THIS OSMC PUBLIC LICENSE (OSMC-PL).
* ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES RECIPIENT'S
* ACCEPTANCE OF THE OSMC PUBLIC LICENSE.
*
* The OpenModelica software and the Open Source Modelica
* Consortium (OSMC) Public License (OSMC-PL) are obtained
* from Linköping University, either from the above address,
* from the URLs: http://www.ida.liu.se/projects/OpenModelica or
* http://www.openmodelica.org, and in the OpenModelica distribution.
* GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html.
*
* This program is distributed WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH
* IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS
* OF OSMC-PL.
*
* See the full OSMC Public License conditions for more details.
*
*/

encapsulated package PriorityQueue
" file: PriorityQueue.mo
package: PriorityQueue
description: ADT PriorityQueue

RCS: $Id$

This data-structure is based on Brodal and Okasaki (1996)
http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.48.973

It uses a binomial heap with reasonable efficiency. It could
be made faster like in the paper by adding some additional information
to the data-type.

Note that we can make this a very general module if we have a bootstrapped
compiler. RML takes all the joy out of writing code.

TODO: Improve the efficiency as in the paper:
TODO: Implement getMin() in O(1) time
TODO: Implement insert() in O(1) time
TODO: Implement meld() in O(1) time
"

import List;
import Util;

/* protected */
/* TODO: Hide when RML is killed */

/* This specific version... */
replaceable type Priority = Integer;
replaceable type Data = list<Integer>;

/* Replaceable types */

replaceable function compareElement
input Element el1;
input Element el2;
output Boolean b;
protected
Priority p1,p2;
algorithm
(p1,_) := el1;
(p2,_) := el2;
b := p1 <= p2;
end compareElement;

public

replaceable type Element = tuple<Priority,Data>;
type T = list<Tree>;

constant T empty = {};

/*
function isEmpty = listEmpty;
*/
function isEmpty
input T ts;
output Boolean isEmpty;
algorithm
isEmpty := List.isEmpty(ts);
end isEmpty;

function insert
input Element elt;
input T ts;
output T ots;
algorithm
ots := ins(NODE(elt,0,{}),ts);
end insert;

function meld
input T ts1;
input T ts2;
output T ts;
algorithm
ts := match (ts1,ts2)
local
Tree t1,t2;
case (ts1,{}) then ts1;
case ({},ts2) then ts2;
case (t1::ts1,t2::ts2) then meld2(rank(t1) < rank(t2),rank(t2) < rank(t1),t1,ts1,t2,ts2);
end match;
end meld;

function meld2
input Boolean b1;
input Boolean b2;
input Tree t1;
input T ts1;
input Tree t2;
input T ts2;
output T ts;
algorithm
ts := match (b1,b2,t1,ts1,t2,ts2)
case (true,_,t1,ts1,t2,ts2)
equation
ts = meld(ts1,t2::ts2);
then t1::ts;
case (_,true,t1,ts1,t2,ts2)
equation
ts = meld(t1::ts1,ts2);
then t2::ts;
else ins(link(t1,t2), meld(ts1,ts2));
end match;
end meld2;

function findMin
input T ts;
output Element elt;
algorithm
elt := match ts
local
Tree t;
Element x,y;
case {t} then root(t);
case t::ts
equation
x = root(t);
y = findMin(ts);
then Util.if_(compareElement(x,y),x,y);
end match;
end findMin;

function deleteMin
input T ts;
output T ots;
protected
T ts1,ts2;
algorithm
(NODE(trees=ts1),ts2) := getMin(ts);
ots := meld(listReverse(ts1),ts2);
end deleteMin;

/* TODO: Hide from user when we remove RML... */

type Rank = Integer;

uniontype Tree
record NODE
Element elt;
Rank rank;
T trees;
end NODE;
end Tree;

protected

function root
input Tree tree;
output Element elt;
algorithm
NODE(elt=elt) := tree;
end root;

function rank
input Tree tree;
output Rank rank;
algorithm
NODE(rank=rank) := tree;
end rank;

function link
input Tree t1;
input Tree t2;
output Tree t;
algorithm
t := match (t1,t2)
local
Element e1,e2;
Rank r1,r2;
T ts1,ts2;
T ots1,ots2;
case (NODE(e1,r1,ts1),NODE(e2,r2,ts2))
equation
r1 = r1+1;
r2 = r2+1;
ts1 = t2::ts1;
ts2 = t1::ts2;
then Util.if_(compareElement(root(t1),root(t2)),
NODE(e1,r1,ts1),
NODE(e2,r2,ts2));
end match;
end link;

function ins
input Tree t;
input T ts;
output T ots;
algorithm
ots := match (t,ts)
local
Tree t1,t2;
case (t,{}) then {t};
case (t1,t2::ts) then
Util.if_(rank(t1) < rank(t2),t1::t2::ts,ins(link(t1,t2),ts));
end match;
end ins;

function getMin
input T ts;
output Tree min;
output T ots;
algorithm
(min,ots) := match ts
local
Tree t,t1,t2;
T ts1,ts2;
Element x,y;
Boolean b;
case {t} then (t,{});
case t1::ts1
equation
(t2,ts2) = getMin(ts1);
b = compareElement(root(t1),root(t2));
then (Util.if_(b,t1,t2), Util.if_(b,ts1,t1::ts2));
end match;
end getMin;

end PriorityQueue;

0 comments on commit 6c5d843

Please sign in to comment.