Add command-line interface ./match (adapted from POPL 2012 version).
authorMatt McCutchen <matt@mattmccutchen.net>
Sat, 27 Aug 2011 16:02:35 +0000 (12:02 -0400)
committerMatt McCutchen <matt@mattmccutchen.net>
Sat, 27 Aug 2011 16:02:35 +0000 (12:02 -0400)
program/.gitignore
program/ArrayStuff.hs
program/Main.hs [new file with mode: 0644]
program/Makefile
program/example.in [new file with mode: 0644]

index b3652c0..7c789e1 100644 (file)
@@ -1,3 +1,4 @@
 /*.hi
 /*.o
 /graph-*.ps
+/match
index ceb7516..df0a969 100644 (file)
@@ -15,6 +15,9 @@ array2DtoListOfLists arr =
        let ((xlo, ylo), (xhi, yhi)) = bounds arr in
        map (\x -> map (\y -> arr ! (x, y)) $ range (ylo, yhi)) $ range (xlo, xhi)
 
+listOfListsToArray2D ll =
+       listArray ((0, 0), (length ll - 1, length (head ll) - 1)) $ concat ll
+
 -- Use instead of amap when the array implementation needs to change.
 -- E.g., mapping an unboxed array to an array whose elements must be boxed.
 amap2 f arr = funcArray (bounds arr) (\i -> f (arr ! i))
diff --git a/program/Main.hs b/program/Main.hs
new file mode 100644 (file)
index 0000000..4487508
--- /dev/null
@@ -0,0 +1,40 @@
+import PMInstance
+import PMDefaults
+import ProposalMatcher
+import System.IO
+import Data.Array.IArray
+import Data.Array.Unboxed
+import ArrayStuff
+import Text.CSV
+
+-- Command-line interface with simple tab-separated input/output formats.
+-- ./match <example.in
+
+-- pretty silly but it does the job
+swapTabCommaIn s = map (\c -> if c == '\t' then ',' else if c == ',' then '\t' else c) s
+removeQuotes s = filter (\c -> not (c == '"')) s
+
+-- Some versions of Text.CSV do not use or accept a trailing newline; compensate for that.
+removeTrailingNewline s = if not (null s) && last s == '\n' then init s else s
+addTrailingNewline s = if not (null s) && last s /= '\n' then s ++ ['\n'] else s
+
+parseTSV fname str = case parseCSV fname (swapTabCommaIn $ removeTrailingNewline str) of
+       Left pe -> Left pe
+       Right ll -> Right $ map (map swapTabCommaIn) ll
+printTSV ll = addTrailingNewline $ removeQuotes $ swapTabCommaIn $ printCSV $ map (map swapTabCommaIn) ll
+
+main = do
+       incsv <- hGetContents stdin
+       -- handle errors another day, or let the platform do it
+       let Right inll = parseTSV "standard input" incsv
+       let loadList = head inll
+       let numRvrs = length loadList
+       let loadA = listArray (0, numRvrs-1) (map read loadList)
+       let numProps = length (tail inll)
+       -- explicit type on the next line appears to be necessary
+       let pxarr = listOfListsToArray2D (tail inll) :: Array (Int,Int) String
+       -- careful, we end up transposing the array in here
+       let prefA = funcArray ((0,0), (numRvrs-1,numProps-1)) (\(i,j) -> read (pxarr ! (j, i)))
+       let theInst = PMInstance numRvrs numProps loadA prefA
+       let PMatching theMatching = doMatching pmDefaults theInst
+       hPutStr stdout $ printTSV $ map (\(i, j) -> map show [i, j]) theMatching
index 78eb667..d72db83 100644 (file)
@@ -2,8 +2,12 @@
 # -cpp: Handle GHC 6.6.1 compatibility checks.
 # -fglasgow-exts: Handle rank-2 type of RandomizedMonad, among other things.
 all:
-       ghc -cpp -fglasgow-exts --make -c *.hs
+#      ghc -cpp -fglasgow-exts --make -c *.hs
+       ghc -cpp -fglasgow-exts --make *.hs -o match
 all-optimized:
-       ghc -cpp -fglasgow-exts --make -O -hisuf O.hi -osuf O.o -c *.hs
+#      ghc -cpp -fglasgow-exts --make -O -hisuf O.hi -osuf O.o -c *.hs
+       ghc -cpp -fglasgow-exts --make -O -hisuf O.hi -osuf O.o *.hs -o match.O
 clean:
-       rm -f *.hi *.o
+       rm -f *.hi *.o match
+
+# Necessary libraries (on Fedora): ghc-fgl, ghc-csv.  Others I miss?
diff --git a/program/example.in b/program/example.in
new file mode 100644 (file)
index 0000000..167622a
--- /dev/null
@@ -0,0 +1,4 @@
+1      1       1       1       1
+15     10      15      40      20
+30     7       10      15      15
+15     25      20      20      15