diff --git a/CombinatorialOptimisation/SAT.hi b/CombinatorialOptimisation/SAT.hi
new file mode 100644
Binary files /dev/null and b/CombinatorialOptimisation/SAT.hi differ
diff --git a/CombinatorialOptimisation/SAT.o b/CombinatorialOptimisation/SAT.o
new file mode 100644
Binary files /dev/null and b/CombinatorialOptimisation/SAT.o differ
diff --git a/CombinatorialOptimisation/TSP.hi b/CombinatorialOptimisation/TSP.hi
new file mode 100644
Binary files /dev/null and b/CombinatorialOptimisation/TSP.hi differ
diff --git a/CombinatorialOptimisation/TSP.hs b/CombinatorialOptimisation/TSP.hs
--- a/CombinatorialOptimisation/TSP.hs
+++ b/CombinatorialOptimisation/TSP.hs
@@ -209,7 +209,7 @@
         matrix = M.fromList $ zip cityCoords (randomRs distanceLimits g)
         -- p' = (\x y->M.findWithDefault 0 (x,y) matrix)
         explicit = A.listArray (0,numCities*numCities-1)  [M.findWithDefault 0 (a,b) matrix | a<-cities,b<-cities]
-    in TSPProblem 0 M.empty (\x y->explicit A.! (x * numCities + y)) numCities M.empty M.empty
+    in TSPProblem 0 M.empty (\x y->explicit A.! (y * numCities + x)) numCities M.empty M.empty
     -- TSPProblem 0 M.empty p numCities M.empty M.empty
 
 {- |  Construct a TSPProblem instance for a Symmetric TSP. That is, the distance
@@ -229,7 +229,7 @@
         matrix = foldl f M.empty (zip cityCoords (randomRs distanceLimits g))
         explicit = A.listArray (0,numCities*numCities-1)  [M.findWithDefault 0 (a,b) matrix | a<-cities,b<-cities]
         triangular = A.listArray (0,sum [0..numCities])  [M.findWithDefault 0 (a,b) matrix | a<-cities,b<-[0..a]]
-        p = if storageType == ExplicitMatrix then (\x y->explicit A.! (x * numCities + y))
+        p = if storageType == ExplicitMatrix then (\x y->explicit A.! (y * numCities + x))
                                              else (\x y->let x' = min x y; y' = max x y in triangular A.! (div (y'*y'+y') 2 + x'))
     in TSPProblem 0 M.empty p numCities M.empty M.empty
 
@@ -250,7 +250,7 @@
         triangular = A.listArray (0,sum [0..numCities])  [euclidianDistance (posArr A.! a) (posArr A.! b) | a<-cities,b<-[0..a]]
 
         p = case storageType of
-              ExplicitMatrix -> \x y->explicit A.! (x * numCities + y)
+              ExplicitMatrix -> \x y->explicit A.! (y * numCities + x)
               TriangularMatrix -> (\x y->let x' = min x y; y' = max x y in triangular A.! (div (y'*y'+y') 2 + x'))
               Recomputation -> \a b->if a == b then 0 else euclidianDistance (posArr A.! a) (posArr A.! b)
     in TSPProblem 0 M.empty p numCities M.empty M.empty
diff --git a/CombinatorialOptimisation/TSP.hs~ b/CombinatorialOptimisation/TSP.hs~
--- a/CombinatorialOptimisation/TSP.hs~
+++ b/CombinatorialOptimisation/TSP.hs~
@@ -8,7 +8,7 @@
 -- Stability   :  provisional
 -- Portability :  portable
 -- 
--- A library for the representation and manipulation of traveling salesperson
+-- A library for the representation and manipulation of travelling salesperson
 -- problems.
 -- The approach taken is the creation of a complex data structure called 
 -- TSPProblem which contains both the problem, the current solution and 
@@ -18,12 +18,12 @@
 -- sequence. This is to facilitate changing the route quickly, and
 -- avoid searching for data in lists.
 --
--- The data structure also contains two additonal fields, the 
+-- The data structure also contains two additional fields, the 
 -- @routeElementToIndex@ and @indexToRouteElement@ components.
 -- These exist to allow manipulation either by the vertex number
 -- or the position in the current solution. 
 -- Solutions are hamiltonian cycles.
--- For ease of reasoning it is recomended that users do not 
+-- For ease of reasoning it is recommended that users do not 
 -- attempt to move vertex 0, or index 0, so that solutions
 -- are cycles from 0 to 0. I may change this in the future to 
 -- lock this down a bit. In the meantime, there is no
@@ -100,7 +100,7 @@
       rm = snd . ((M.!) (routeMap t))
       r = 0:(takeWhile (\x->x/=0) $ iterate rm (rm 0))++[0]
 
-{- |  Converts the lookup table of a problem into a comma and newline deliminated
+{- |  Converts the lookup table of a problem into a comma and newline delimited
       string. This should facilitate copying into spreadsheets for checking the 
       problem being used and validating solutions by hand. -}
 
@@ -209,7 +209,7 @@
         matrix = M.fromList $ zip cityCoords (randomRs distanceLimits g)
         -- p' = (\x y->M.findWithDefault 0 (x,y) matrix)
         explicit = A.listArray (0,numCities*numCities-1)  [M.findWithDefault 0 (a,b) matrix | a<-cities,b<-cities]
-    in TSPProblem 0 M.empty (\x y->explicit A.! (x * numCities + y)) numCities M.empty M.empty
+    in TSPProblem 0 M.empty (\x y->explicit A.! (y * numCities + x)) numCities M.empty M.empty
     -- TSPProblem 0 M.empty p numCities M.empty M.empty
 
 {- |  Construct a TSPProblem instance for a Symmetric TSP. That is, the distance
@@ -229,7 +229,7 @@
         matrix = foldl f M.empty (zip cityCoords (randomRs distanceLimits g))
         explicit = A.listArray (0,numCities*numCities-1)  [M.findWithDefault 0 (a,b) matrix | a<-cities,b<-cities]
         triangular = A.listArray (0,sum [0..numCities])  [M.findWithDefault 0 (a,b) matrix | a<-cities,b<-[0..a]]
-        p = if storageType == ExplicitMatrix then (\x y->explicit A.! (x * numCities + y))
+        p = if storageType == ExplicitMatrix then (\x y->explicit A.! (y * numCities + x))
                                              else (\x y->let x' = min x y; y' = max x y in triangular A.! (div (y'*y'+y') 2 + x'))
     in TSPProblem 0 M.empty p numCities M.empty M.empty
 
diff --git a/CombinatorialOptimisation/TSP.o b/CombinatorialOptimisation/TSP.o
new file mode 100644
Binary files /dev/null and b/CombinatorialOptimisation/TSP.o differ
diff --git a/FileFormat/SATLIB.hi b/FileFormat/SATLIB.hi
new file mode 100644
Binary files /dev/null and b/FileFormat/SATLIB.hi differ
diff --git a/FileFormat/SATLIB.o b/FileFormat/SATLIB.o
new file mode 100644
Binary files /dev/null and b/FileFormat/SATLIB.o differ
diff --git a/FileFormat/TSPLIB.hi b/FileFormat/TSPLIB.hi
new file mode 100644
Binary files /dev/null and b/FileFormat/TSPLIB.hi differ
diff --git a/FileFormat/TSPLIB.hs b/FileFormat/TSPLIB.hs
--- a/FileFormat/TSPLIB.hs
+++ b/FileFormat/TSPLIB.hs
@@ -1,22 +1,58 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  FileFormat.TSPLIB
+-- Copyright   :  (c) Richard Senington 2011
+-- License     :  GPL-style
+-- 
+-- Maintainer  :  Richard Senington <sc06r2s@leeds.ac.uk>
+-- Stability   :  provisional
+-- Portability :  portable
+-- 
+-- Partial loading routines for the TSPLIB file format.
+-- The format itself has a large number of variations, 
+-- and this has only been designed to load the @tsp@ and 
+-- @atsp@ variants. It has been tried on all the files
+-- from the repository in these classes and it parses
+-- them at least. 
+--
+-- Relies upon the @CombinatorialOptimisation.TSP@ library.
+--
+-- Currently this does not use the Haskell parsing 
+-- libraries, nor ByteString, just some custom built
+-- routines.
+----------------------------------------------------------------------------- 
+
 module FileFormat.TSPLIB(
   loadTSPFile
   )where
 
--- only supports a subset of the TSPLIB format
--- not using real parsing libraries. This is probably a mistake.
--- also, still not using ByteString, also a misake.
-
 import CombinatorialOptimisation.TSP
-
-
--- load save of TSPLIB -- can only resave explicit data, could be cripling for big
--- data sets
+import Data.Maybe
+import qualified Data.Map as M
+import qualified Data.Array as A
+import Data.List
 
+{- |  Simple 2d Euclidian. -}
 
--- for those files where the co-ordinates of nodes are given
 euclidianDistance :: (Float,Float)->(Float,Float)->Float
 euclidianDistance (a,b) (c,d) = sqrt ((a-c)*(a-c)+(b-d)*(b-d))
 
+{- |  Always rounded up Euclidian. -}
+
+euclidianDistanceCeil :: (Float,Float)->(Float,Float)->Float
+euclidianDistanceCeil a b =  fromIntegral . ceiling     $  euclidianDistance a b
+
+{- |  For only two types of file. Basically a form of rounded Euclidian. -}
+
+pseudoEuclideanDistance :: (Float,Float)->(Float,Float)->Float
+pseudoEuclideanDistance (a,b) (c,d) = let e = sqrt (((a-c)*(a-c)+(b-d)*(b-d))  /10 )
+                                          f = fromIntegral (floor e)
+                                      in if f<e then f+1 else f
+
+{- |  Distance between two points on the Earth's surface. This is based upon code that 
+      another developer wrote, based on the code proposed by TSPLIB itself. I am 
+      not sure if this is for an earth shape, or just a sphere. I suspect earth shape. -}
+
 geoDistance :: (Float,Float)->(Float,Float)->Float
 geoDistance (x1,y1) (x2,y2) = encodeFloat (floor dij) 0
   where
@@ -33,27 +69,22 @@
     degConvert m = let deg = encodeFloat (floor m) 0
                        miN = m - deg
                    in 3.141592 * (deg + (5.0 * miN/3.0))/180.0
-{-
-readSpecification :: String->([(String,String)],String)
-readSpecification s | name -> print?
-                    | type -> TSP or ATSP only
-                    | comment -> throw or print
-                    | dimension Int
-                    | capacity, not interested
-                    | edge-weight-type -> Lots
-                    | edge-weight-format
-                    | edge-data-format
-                    | node-coord-type
-                    | display-data-type
-                    | eof: end do not expect
 
--}
+{- |  A data type for representing bits of the specification section of a file.
+      Assumed to be used later as a list of Specifications. -}
 
 data Specification = IGNORE String | USEFUL String String | ENDSPEC String | FAIL String deriving Show
 
+{- |  Test for filtering specification lines, so we only get data we might want to use. Could be
+      got rid of as most of the time I do dictionary lookups on the output of the specification
+      reading routines. -}
+
 isUsefulSpec (USEFUL _ _) = True
 isUsefulSpec _ = False
 
+{- |  Helper routine for @readSpecification@. Reads a single line (assumes 
+      that input is already line by line). -}
+
 readSpecificationLine :: String->Specification
 readSpecificationLine s 
   | likeString "NAME" s = IGNORE s
@@ -64,12 +95,15 @@
   | likeString "DIMENSION" s = USEFUL "Dimension" (trim s)
   | likeString "DISPLAY_DATA_TYPE" s = IGNORE s
   | likeString "EDGE_WEIGHT_TYPE" s = USEFUL "EdgeWeightType" (trim s)
+  | likeString "EDGE_WEIGHT_FORMAT" s = USEFUL "EdgeWeightFormat" (trim s)
   | otherwise = FAIL $ "unrecognised field in specification : "++s
   where
     likeString q s = take (length q) s == q
     trim s = let s' = (dropWhile (==' ')) . (drop 1) . (dropWhile (/=':')) $ s 
              in reverse . (dropWhile (==' ')) . reverse $ s'
 
+{- |  Helper routine for @loadTSPFile@. Reads the specification section of a file. -}
+
 readSpecification :: [String]->([Specification],[String])
 readSpecification [] = ([FAIL "seem to have run out of data, without ending the specification phase"],[]) 
 readSpecification (s:ss) = let p = readSpecificationLine s
@@ -80,25 +114,91 @@
                              FAIL _     -> (p:rs,es)
                              USEFUL _ _ -> (p:rs,es)
  
-loadTSPFile :: String->IO () -- TSPProblem
-loadTSPFile fName = do rawContents<-readFile fName
-                       let (spec,remainder) = readSpecification $ lines rawContents
-                       mapM_ print spec
-                       print ""
-                       mapM_ print $ filter isUsefulSpec spec
+{- |  Loads a TSPLIB style file. The first parameter is the internal 
+      storage type from @CombinatorialProblems.TSP@. It allows for 
+      full matrix, triangular matrix and full recalculation. If the 
+      requested internal storage cannot be used with the file, this 
+      will throw an error (e.g. recomputation where you are given a 
+      full matrix in the file).
 
-{- 
-readEdgeWeightSection
+      The second parameter is the file path. -}
 
-FULL_MATRIX 
+loadTSPFile :: InternalStorage->FilePath->IO TSPProblem
+loadTSPFile storageType fName 
+  = do rawContents<-readFile fName
+       let (spec,remainder) = readSpecification $ lines rawContents
+                       
+       -- mapM_ print spec
+       -- print ""
+  
+       let specList = map (\(USEFUL a b)->(a,b)) . filter isUsefulSpec $ spec
+       -- print specList
+       let dataPart = fromJust $ lookup "DATA PART TYPE" specList
+       let numNodes = read $ fromJust $ lookup "Dimension" specList
+       case dataPart of 
+         "NODE COORD"  -> return $ loadFromNodePositions storageType numNodes specList (takeWhile (/="EOF") remainder)
+         "EDGE WEIGHT" -> return $ loadFromMatrix storageType numNodes specList (takeWhile (/="EOF") remainder)
+         _             -> error "Unsupported data section"
 
-readEdgeWeightSection :: Num a=>String->Int->String->IO (Int->Int->Float)
-readEdgeWeightSection ty dim inputData 
-  = do 
+{- |  Helper routine for @loadTSPFile@. This assumes the input is just points and the 
+      distances must be calculated. -}
 
-readNodeCoordSection :: Num a=>String->Int->String->IO (Int->Int->Float)
-readNodeCoordSection dim inputData 
-  = do 
-                                              
+loadFromNodePositions :: InternalStorage->Int->[(String,String)]->[String]->TSPProblem
+loadFromNodePositions storageType numCities spec d 
+  = let d' = map ((\[a,b]->(a,b)) . (map readF) . (drop 1) . words) d
+        posArr = A.listArray (0 , numCities-1) d'
 
--}
+        cities = [0 ..(numCities-1)]
+        
+        explicit = A.listArray (0,numCities*numCities-1)  [distFunc (posArr A.! a) (posArr A.! b) | a<-cities,b<-cities]
+        triangular = A.listArray (0,sum [0..numCities])  [distFunc (posArr A.! a) (posArr A.! b) | a<-cities,b<-[0..a]]
+       
+        p = case storageType of
+              ExplicitMatrix -> \x y->explicit A.! (x * numCities + y)
+              TriangularMatrix -> (\x y->let x' = min x y; y' = max x y in triangular A.! (div (y'*y'+y') 2 + x'))
+              Recomputation -> \a b->distFunc (posArr A.! a) (posArr A.! b)
+    in TSPProblem 0 M.empty p numCities M.empty M.empty
+  where
+    readF = read :: (String->Float)
+    distanceFunctionSpec = fromJust $ lookup "EdgeWeightType" spec
+    distFunc = case distanceFunctionSpec of
+       "GEO" -> geoDistance
+       "EUC_2D" -> euclidianDistance
+       "ATT"    -> pseudoEuclideanDistance
+       "CEIL_2D"-> euclidianDistanceCeil
+       _        -> error $ "unsupported distance function : "++distanceFunctionSpec
+ 
+{- |  Helper routine for @loadTSPFile@. This assumes the input data is a matrix of some form, 
+      and loads it. -}
+
+loadFromMatrix  :: InternalStorage->Int->[(String,String)]->[String]->TSPProblem
+loadFromMatrix Recomputation _ _ _ = error "Cannot load matrix and store in recomputation form"
+loadFromMatrix storageType numCities spec d
+  | distanceFunctionSpec /= "EXPLICIT" = error "loading from non explicit matrix? (does not make sense)"
+  | storageType == TriangularMatrix = TSPProblem 0 M.empty (\x y->let x' = min x y; y' = max x y in triangularArray A.! (div (y'*y'+y') 2 + x')) numCities M.empty M.empty
+  | storageType == ExplicitMatrix = TSPProblem 0 M.empty (\x y->explicitArray A.! (y * numCities + x)) numCities M.empty M.empty
+  where
+    readF = read :: (String->Float)
+    distanceFunctionSpec = fromJust $ lookup "EdgeWeightType" spec
+    inputNumberSequence = concatMap ((map readF) . words) d -- not entirely trusting line breaks in file format, so turning into list of numbers, and putting in coords later
+    cities = [0 ..(numCities-1)]
+
+    blankMatrix = foldl' (\m d->M.insert (d,d) 0 m) M.empty cities
+    fillPair m ((a,b),c) = M.insert (b,a) c $ (M.insert (a,b) c m)
+    makeFromTri = foldl' fillPair blankMatrix
+
+    loadedMap = case fromJust $ lookup "EdgeWeightFormat" spec of
+           "FULL_MATRIX" -> foldl' (\m (d,c)->M.insert d c m) M.empty (zip [(a,b) | a<-cities,b<-cities] inputNumberSequence)
+           "UPPER_ROW"      -> makeFromTri $ zip [(a,b) | a<-cities,b<-[a..(numCities - 1)],a/=b] inputNumberSequence
+           "LOWER_ROW"      -> makeFromTri $ zip [(a,b) | a<-cities,b<-[0..a],a/=b] inputNumberSequence
+           "UPPER_DIAG_ROW" -> makeFromTri $ zip [(a,b) | a<-cities,b<-[a..(numCities - 1)]] inputNumberSequence
+           "LOWER_DIAG_ROW" -> makeFromTri $ zip [(a,b) | a<-cities,b<-[0..a]] inputNumberSequence
+
+           "UPPER_COL"      -> makeFromTri $ zip [(b,a) | a<-cities,b<-[a..(numCities - 1)],a/=b] inputNumberSequence
+           "LOWER_COL"      -> makeFromTri $ zip [(b,a) | a<-cities,b<-[0..a],a/=b] inputNumberSequence
+           "UPPER_DIAG_COL" -> makeFromTri $ zip [(b,a) | a<-cities,b<-[a..(numCities - 1)]] inputNumberSequence
+           "LOWER_DIAG_COL" -> makeFromTri $ zip [(b,a) | a<-cities,b<-[0..a]] inputNumberSequence
+ 
+    explicitArray = A.listArray (0,numCities*numCities-1) [loadedMap M.! (a,b) | a<-cities,b<-cities]
+    triangularArray = A.listArray (0,sum [0..numCities])  [loadedMap M.! (a,b) | a<-cities,b<-[0..a]]
+
diff --git a/FileFormat/TSPLIB.hs~ b/FileFormat/TSPLIB.hs~
--- a/FileFormat/TSPLIB.hs~
+++ b/FileFormat/TSPLIB.hs~
@@ -1,22 +1,58 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  FileFormat.TSPLIB
+-- Copyright   :  (c) Richard Senington 2011
+-- License     :  GPL-style
+-- 
+-- Maintainer  :  Richard Senington <sc06r2s@leeds.ac.uk>
+-- Stability   :  provisional
+-- Portability :  portable
+-- 
+-- Partial loading routines for the TSPLIB file format.
+-- The format itself has a large number of variations, 
+-- and this has only been designed to load the @tsp@ and 
+-- @atsp@ variants. It has been tried on all the files
+-- from the repository in these classes and it parses
+-- them at least. 
+--
+-- Relies upon the @CombinatorialOptimisation.TSP@ library.
+--
+-- Currently this does not use the Haskell parsing 
+-- libraries, nor ByteString, just some custom built
+-- routines.
+----------------------------------------------------------------------------- 
+
 module FileFormat.TSPLIB(
   loadTSPFile
   )where
 
--- only supports a subset of the TSPLIB format
--- not using real parsing libraries. This is probably a mistake.
--- also, still not using ByteString, also a misake.
-
 import CombinatorialOptimisation.TSP
-
-
--- load save of TSPLIB -- can only resave explicit data, could be cripling for big
--- data sets
+import Data.Maybe
+import qualified Data.Map as M
+import qualified Data.Array as A
+import Data.List
 
+{- |  Simple 2d Euclidian. -}
 
--- for those files where the co-ordinates of nodes are given
 euclidianDistance :: (Float,Float)->(Float,Float)->Float
 euclidianDistance (a,b) (c,d) = sqrt ((a-c)*(a-c)+(b-d)*(b-d))
 
+{- |  Always rounded up euclidian. -}
+
+euclidianDistanceCeil :: (Float,Float)->(Float,Float)->Float
+euclidianDistanceCeil a b =  fromIntegral . ceiling     $  euclidianDistance a b
+
+{- |  For only two types of file. Basically a form of rounded euclidian. -}
+
+pseudoEuclideanDistance :: (Float,Float)->(Float,Float)->Float
+pseudoEuclideanDistance (a,b) (c,d) = let e = sqrt (((a-c)*(a-c)+(b-d)*(b-d))  /10 )
+                                          f = fromIntegral (floor e)
+                                      in if f<e then f+1 else f
+
+{- |  Distance between two points on the earths surface. This is based upon code that 
+      another developer wrote, based on the code proposed by TSPLIB itself. I am 
+      not sure if this is for an earth shape, or just a sphere. I suspect earth shape. -}
+
 geoDistance :: (Float,Float)->(Float,Float)->Float
 geoDistance (x1,y1) (x2,y2) = encodeFloat (floor dij) 0
   where
@@ -33,27 +69,22 @@
     degConvert m = let deg = encodeFloat (floor m) 0
                        miN = m - deg
                    in 3.141592 * (deg + (5.0 * miN/3.0))/180.0
-{-
-readSpecification :: String->([(String,String)],String)
-readSpecification s | name -> print?
-                    | type -> TSP or ATSP only
-                    | comment -> throw or print
-                    | dimension Int
-                    | capacity, not interested
-                    | edge-weight-type -> Lots
-                    | edge-weight-format
-                    | edge-data-format
-                    | node-coord-type
-                    | display-data-type
-                    | eof: end do not expect
 
--}
+{- |  A data type for representing bits of the specification section of a file.
+      Assumed to be used later as a list of Specifications. -}
 
 data Specification = IGNORE String | USEFUL String String | ENDSPEC String | FAIL String deriving Show
 
+{- |  Test for filtering specification lines, so we only get data we might want to use. Could be
+      got rid of as most of the time I do dictionary lookups on the output of the specification
+      reading routines. -}
+
 isUsefulSpec (USEFUL _ _) = True
 isUsefulSpec _ = False
 
+{- |  Helper routine for @readSpecification@. Reads a single line (assumes 
+      that input is already line by line). -}
+
 readSpecificationLine :: String->Specification
 readSpecificationLine s 
   | likeString "NAME" s = IGNORE s
@@ -64,12 +95,15 @@
   | likeString "DIMENSION" s = USEFUL "Dimension" (trim s)
   | likeString "DISPLAY_DATA_TYPE" s = IGNORE s
   | likeString "EDGE_WEIGHT_TYPE" s = USEFUL "EdgeWeightType" (trim s)
+  | likeString "EDGE_WEIGHT_FORMAT" s = USEFUL "EdgeWeightFormat" (trim s)
   | otherwise = FAIL $ "unrecognised field in specification : "++s
   where
     likeString q s = take (length q) s == q
     trim s = let s' = (dropWhile (==' ')) . (drop 1) . (dropWhile (/=':')) $ s 
              in reverse . (dropWhile (==' ')) . reverse $ s'
 
+{- |  Helper routine for @loadTSPFile@. Reads the specification section of a file. -}
+
 readSpecification :: [String]->([Specification],[String])
 readSpecification [] = ([FAIL "seem to have run out of data, without ending the specification phase"],[]) 
 readSpecification (s:ss) = let p = readSpecificationLine s
@@ -80,26 +114,91 @@
                              FAIL _     -> (p:rs,es)
                              USEFUL _ _ -> (p:rs,es)
  
+{- |  Loads a TSPLIB style file. The first parameter is the internal 
+      storage type from @CombinatorialProblems.TSP@. It allows for 
+      full matrix, triangular matrix and full recalculation. If the 
+      requested internal storage cannot be used with the file, this 
+      will throw an error (e.g. recomputation where you are given a 
+      full matrix in the file).
 
-loadTSPFile :: String->IO () -- TSPProblem
-loadTSPFile fName = do rawContents<-readFile fName
-                       let (spec,remainder) = readSpecification $ lines rawContents
-                       mapM_ print spec
-                       print ""
-                       mapM_ print $ filter isUsefulSpec spec
+      The second parameter is the file path. -}
 
-{- 
-readEdgeWeightSection
+loadTSPFile :: InternalStorage->FilePath->IO TSPProblem
+loadTSPFile storageType fName 
+  = do rawContents<-readFile fName
+       let (spec,remainder) = readSpecification $ lines rawContents
+                       
+       -- mapM_ print spec
+       -- print ""
+  
+       let specList = map (\(USEFUL a b)->(a,b)) . filter isUsefulSpec $ spec
+       -- print specList
+       let dataPart = fromJust $ lookup "DATA PART TYPE" specList
+       let numNodes = read $ fromJust $ lookup "Dimension" specList
+       case dataPart of 
+         "NODE COORD"  -> return $ loadFromNodePositions storageType numNodes specList (takeWhile (/="EOF") remainder)
+         "EDGE WEIGHT" -> return $ loadFromMatrix storageType numNodes specList (takeWhile (/="EOF") remainder)
+         _             -> error "Unsupported data section"
 
-FULL_MATRIX 
+{- |  Helper routine for @loadTSPFile@. This assumes the input is just points and the 
+      distances must be calculated. -}
 
-readEdgeWeightSection :: Num a=>String->Int->String->IO (Int->Int->Float)
-readEdgeWeightSection ty dim inputData 
-  = do 
+loadFromNodePositions :: InternalStorage->Int->[(String,String)]->[String]->TSPProblem
+loadFromNodePositions storageType numCities spec d 
+  = let d' = map ((\[a,b]->(a,b)) . (map readF) . (drop 1) . words) d
+        posArr = A.listArray (0 , numCities-1) d'
 
-readNodeCoordSection :: Num a=>String->Int->String->IO (Int->Int->Float)
-readNodeCoordSection dim inputData 
-  = do 
-                                              
+        cities = [0 ..(numCities-1)]
+        
+        explicit = A.listArray (0,numCities*numCities-1)  [distFunc (posArr A.! a) (posArr A.! b) | a<-cities,b<-cities]
+        triangular = A.listArray (0,sum [0..numCities])  [distFunc (posArr A.! a) (posArr A.! b) | a<-cities,b<-[0..a]]
+       
+        p = case storageType of
+              ExplicitMatrix -> \x y->explicit A.! (x * numCities + y)
+              TriangularMatrix -> (\x y->let x' = min x y; y' = max x y in triangular A.! (div (y'*y'+y') 2 + x'))
+              Recomputation -> \a b->distFunc (posArr A.! a) (posArr A.! b)
+    in TSPProblem 0 M.empty p numCities M.empty M.empty
+  where
+    readF = read :: (String->Float)
+    distanceFunctionSpec = fromJust $ lookup "EdgeWeightType" spec
+    distFunc = case distanceFunctionSpec of
+       "GEO" -> geoDistance
+       "EUC_2D" -> euclidianDistance
+       "ATT"    -> pseudoEuclideanDistance
+       "CEIL_2D"-> euclidianDistanceCeil
+       _        -> error $ "unsupported distance function : "++distanceFunctionSpec
+ 
+{- |  Helper routine for @loadTSPFile@. This assumes the input data is a matrix of some form, 
+      and loads it. -}
 
--}
+loadFromMatrix  :: InternalStorage->Int->[(String,String)]->[String]->TSPProblem
+loadFromMatrix Recomputation _ _ _ = error "Cannot load matrix and store in recomputation form"
+loadFromMatrix storageType numCities spec d
+  | distanceFunctionSpec /= "EXPLICIT" = error "loading from non explicit matrix? (does not make sense)"
+  | storageType == TriangularMatrix = TSPProblem 0 M.empty (\x y->let x' = min x y; y' = max x y in triangularArray A.! (div (y'*y'+y') 2 + x')) numCities M.empty M.empty
+  | storageType == ExplicitMatrix = TSPProblem 0 M.empty (\x y->explicitArray A.! (y * numCities + x)) numCities M.empty M.empty
+  where
+    readF = read :: (String->Float)
+    distanceFunctionSpec = fromJust $ lookup "EdgeWeightType" spec
+    inputNumberSequence = concatMap ((map readF) . words) d -- not entirely trusting line breaks in file format, so turning into list of numbers, and putting in coords later
+    cities = [0 ..(numCities-1)]
+
+    blankMatrix = foldl' (\m d->M.insert (d,d) 0 m) M.empty cities
+    fillPair m ((a,b),c) = M.insert (b,a) c $ (M.insert (a,b) c m)
+    makeFromTri = foldl' fillPair blankMatrix
+
+    loadedMap = case fromJust $ lookup "EdgeWeightFormat" spec of
+           "FULL_MATRIX" -> foldl' (\m (d,c)->M.insert d c m) M.empty (zip [(a,b) | a<-cities,b<-cities] inputNumberSequence)
+           "UPPER_ROW"      -> makeFromTri $ zip [(a,b) | a<-cities,b<-[a..(numCities - 1)],a/=b] inputNumberSequence
+           "LOWER_ROW"      -> makeFromTri $ zip [(a,b) | a<-cities,b<-[0..a],a/=b] inputNumberSequence
+           "UPPER_DIAG_ROW" -> makeFromTri $ zip [(a,b) | a<-cities,b<-[a..(numCities - 1)]] inputNumberSequence
+           "LOWER_DIAG_ROW" -> makeFromTri $ zip [(a,b) | a<-cities,b<-[0..a]] inputNumberSequence
+
+           "UPPER_COL"      -> makeFromTri $ zip [(b,a) | a<-cities,b<-[a..(numCities - 1)],a/=b] inputNumberSequence
+           "LOWER_COL"      -> makeFromTri $ zip [(b,a) | a<-cities,b<-[0..a],a/=b] inputNumberSequence
+           "UPPER_DIAG_COL" -> makeFromTri $ zip [(b,a) | a<-cities,b<-[a..(numCities - 1)]] inputNumberSequence
+           "LOWER_DIAG_COL" -> makeFromTri $ zip [(b,a) | a<-cities,b<-[0..a]] inputNumberSequence
+ 
+    explicitArray = A.listArray (0,numCities*numCities-1) [loadedMap M.! (a,b) | a<-cities,b<-cities]
+    triangularArray = A.listArray (0,sum [0..numCities])  [loadedMap M.! (a,b) | a<-cities,b<-[0..a]]
+
diff --git a/FileFormat/TSPLIB.o b/FileFormat/TSPLIB.o
new file mode 100644
Binary files /dev/null and b/FileFormat/TSPLIB.o differ
diff --git a/Test.hs~ b/Test.hs~
--- a/Test.hs~
+++ b/Test.hs~
@@ -6,6 +6,8 @@
 import System.Random
 import qualified Data.Map as M
 
+import System.Directory
+
 {- 
 main :: IO()
 main = do s<-loadCNFFile "./CBS_k3_n100_m403_b10_0.cnf"
@@ -33,17 +35,16 @@
 
 -}
 
-{- 
--- checking stability of arrays, rather than map
+{-
 main :: IO()
-main = do gen<-newStdGen
-          let (meep,meep') = makeASymmetricTSPMap (2,5) 50 gen
-          putStrLn $ showEdgeWeights meep
-          putStrLn ""
-          putStrLn $ showEdgeWeights meep'
+main = do let gen = mkStdGen 5
+          let meep = makeSymmetricTSPMap ExplicitMatrix (2,5) 50 gen
+          let meep' = makeSymmetricTSPMap TriangularMatrix (2,5) 50 gen
           putStrLn $ show $ showEdgeWeights meep == showEdgeWeights meep'
+
 -}
 
+{-
 -- checking stability of arrays, rather than map
 main :: IO()
 main = do let gen = mkStdGen 5
@@ -55,8 +56,51 @@
           putStrLn ""
           putStrLn $ showEdgeWeights meep'
           putStrLn $ show $ (showEdgeWeights meep == showEdgeWeights meep') && (showEdgeWeights meep == showEdgeWeights meep'')
+-}
 
-{- 
+{-
 -- checking loading TSPs
 main :: IO()
-main = do loadTSPFile "../exampleProblems/ali535.tsp" -}
+main = do b<-loadTSPFile Recomputation "../exampleProblems/ali535.tsp" 
+          c<-loadTSPFile TriangularMatrix "../exampleProblems/ali535.tsp" 
+          d<-loadTSPFile ExplicitMatrix "../exampleProblems/ali535.tsp" 
+          putStrLn $ show $ (showEdgeWeights d == showEdgeWeights c) && (showEdgeWeights d == showEdgeWeights b)
+-}
+
+{-
+-- still checking the loading of TSPs
+main :: IO()
+main = do b<-loadTSPFile ExplicitMatrix "../exampleProblems/brazil58.tsp" 
+          putStrLn $ showEdgeWeights b -}
+
+-- brute force loading
+main :: IO()
+main = do xs<-getDirectoryContents "../exampleProblems" >>= (\x->return (drop 2 x))
+          mapM_ (\x->do b<-loadTSPFile ExplicitMatrix ("../exampleProblems/"++x)
+                        if (numCities b < 1000) then print $ getLastEdge b  
+                                                else print $ x++" too big for explicit") xs
+          main2
+  where
+    getLastEdge t = let m = numCities t -1 in edgePrices t m m
+
+problemFiles = ["brazil58.tsp","bayg29.tsp","bays29.tsp","brg180.tsp","dantzig42.tsp"]
+
+customFilter :: [String]->IO [String]
+customFilter [] = return []
+customFilter (x:xs) = do b<-loadTSPFile ExplicitMatrix ("../exampleProblems/"++x)
+                         if numCities b <1000 then customFilter xs
+                                              else do ps<-customFilter xs
+                                                      return (x:ps)
+
+main2 :: IO()
+main2 = do xs<-getDirectoryContents "../exampleProblems" >>= (\x->return (drop 2 x)) 
+           xs' <-customFilter xs
+           print xs'
+           mapM_ (\x->do print x
+                         b<-loadTSPFile Recomputation ("../exampleProblems/"++x)
+                         print $ getLastEdge b ) xs' 
+  where
+    getLastEdge t = let m = numCities t -1 in edgePrices t m m
+          
+
+
diff --git a/combinatorial-problems.cabal b/combinatorial-problems.cabal
--- a/combinatorial-problems.cabal
+++ b/combinatorial-problems.cabal
@@ -1,5 +1,5 @@
 Name:              combinatorial-problems
-Version:           0.0.1
+Version:           0.0.2
 Synopsis:          A number of data structures to represent and allow the manipulation of standard combinatorial problems, used as test problems in computer science.
 Description:       In computer science there are a number of standard test problems that are used for testing algorithms, 
                    especially those related to Artificial Intelligence and Operations Research. Online there are a number 
@@ -10,7 +10,7 @@
                    This library seeks to provide implementations of data structures to store these problems, along with 
                    functions for manipulating the problems and routines to load problem files from various sources. 
                    .
-                   At present it only supports TSP and SAT\/SATLIB (TSPLIB coming soon), however it is hoped that the loading routines 
+                   At present it only supports TSP\/TSPLIB and SAT\/SATLIB, however it is hoped that the loading routines 
                    can be expanded and the range of problems expanded to cover problems like scheduling and timetabling.
                    The internal data structures make heavy use of the @Data.Map@ library and @Data.Array@. It is not currently
                    using unboxed values. The library does not use the @bytestring@ library for loading and saving data either, 
@@ -22,13 +22,14 @@
 License:           GPL
 license-file:      LICENSE
 Copyright:         Copyright (c) 2011 Richard Senington
-Homepage:          http://www.comp.leeds.ac.uk/sc06r2s/Projects/HaskellLocalSearch
+Homepage:          http://www.comp.leeds.ac.uk/sc06r2s/Projects/HaskellCombinatorialProblems
 Maintainer:        sc06r2s@leeds.ac.uk
 Build-Type:        Simple
 Cabal-Version:     >= 1.2
 
 library
   Exposed-Modules: FileFormat.SATLIB
+                   FileFormat.TSPLIB
                    CombinatorialOptimisation.SAT
                    CombinatorialOptimisation.TSP
   Build-Depends:   base >= 2.0 && <=5, 
diff --git a/combinatorial-problems.cabal~ b/combinatorial-problems.cabal~
--- a/combinatorial-problems.cabal~
+++ b/combinatorial-problems.cabal~
@@ -1,5 +1,5 @@
 Name:              combinatorial-problems
-Version:           0.0.1
+Version:           0.0.2
 Synopsis:          A number of data structures to represent and allow the manipulation of standard combinatorial problems, used as test problems in computer science.
 Description:       In computer science there are a number of standard test problems that are used for testing algorithms, 
                    especially those related to Artificial Intelligence and Operations Research. Online there are a number 
@@ -10,7 +10,7 @@
                    This library seeks to provide implementations of data structures to store these problems, along with 
                    functions for manipulating the problems and routines to load problem files from various sources. 
                    .
-                   At present it only supports TSP and SAT\/SATLIB (TSPLIB coming soon), however it is hoped that the loading routines 
+                   At present it only supports TSP\/TSPLIB and SAT\/SATLIB, however it is hoped that the loading routines 
                    can be expanded and the range of problems expanded to cover problems like scheduling and timetabling.
                    The internal data structures make heavy use of the @Data.Map@ library and @Data.Array@. It is not currently
                    using unboxed values. The library does not use the @bytestring@ library for loading and saving data either, 
@@ -22,7 +22,7 @@
 License:           GPL
 license-file:      LICENSE
 Copyright:         Copyright (c) 2011 Richard Senington
-Homepage:          http://www.comp.leeds.ac.uk/sc06r2s/Projects/HaskellLocalSearch
+Homepage:          http://www.comp.leeds.ac.uk/sc06r2s/Projects/HaskellCombinatorialProblems
 Maintainer:        sc06r2s@leeds.ac.uk
 Build-Type:        Simple
 Cabal-Version:     >= 1.2
diff --git a/meep~ b/meep~
new file mode 100644
# file too large to diff: meep~
