-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathSearchTest.hs
155 lines (135 loc) · 4.75 KB
/
SearchTest.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
{-# LANGUAGE RecordWildCards, NamedFieldPuns #-}
module SearchTest where
import qualified Data.Set as S
import Data.Maybe
import qualified Data.Map as M
import qualified Data.PSQueue as P
type Program = String
type EdgeName = Program -> Program -- String
type Name = Char
type Vertex = ([Name], [Name])
data Trans = Trans { from :: [Name], to :: [Name], transName :: String }
allNames = "LMTNG"
isTraversable = (`elem` "LMN")
isApplicative = (`elem` "LMTG")
transes :: [Trans]
transes =
[ Trans { from = "LM", to = "L", transName = "catMaybes"}
, Trans { from = "", to = "L", transName = "\\x -> map (const x) ?" }
, Trans { from = "LL", to = "L", transName = "concat" }
, Trans { from = "T", to = "G", transName = "inHoleEnv" }
, Trans { from = "", to = "N", transName = "\\x -> (?, x)" }
]
type ListView a = (Int, [a], [a])
rewrite :: Trans -> ListView String -> Maybe (String, EdgeName)
rewrite (Trans {from, to, transName}) (pre, s) =
case leftFromRight from s of
Just cs -> (Just (reverse pre ++ cs), \p -> transName ++ " . " p)
Nothing -> Nothing
successors' :: Vertex -> [(Vertex, EdgeName)]
successors' (s, t) = _
-- naive algorithm for now
listViews :: [a] -> [ListView a]
listViews = go [] where
go pre l@(x:xs) = (pre, l) : listViews (x:pre) xs
go pre [] = [(pre, [])]
-- Really should do something special when they're equal.
successors :: Vertex -> [(Vertex, EdgeName)]
successors (s, t) =
fmapEdge ++ sequenceREdge ++ sequenceLEdge ++ transEdges
where
fmapEdge
| (cs:s', ct:t') <- (s, t), cs == ct
= [((s', t'), \p -> "fmap{" ++ [cs] ++ "}" ++ "(" ++ p ++ ")")]
| otherwise = []
sequenceREdge
| ctf:ctt:t' <- t
, isApplicative ctf && isTraversable ctt
= [((s, ctt:ctf:t'), \p -> "sequenceA . " ++ p)] -- "sequence-right")]
| otherwise = []
sequenceLEdge
| cst:csf:s' <- s
, isTraversable cst && isApplicative csf
= [((csf:cst:s', t), \p -> p ++ ". sequenceA")] -- "sequence-left")]
| otherwise = []
transEdges =
concatMap (\(Trans{..}) ->
let rrule =
case leftFromRight to t of
Just t' -> [((s, from ++ t'), \p -> transName ++ " . " ++ p)] -- transName ++ "-right")]
Nothing -> []
lrule =
case leftFromRight from s of
Just s' -> [((to ++ s', t), \p -> p ++ " . " ++ transName)] -- transName ++ "-left")]
Nothing -> []
in
rrule ++ lrule)
transes
leftFromRight :: Eq a => [a] -> [a] -> Maybe [a]
leftFromRight (x : xs) [] = Nothing
leftFromRight (x : xs) (y : ys)
| x == y = leftFromRight xs ys
| otherwise = Nothing
leftFromRight [] ys = Just ys
dijkstra
:: Vertex -> M.Map Vertex (Int, (Vertex, EdgeName))
dijkstra init =
let nexts = successors init
in
go M.empty
(M.fromList . map (\(v, en) -> (v, (init, en))) $ nexts)
(P.fromList . map (\(v, _) -> v P.:-> 1) $ nexts)
where
maxDist = 8
go visited onDeckPreds onDeckDists =
case P.minView onDeckDists of
Just (u P.:-> dist, onDeckDists') ->
let visited' =
M.insert u (dist, fromJust $ M.lookup u onDeckPreds) visited
nexts =
if dist >= maxDist
then []
else if let (s, t) = u in length s > 5 || length t > 5
then []
else
filter (\(v, _) -> not (M.member v visited'))
$ successors u
(onDeckPreds', onDeckDists'') =
foldl (\(ps, ds) (v, en) ->
let ds' = P.insertWith min v (dist + 1) ds
ps' =
if P.lookup v ds' == Just (dist + 1)
then M.insert v (u,en) ps
else ps
in (ps', ds'))
(onDeckPreds, onDeckDists') nexts
in
go visited' onDeckPreds' onDeckDists''
Nothing -> visited -- visited
prove :: Vertex -> Program
prove init = go "id" ("", "") where
d = dijkstra init
go acc v =
case M.lookup v d of
Just (_, (pre, en)) -> go (en acc) pre
Nothing -> acc
-- for prove ("TM", "GLN"), got
-- inHoleEnv . fmap{T}(catMaybes . \x -> map (const x) ? . fmap{M}(\x -> (?, x) . id))
-- wanted
-- fmap catMaybes
-- . sequenceA
-- . (\x -> map (fmap (fmap (cmap ?)) . inHoleEnv . const x) ?)
-- ==
-- fmap catMaybes
-- . sequenceA
-- . (\x -> map (\_ -> fmap (fmap (cmap ?)) (inHoleEnv x)) ?)
--
-- or possibly
-- inHoleEnv . fmap catMaybes . sequenceA . map (\x -> map (\_ -> (fmap (fmap (\y -> (?,y)))) x) ?)
-- ==
-- inHoleEnv . fmap catMaybes . sequenceA . (\x -> map (fmap (fmap (\y -> (?, y))) . const x) ?)
--
-- want cmaps close to the seed data (so that the data can depend on some
-- stuff)
--
--TODO: heuristic: never permit > 2 of the same letter in a row