Skip to content

Commit 621a04d

Browse files
authored
Merge pull request #26 from isovector/tracing
Tactic tracing
2 parents 3272a1e + 8a416d9 commit 621a04d

File tree

7 files changed

+121
-48
lines changed

7 files changed

+121
-48
lines changed

plugins/tactics/src/Ide/Plugin/Tactic.hs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,6 @@ judgementForHole state nfp range = do
258258

259259
resulting_range <- liftMaybe $ toCurrentRange amapping $ realSrcSpanToRange rss
260260
(tcmod, _) <- MaybeT $ runIde state $ useWithStale TypeCheck nfp
261-
-- traceMX "holes!" $ isRhsHole rss $
262261
let tcg = fst $ tm_internals_ $ tmrModule tcmod
263262
tcs = tm_typechecked_source $ tmrModule tcmod
264263
ctx = mkContext
@@ -297,9 +296,10 @@ tacticCmd tac lf state (TacticParams uri range var_name)
297296
pure $ (, Nothing)
298297
$ Left
299298
$ ResponseError InvalidRequest (T.pack $ show err) Nothing
300-
Right res -> do
301-
let g = graft (RealSrcSpan span) res
299+
Right (tr, ext) -> do
300+
let g = graft (RealSrcSpan span) ext
302301
response = transform dflags (clientCapabilities lf) uri g pm
302+
traceMX "trace" tr
303303
pure $ case response of
304304
Right res -> (Right Null , Just (WorkspaceApplyEdit, ApplyWorkspaceEditParams res))
305305
Left err -> (Left $ ResponseError InternalError (T.pack err) Nothing, Nothing)

plugins/tactics/src/Ide/Plugin/Tactic/Auto.hs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import Ide.Plugin.Tactic.KnownStrategies
66
import Ide.Plugin.Tactic.Tactics
77
import Ide.Plugin.Tactic.Types
88
import Refinery.Tactic
9+
import Ide.Plugin.Tactic.Machinery (tracing)
910

1011

1112
------------------------------------------------------------------------------
@@ -15,7 +16,9 @@ auto = do
1516
jdg <- goal
1617
current <- getCurrentDefinitions
1718
traceMX "goal" jdg
18-
commit
19-
knownStrategies
20-
(localTactic (auto' 4) $ disallowing $ fmap fst current)
19+
commit knownStrategies
20+
. tracing "auto"
21+
. localTactic (auto' 4)
22+
. disallowing
23+
$ fmap fst current
2124

plugins/tactics/src/Ide/Plugin/Tactic/CodeGen.hs

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
{-# LANGUAGE TupleSections #-}
12
{-# LANGUAGE FlexibleContexts #-}
23
module Ide.Plugin.Tactic.CodeGen where
34

@@ -38,7 +39,7 @@ destructMatches
3839
-> CType
3940
-- ^ Type being destructed
4041
-> Judgement
41-
-> RuleM [RawMatch]
42+
-> RuleM (Trace, [RawMatch])
4243
destructMatches f f2 t jdg = do
4344
let hy = jHypothesis jdg
4445
g = jGoal jdg
@@ -48,7 +49,7 @@ destructMatches f f2 t jdg = do
4849
let dcs = tyConDataCons tc
4950
case dcs of
5051
[] -> throwError $ GoalMismatch "destruct" g
51-
_ -> for dcs $ \dc -> do
52+
_ -> fmap unzipTrace $ for dcs $ \dc -> do
5253
let args = dataConInstArgTys dc apps
5354
names <- mkManyGoodNames hy args
5455
let hy' = zip names $ coerce args
@@ -61,9 +62,19 @@ destructMatches f f2 t jdg = do
6162
$ withPositionMapping dcon_name names
6263
$ introducingPat hy'
6364
$ withNewGoal g jdg
64-
sg <- f dc j
65+
(tr, sg) <- f dc j
6566
modify $ withIntroducedVals $ mappend $ S.fromList names
66-
pure $ match [pat] $ unLoc sg
67+
pure ( rose ("match " <> show dc <> " {" <>
68+
intercalate ", " (fmap show names) <> "}")
69+
$ pure tr
70+
, match [pat] $ unLoc sg
71+
)
72+
73+
74+
unzipTrace :: [(Trace, a)] -> (Trace, [a])
75+
unzipTrace l =
76+
let (trs, as) = unzip l
77+
in (rose mempty trs, as)
6778

6879

6980
------------------------------------------------------------------------------
@@ -77,12 +88,15 @@ destruct' f term jdg = do
7788
Nothing -> throwError $ UndefinedHypothesis term
7889
Just (_, t) -> do
7990
useOccName jdg term
80-
fmap noLoc $ case' (var' term) <$>
81-
destructMatches
82-
f
83-
(\cs -> setParents term (fmap fst cs) . destructing term)
84-
t
85-
jdg
91+
(tr, ms)
92+
<- destructMatches
93+
f
94+
(\cs -> setParents term (fmap fst cs) . destructing term)
95+
t
96+
jdg
97+
pure ( rose ("destruct " <> show term) $ pure tr
98+
, noLoc $ case' (var' term) ms
99+
)
86100

87101

88102
------------------------------------------------------------------------------
@@ -94,7 +108,7 @@ destructLambdaCase' f jdg = do
94108
let g = jGoal jdg
95109
case splitFunTy_maybe (unCType g) of
96110
Just (arg, _) | isAlgType arg ->
97-
fmap noLoc $ lambdaCase <$>
111+
fmap (fmap noLoc $ lambdaCase) <$>
98112
destructMatches f (const id) (CType arg) jdg
99113
_ -> throwError $ GoalMismatch "destructLambdaCase'" g
100114

@@ -105,18 +119,21 @@ buildDataCon
105119
:: Judgement
106120
-> DataCon -- ^ The data con to build
107121
-> [Type] -- ^ Type arguments for the data con
108-
-> RuleM (LHsExpr GhcPs)
122+
-> RuleM (Trace, LHsExpr GhcPs)
109123
buildDataCon jdg dc apps = do
110124
let args = dataConInstArgTys dc apps
111125
dcon_name = nameOccName $ dataConName dc
112-
sgs <- traverse ( \(arg, n) ->
126+
(tr, sgs)
127+
<- fmap unzipTrace
128+
$ traverse ( \(arg, n) ->
113129
newSubgoal
114130
. filterSameTypeFromOtherPositions dcon_name n
115131
. blacklistingDestruct
116132
. flip withNewGoal jdg
117133
$ CType arg
118134
) $ zip args [0..]
119135
pure
136+
. (rose (show dc) $ pure tr,)
120137
. noLoc
121138
. foldl' (@@)
122139
(HsVar noExtField $ noLoc $ Unqual $ nameOccName $ dataConName dc)
@@ -128,6 +145,7 @@ buildDataCon jdg dc apps = do
128145
var' :: Var a => OccName -> a
129146
var' = var . fromString . occNameString
130147

148+
131149
------------------------------------------------------------------------------
132150
-- | Like 'bvar', but works over standard GHC 'OccName's.
133151
bvar' :: BVar a => OccName -> a

plugins/tactics/src/Ide/Plugin/Tactic/KnownStrategies.hs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import Ide.Plugin.Tactic.Tactics
88
import Ide.Plugin.Tactic.Types
99
import OccName (mkVarOcc)
1010
import Refinery.Tactic
11+
import Ide.Plugin.Tactic.Machinery (tracing)
1112

1213

1314
knownStrategies :: TacticsM ()
@@ -19,9 +20,8 @@ knownStrategies = choice
1920
known :: String -> TacticsM () -> TacticsM ()
2021
known name t = do
2122
getCurrentDefinitions >>= \case
22-
[(def, _)] | def == mkVarOcc name -> do
23-
traceMX "running known strategy" name
24-
t
23+
[(def, _)] | def == mkVarOcc name ->
24+
tracing ("known " <> name) t
2525
_ -> throwError NoApplicableTactic
2626

2727

plugins/tactics/src/Ide/Plugin/Tactic/Machinery.hs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ import Refinery.Tactic.Internal
3636
import TcType
3737
import Type
3838
import Unify
39+
import Control.Arrow
40+
import Control.Monad.State.Strict (StateT (..))
3941

4042

4143
substCTy :: TCvSubst -> CType -> CType
@@ -47,7 +49,7 @@ substCTy subst = coerce . substTy subst . coerce
4749
-- goal.
4850
newSubgoal
4951
:: Judgement
50-
-> RuleM (LHsExpr GhcPs)
52+
-> Rule
5153
newSubgoal j = do
5254
unifier <- gets ts_unifier
5355
subgoal
@@ -62,7 +64,7 @@ runTactic
6264
:: Context
6365
-> Judgement
6466
-> TacticsM () -- ^ Tactic to use
65-
-> Either [TacticError] (LHsExpr GhcPs)
67+
-> Either [TacticError] (Trace, LHsExpr GhcPs)
6668
runTactic ctx jdg t =
6769
let skolems = tyCoVarsOfTypeWellScoped $ unCType $ jGoal jdg
6870
tacticState = defaultTacticState { ts_skolems = skolems }
@@ -81,6 +83,20 @@ runTactic ctx jdg t =
8183
_ -> Left []
8284

8385

86+
tracePrim :: String -> Trace
87+
tracePrim = flip rose []
88+
89+
90+
tracing
91+
:: Functor m
92+
=> String
93+
-> TacticT jdg (Trace, ext) err s m a
94+
-> TacticT jdg (Trace, ext) err s m a
95+
tracing s (TacticT m)
96+
= TacticT $ StateT $ \jdg ->
97+
mapExtract' (first $ rose s . pure) $ runStateT m jdg
98+
99+
84100
recursiveCleanup
85101
:: TacticState
86102
-> Maybe TacticError

plugins/tactics/src/Ide/Plugin/Tactic/Tactics.hs

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
{-# LANGUAGE TupleSections #-}
12
{-# LANGUAGE DataKinds #-}
23
{-# LANGUAGE TypeApplications #-}
34
{-# LANGUAGE DeriveGeneric #-}
@@ -17,6 +18,7 @@ import Control.Monad.Except (throwError)
1718
import Control.Monad.Reader.Class (MonadReader(ask))
1819
import Control.Monad.State.Class
1920
import Control.Monad.State.Strict (StateT(..), runStateT)
21+
import Data.Bool (bool)
2022
import Data.List
2123
import qualified Data.Map as M
2224
import Data.Maybe
@@ -33,12 +35,11 @@ import Ide.Plugin.Tactic.Judgements
3335
import Ide.Plugin.Tactic.Machinery
3436
import Ide.Plugin.Tactic.Naming
3537
import Ide.Plugin.Tactic.Types
36-
import Name (nameOccName)
38+
import Name (occNameString)
3739
import Refinery.Tactic
3840
import Refinery.Tactic.Internal
3941
import TcType
4042
import Type hiding (Var)
41-
import Data.Bool (bool)
4243

4344

4445
------------------------------------------------------------------------------
@@ -60,14 +61,14 @@ assume name = rule $ \jdg -> do
6061
True -> setRecursionFrameData True
6162
False -> pure ()
6263
useOccName jdg name
63-
pure $ noLoc $ var' name
64+
pure $ (tracePrim $ "assume " <> occNameString name, ) $ noLoc $ var' name
6465
False -> throwError $ GoalMismatch "assume" g
6566
Nothing -> throwError $ UndefinedHypothesis name
6667

6768

6869

6970
recursion :: TacticsM ()
70-
recursion = do
71+
recursion = tracing "recursion" $ do
7172
defs <- getCurrentDefinitions
7273
attemptOn (const $ fmap fst defs) $ \name -> do
7374
modify $ withRecursionStack (False :)
@@ -90,14 +91,16 @@ intros = rule $ \jdg -> do
9091
let jdg' = introducing (zip vs $ coerce as)
9192
$ withNewGoal (CType b) jdg
9293
modify $ withIntroducedVals $ mappend $ S.fromList vs
93-
sg <- newSubgoal
94+
(tr, sg)
95+
<- newSubgoal
9496
$ bool
9597
id
9698
(withPositionMapping
9799
(extremelyStupid__definingFunction ctx) vs)
98100
(isTopHole jdg)
99101
$ jdg'
100102
pure
103+
. (rose ("intros {" <> intercalate ", " (fmap show vs) <> "}") $ pure tr, )
101104
. noLoc
102105
. lambda (fmap bvar' vs)
103106
$ unLoc sg
@@ -106,7 +109,7 @@ intros = rule $ \jdg -> do
106109
------------------------------------------------------------------------------
107110
-- | Case split, and leave holes in the matches.
108111
destructAuto :: OccName -> TacticsM ()
109-
destructAuto name = do
112+
destructAuto name = tracing "destruct(auto)" $ do
110113
jdg <- goal
111114
case hasDestructed jdg name of
112115
True -> throwError $ AlreadyDestructed name
@@ -126,7 +129,7 @@ destructAuto name = do
126129
------------------------------------------------------------------------------
127130
-- | Case split, and leave holes in the matches.
128131
destruct :: OccName -> TacticsM ()
129-
destruct name = do
132+
destruct name = tracing "destruct(user)" $ do
130133
jdg <- goal
131134
case hasDestructed jdg name of
132135
True -> throwError $ AlreadyDestructed name
@@ -136,20 +139,20 @@ destruct name = do
136139
------------------------------------------------------------------------------
137140
-- | Case split, using the same data constructor in the matches.
138141
homo :: OccName -> TacticsM ()
139-
homo = rule . destruct' (\dc jdg ->
142+
homo = tracing "homo" . rule . destruct' (\dc jdg ->
140143
buildDataCon jdg dc $ snd $ splitAppTys $ unCType $ jGoal jdg)
141144

142145

143146
------------------------------------------------------------------------------
144147
-- | LambdaCase split, and leave holes in the matches.
145148
destructLambdaCase :: TacticsM ()
146-
destructLambdaCase = rule $ destructLambdaCase' (const subgoal)
149+
destructLambdaCase = tracing "destructLambdaCase" $ rule $ destructLambdaCase' (const subgoal)
147150

148151

149152
------------------------------------------------------------------------------
150153
-- | LambdaCase split, using the same data constructor in the matches.
151154
homoLambdaCase :: TacticsM ()
152-
homoLambdaCase = rule $ destructLambdaCase' (\dc jdg ->
155+
homoLambdaCase = tracing "homoLambdaCase" $ rule $ destructLambdaCase' (\dc jdg ->
153156
buildDataCon jdg dc $ snd $ splitAppTys $ unCType $ jGoal jdg)
154157

155158

@@ -158,7 +161,7 @@ apply = apply' (const id)
158161

159162

160163
apply' :: (Int -> Judgement -> Judgement) -> OccName -> TacticsM ()
161-
apply' f func = do
164+
apply' f func = tracing ("apply' " <> show func) $ do
162165
rule $ \jdg -> do
163166
let hy = jHypothesis jdg
164167
g = jGoal jdg
@@ -167,24 +170,28 @@ apply' f func = do
167170
let (args, ret) = splitFunTys ty
168171
unify g (CType ret)
169172
useOccName jdg func
170-
sgs <- traverse ( \(i, t) ->
173+
(tr, sgs)
174+
<- fmap unzipTrace
175+
$ traverse ( \(i, t) ->
171176
newSubgoal
172177
. f i
173178
. blacklistingDestruct
174179
. flip withNewGoal jdg
175180
$ CType t
176181
) $ zip [0..] args
177-
pure . noLoc
178-
. foldl' (@@) (var' func)
179-
$ fmap unLoc sgs
182+
pure
183+
. (tr, )
184+
. noLoc
185+
. foldl' (@@) (var' func)
186+
$ fmap unLoc sgs
180187
Nothing -> do
181188
throwError $ GoalMismatch "apply" g
182189

183190

184191
------------------------------------------------------------------------------
185192
-- | Choose between each of the goal's data constructors.
186193
split :: TacticsM ()
187-
split = do
194+
split = tracing "split(user)" $ do
188195
jdg <- goal
189196
let g = jGoal jdg
190197
case splitTyConApp_maybe $ unCType g of
@@ -196,7 +203,7 @@ split = do
196203
------------------------------------------------------------------------------
197204
-- | Choose between each of the goal's data constructors.
198205
splitAuto :: TacticsM ()
199-
splitAuto = do
206+
splitAuto = tracing "split(auto)" $ do
200207
jdg <- goal
201208
let g = jGoal jdg
202209
case splitTyConApp_maybe $ unCType g of
@@ -220,7 +227,7 @@ splitAuto = do
220227
------------------------------------------------------------------------------
221228
-- | Attempt to instantiate the given data constructor to solve the goal.
222229
splitDataCon :: DataCon -> TacticsM ()
223-
splitDataCon dc = rule $ \jdg -> do
230+
splitDataCon dc = tracing ("splitDataCon:" <> show dc) $ rule $ \jdg -> do
224231
let g = jGoal jdg
225232
case splitTyConApp_maybe $ unCType g of
226233
Just (tc, apps) -> do

0 commit comments

Comments
 (0)