Skip to content

Commit cf7eb32

Browse files
committed
initial commit
0 parents  commit cf7eb32

28 files changed

+970
-0
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.stack-work/
2+
*~

ChangeLog.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Changelog for autotool-solver
2+
3+
## Unreleased changes

LICENSE

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
Copyright Oliver Herrmann (c) 2021
2+
3+
All rights reserved.
4+
5+
Redistribution and use in source and binary forms, with or without
6+
modification, are permitted provided that the following conditions are met:
7+
8+
* Redistributions of source code must retain the above copyright
9+
notice, this list of conditions and the following disclaimer.
10+
11+
* Redistributions in binary form must reproduce the above
12+
copyright notice, this list of conditions and the following
13+
disclaimer in the documentation and/or other materials provided
14+
with the distribution.
15+
16+
* Neither the name of Oliver Herrmann nor the names of other
17+
contributors may be used to endorse or promote products derived
18+
from this software without specific prior written permission.
19+
20+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24+
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

README.md

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Lösungsalgorithmen
2+
3+
- circle.hs: findet einen Kreis der Länge n in einem Graphen
4+
- colorgraph.hs: findet eine konfliktfreie Färbung eines Graphen
5+
- hamilton.hs: findet Hamiltonkreis in Graph
6+
- relations.hs: findet einen Ausdruck aus zwei Relationen, der einer dritten Relation entspricht
7+
- sets.hs: findet einen Ausdruck aus zwei Mengen, der einer dritten Menge entspricht

Setup.hs

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import Distribution.Simple
2+
main = defaultMain

app/Main.hs

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import Autotool.Data.Set (S(..), insert, union, diff, intersect, compose, pow)
2+
import Autotool.Data.Op (Op2(..), Op1(..))
3+
import Autotool.Data.Tree (Tree(..), size, buildTrees)
4+
import Autotool.Solver.Relations (solve)
5+
6+
main :: IO ()
7+
main = do
8+
let a = Set "R" [ V(1 , 4), V(2 , 4), V(3 , 2), V(4 , 1) ] :: S (Int,Int)
9+
let b = Set "S" [ V(1 , 4), V(2 , 2), V(2 , 3), V(4 , 4) ]
10+
let r = S[ V(1 , 1) , V(1 , 4) , V(2 , 1) , V(2 , 2) , V(2 , 4) , V(4 , 1) , V(4 , 4) ]
11+
let op2s = [Add, And, Subtr, Compose]
12+
let op1s = []
13+
print $ solve op2s op1s [a,b] r 3

autotool-solver.cabal

+82
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
cabal-version: 1.12
2+
3+
-- This file has been generated from package.yaml by hpack version 0.33.0.
4+
--
5+
-- see: https://github.com/sol/hpack
6+
--
7+
-- hash: 22ede20657c59b8dac01b91a2978e572dc7bfc2c9a535431dec16b1f5c27b366
8+
9+
name: autotool-solver
10+
version: 0.1.0.0
11+
description: Please see the README on GitHub at <https://github.com/herrmanno/autotool-solver#readme>
12+
homepage: https://github.com/herrmanno/autotool-solver#readme
13+
bug-reports: https://github.com/herrmanno/autotool-solver/issues
14+
author: Oliver Herrmann
15+
maintainer: o.herrmann92@gmail.com
16+
copyright: Oliver Herrmann 2021
17+
license: BSD3
18+
license-file: LICENSE
19+
build-type: Simple
20+
extra-source-files:
21+
README.md
22+
ChangeLog.md
23+
24+
source-repository head
25+
type: git
26+
location: https://github.com/herrmanno/autotool-solver
27+
28+
library
29+
exposed-modules:
30+
Autotool.Data.Graph
31+
Autotool.Data.LazyTree
32+
Autotool.Data.Op
33+
Autotool.Data.Set
34+
Autotool.Data.Tree
35+
Autotool.Solver.Circle
36+
Autotool.Solver.ColorGraph
37+
Autotool.Solver.Graphs
38+
Autotool.Solver.Hamilton
39+
Autotool.Solver.Relations
40+
Autotool.Solver.Sets
41+
Autotool.Util.Hash
42+
other-modules:
43+
Paths_autotool_solver
44+
hs-source-dirs:
45+
src
46+
build-depends:
47+
base >=4.7 && <5
48+
, containers >=0.5.6 && <6
49+
default-language: Haskell2010
50+
51+
executable autotool-solver-exe
52+
main-is: Main.hs
53+
other-modules:
54+
Paths_autotool_solver
55+
hs-source-dirs:
56+
app
57+
ghc-options: -threaded -rtsopts -with-rtsopts=-N
58+
build-depends:
59+
autotool-solver
60+
, base >=4.7 && <5
61+
, containers >=0.5.6 && <6
62+
default-language: Haskell2010
63+
64+
test-suite autotool-solver-test
65+
type: exitcode-stdio-1.0
66+
main-is: Spec.hs
67+
other-modules:
68+
Autotool.Solver.CircleSpec
69+
Autotool.Solver.ColorGraphSpec
70+
Autotool.Solver.HamiltonSpec
71+
Autotool.Solver.RelationsSpec
72+
Autotool.Solver.SetsSpec
73+
Paths_autotool_solver
74+
hs-source-dirs:
75+
test
76+
ghc-options: -threaded -rtsopts -with-rtsopts=-N
77+
build-depends:
78+
autotool-solver
79+
, base >=4.7 && <5
80+
, containers >=0.5.6 && <6
81+
, hspec
82+
default-language: Haskell2010

package.yaml

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
name: autotool-solver
2+
version: 0.1.0.0
3+
github: "herrmanno/autotool-solver"
4+
license: BSD3
5+
author: "Oliver Herrmann"
6+
maintainer: "o.herrmann92@gmail.com"
7+
copyright: "Oliver Herrmann 2021"
8+
9+
extra-source-files:
10+
- README.md
11+
- ChangeLog.md
12+
13+
# Metadata used when publishing your package
14+
# synopsis: Short description of your package
15+
# category: Web
16+
17+
# To avoid duplicated efforts in documentation and dealing with the
18+
# complications of embedding Haddock markup inside cabal files, it is
19+
# common to point users to the README.md file.
20+
description: Please see the README on GitHub at <https://github.com/herrmanno/autotool-solver#readme>
21+
22+
dependencies:
23+
- base >= 4.7 && < 5
24+
- containers >= 0.5.6 && < 6
25+
26+
library:
27+
source-dirs: src
28+
29+
executables:
30+
autotool-solver-exe:
31+
main: Main.hs
32+
source-dirs: app
33+
ghc-options:
34+
- -threaded
35+
- -rtsopts
36+
- -with-rtsopts=-N
37+
dependencies:
38+
- autotool-solver
39+
40+
tests:
41+
autotool-solver-test:
42+
main: Spec.hs
43+
source-dirs: test
44+
ghc-options:
45+
- -threaded
46+
- -rtsopts
47+
- -with-rtsopts=-N
48+
dependencies:
49+
- autotool-solver
50+
- hspec

src/Autotool/Data/Graph.hs

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
{-# LANGUAGE TupleSections #-}
2+
3+
module Autotool.Data.Graph (Graph, mkGraph, mkI, mkK, mkP, mkC, kante, neighbours, complement, join, add, subgraph, isCircle, Color(..)) where
4+
5+
import Data.Set (fromList, Set, toList, (\\), notMember)
6+
import qualified Data.Set as S
7+
import Data.Maybe (mapMaybe)
8+
9+
-- FIXME: a graph may need a Name for output!
10+
type Graph a = (Set a, Set (a,a))
11+
12+
-- constructors
13+
14+
mkGraph :: (Ord a) => [a] -> [(a,a)] -> Graph a
15+
mkGraph vs es = (fromList vs, fromList es)
16+
17+
kante :: (Ord a) => a -> a -> (a,a)
18+
kante = (,)
19+
20+
mkI :: Int -> Graph Int
21+
mkI n = mkGraph [1..n] []
22+
23+
mkK :: Int -> Graph Int
24+
mkK n = let vs = [1..n] in mkGraph vs (allEdges vs)
25+
26+
mkP :: Int -> Graph Int
27+
mkP n = let vs = [1..n] in mkGraph vs (zip vs $ drop 1 vs)
28+
29+
mkC :: Int -> Graph Int
30+
mkC n = let vs = [1..n] in mkGraph vs ((n,1):zip vs (drop 1 vs))
31+
32+
-- operations
33+
34+
neighbours :: (Eq a) => Graph a -> a -> [a]
35+
neighbours (vs, es) v = mapMaybe f (toList es) where
36+
f (a,b)
37+
| a == v = Just b
38+
| b == v = Just a
39+
| otherwise = Nothing
40+
41+
complement :: (Ord a) => Graph a -> Graph a
42+
complement (vs, es) = let esAll = fromList $ allEdges (toList vs) in (vs, diff esAll es)
43+
where diff ea eb = S.filter (\(a,b) -> (a,b) `notMember` eb && (b,a) `notMember` eb) ea
44+
45+
-- TODO: make join take a rename function
46+
join :: (Ord a, Num a) => Graph a -> Graph a -> Graph a
47+
join g@(vs, es) h@(hs,_) = (S.union vs vs', edges) where
48+
(vs', es') = rename renameF h
49+
edges = fromList $ concatMap (\v -> map (,v) (toList vs')) (toList vs)
50+
maxV = S.findMax vs
51+
minV' = S.findMin hs
52+
renameF = if maxV >= minV' then (+maxV) else id
53+
54+
add :: (Ord a, Num a) => Graph a -> Graph a -> Graph a
55+
add (vs, es) h@(hs,_) = (S.union vs vs', S.union es es') where
56+
(vs', es') = rename renameF h
57+
maxV = S.findMax vs
58+
minV' = S.findMin hs
59+
renameF = if maxV >= minV' then (+maxV) else id
60+
61+
subgraph :: (Ord a) => Graph a -> [a] -> Graph a
62+
subgraph (vs, es) vs' = (fromList vs', es') where
63+
es' = S.filter (\(a,b) -> a `elem` vs' && b `elem` vs') es
64+
65+
isCircle :: (Eq a) => Graph a -> Bool
66+
isCircle g@(vs, es) = length vs == length es && all ((==2) . degree g) (toList vs)
67+
68+
degree :: (Eq a) => Graph a -> a -> Int
69+
degree (_, es) v = length $ S.filter (\(a,b) -> a == v || b == v) es
70+
71+
-- utility functions
72+
73+
allEdges :: [a] -> [(a,a)]
74+
allEdges [a,b] = [(a,b)]
75+
allEdges (v:vs) = allEdges vs ++ concatMap (allEdges . (:[v])) vs
76+
allEdges _ = []
77+
78+
rename :: (Ord a, Ord b) => (a -> b) -> Graph a -> Graph b
79+
rename f (vs, es) = (vs', es') where
80+
vs' = S.map f vs
81+
es' = S.map f' es
82+
f' (a,b) = (f a, f b)
83+
84+
-- Colors
85+
86+
data Color = A | B | C | D | E | F deriving (Eq, Ord, Enum, Show)

src/Autotool/Data/LazyTree.hs

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
{-# LANGUAGE LambdaCase #-}
2+
{-# LANGUAGE TupleSections #-}
3+
4+
module Autotool.Data.LazyTree (Op(..), trees) where
5+
6+
import Data.Tree ( foldTree, levels, Tree(Node) )
7+
8+
data Op a = Op0 a | Op1 String (a -> a) | Op2 String (a -> a -> a)
9+
10+
isOp0 (Op0 _) = True
11+
isOp0 _ = False
12+
13+
isOp1 (Op1 _ _) = True
14+
isOp1 _ = False
15+
16+
isOp2 (Op2 _ _) = True
17+
isOp2 _ = False
18+
19+
instance (Eq a) => Eq (Op a) where
20+
(Op0 a) == (Op0 b) = a == b
21+
(Op1 a _) == (Op1 b _) = a == b
22+
(Op2 a _) == (Op2 b _) = a == b
23+
_ == _ = False
24+
25+
instance (Show a) => Show (Op a) where
26+
show (Op0 a) = show a
27+
show (Op1 s _) = s
28+
show (Op2 s _) = s
29+
30+
-- |Lazy-builds a list of trees from a given operator and takes a specific one from the list
31+
--
32+
-- example: build arithmetic trees from a given set of constants (1,2)
33+
--
34+
-- >>> trees [Op0 1, Op0 2, Op1, "-" negate, Op2 "+" (+)] 0
35+
--
36+
trees :: [Op a] -- ^ the given operators
37+
-> Int -- ^ the tree index to retrieve
38+
-> Tree (Op a) -- ^ the n-th tree
39+
trees ops = (fmap f [0..] !!) where
40+
-- constants
41+
ar0 = filter isOp0 ops
42+
ar1 = filter isOp1 ops
43+
ar2 = filter isOp2 ops
44+
-- functions
45+
f n
46+
| n < length ar0 = Node (ar0 !! n) []
47+
| otherwise = let op = operator n in Node op $ children op n
48+
children op n = let tl = termsL n; tl2 = tl^2 in case op of
49+
(Op1 _ _) -> [trees ops (n - tl)]
50+
(Op2 _ _) -> [trees ops (n `rem` tl2 `div` tl), trees ops (n `rem` tl2 `rem` tl)]
51+
_ -> []
52+
operator n =
53+
let tl = termsL n
54+
ops = concatMap (replicate tl) ar1 ++ concatMap (replicate (2^tl)) ar2
55+
in ops !! (n - tl)
56+
termsL = termsLength (map length [ar0, ar1, ar2])
57+
58+
-- |Returns the number of unique trees w/ given operators and constants of a specific depth
59+
--
60+
-- >>> treesLevelCount [2, 3, 4] 3
61+
-- 16038022
62+
--
63+
-- returns the number of unique trees of depth 3
64+
-- build from a set of
65+
-- - 2 constants
66+
-- - 3 1-arity functions
67+
-- - 4 2-arity functions
68+
treesLevelCount :: [Int] -> Int -> Int
69+
treesLevelCount ns 0 = head ns
70+
treesLevelCount ns d =
71+
let n_1 = treesLevelCount ns (d - 1)
72+
in sum $ zipWith (\nn idx -> nn * n_1^idx) (tail ns) [1..]
73+
74+
-- |Returns the number of unique terms for a tree at position *n* in a lazy tree list
75+
-- example:
76+
--
77+
-- >>> termsLength [2,1,1] 10
78+
-- 8
79+
--
80+
-- returns the number of terms for a depth 3 (from n == 10) tree build upon
81+
-- - 2 constants
82+
-- - 1 1-arity function
83+
-- - 1 2-arity function
84+
termsLength :: [Int] -> Int -> Int
85+
termsLength ns n
86+
| n < head ns = head ns
87+
| otherwise = last $ takeWhile (<=n) $ scanl1 (+) $ map (treesLevelCount ns) [0..]
88+
89+
evalTree = foldTree f where
90+
f (Op0 a) _ = a
91+
f (Op1 "-" _) xs = negate $ head xs
92+
f (Op2 "+" _) xs = sum xs
93+
94+
main = do
95+
let ops = [Op0 1, Op0 2, Op1 "-" negate, Op2 "+" (+)] :: [Op Int]
96+
let ts = map (trees ops) [0..]
97+
let vs = map (\t -> (t, evalTree t)) ts
98+
print $ levels $ fst $ head $ dropWhile ((/= -4) . snd) vs
99+
-- main = print $ (treesLevelCount [2, 3, 4]) 3
100+
-- main = print $ zip [0..20] $ map (termsLength [2, 1, 1]) [0..20]

0 commit comments

Comments
 (0)