Skip to content

Commit 001c13f

Browse files
committed
Possible definition which would require eta-conversion in the type checker
1 parent 6c52c8d commit 001c13f

File tree

6 files changed

+130
-47
lines changed

6 files changed

+130
-47
lines changed

.vscode/tasks.json

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
2+
{
3+
// Automatically created by phoityne-vscode extension.
4+
5+
"version": "2.0.0",
6+
"presentation": {
7+
"reveal": "always",
8+
"panel": "new"
9+
},
10+
"tasks": [
11+
{
12+
// F7
13+
"group": {
14+
"kind": "build",
15+
"isDefault": true
16+
},
17+
"label": "haskell build",
18+
"type": "shell",
19+
//"command": "cabal configure && cabal build"
20+
"command": "stack build"
21+
},
22+
{
23+
// F6
24+
"group": "build",
25+
"type": "shell",
26+
"label": "haskell clean & build",
27+
//"command": "cabal clean && cabal configure && cabal build"
28+
"command": "stack clean && stack build"
29+
//"command": "stack clean ; stack build" // for powershell
30+
},
31+
{
32+
// F8
33+
"group": {
34+
"kind": "test",
35+
"isDefault": true
36+
},
37+
"type": "shell",
38+
"label": "haskell test",
39+
//"command": "cabal test"
40+
"command": "stack test"
41+
},
42+
{
43+
// F6
44+
"isBackground": true,
45+
"type": "shell",
46+
"label": "haskell watch",
47+
"command": "stack build --test --no-run-tests --file-watch"
48+
}
49+
]
50+
}

app/Agda/Core/ToCore.hs

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,24 @@ import System.IO (withBinaryFile)
4747
import Agda.Compiler.Backend (Definition(defType))
4848
import Control.Exception (throw)
4949

50-
import Debug.Trace
5150
import Agda.TypeChecking.Pretty (PrettyTCM(prettyTCM))
5251

52+
import Agda.Syntax.Common.Pretty(text, render)
53+
54+
import Debug.Trace
55+
56+
-- Helper to add color
57+
traceColor :: String -> String -> a -> a
58+
traceColor color msg = trace (color ++ msg ++ "\x1b[0m")
59+
60+
traceRed, traceGreen, traceYellow, traceBlue, traceMagenta, traceCyan :: String -> a -> a
61+
traceRed = traceColor "\x1b[31m"
62+
traceGreen = traceColor "\x1b[32m"
63+
traceYellow = traceColor "\x1b[33m"
64+
traceBlue = traceColor "\x1b[34m"
65+
traceMagenta = traceColor "\x1b[35m"
66+
traceCyan = traceColor "\x1b[36m"
67+
5368

5469
-- TODO(flupe): move this to Agda.Core.Syntax
5570
-- | Apply a core term to elims
@@ -136,8 +151,6 @@ instance ToCore I.Term where
136151

137152
-- TODO(flupe): add literals once they're added to core
138153
toCore (I.Lit l) = throwError "literals not supported"
139-
140-
-- (diode-lang) Seems like a bug: lookUpDefOrData can return data, but a `TDef` is always constructed
141154

142155
toCore (I.Def qn es) = do
143156
coreEs <- toCore es
@@ -156,19 +169,20 @@ instance ToCore I.Term where
156169
return (tApp dataRef coreEs)
157170
)
158171

159-
toCore (I.Con ch ci es)
172+
toCore (I.Con ch _ es)
160173
| Just args <- allApplyElims es
161174
= do
162175
-- @l@ is the amount of arguments missing from the application.
163176
-- we need to eta-expand manually @l@ times to fully-apply the constructor.
164177
let l = length (I.conFields ch) - length es
165-
let vs = reverse $ take l $ TVar <$> iterate Scope.inThere Scope.inHere
178+
-- Construct @l@ additional deBruijn indices
179+
let additionalVars = reverse $ take l $ TVar <$> iterate Scope.inThere Scope.inHere
166180
(dt , con) <- lookupCon (I.conName ch)
167181

168-
t <- TCon dt con . toTermS . (++ vs) <$> toCore (raise l args)
182+
t <- TCon dt con . toTermS . (++ additionalVars) <$> toCore (raise l args)
169183

170-
-- in the end, we bind @l@ fresh variables
171-
pure (iterate TLam t !! l)
184+
-- in the end, we bind @l@ fresh deBruijn indices
185+
traceMagenta "Constructed TLam" pure (iterate TLam t !! l)
172186

173187
toCore I.Con{} = throwError "cubical endpoint application to constructors not supported"
174188

@@ -248,15 +262,15 @@ toCoreDefn (I.FunctionDefn def) _ =
248262
, [cl] <- _funClauses
249263
, [] <- I.clausePats cl
250264
, Just body <- I.clauseBody cl
251-
-> Core.FunctionDefn <$> toCore body
265+
-> Core.FunctionDefn <$> traceMagenta ("calling toCore with body=" <> (render $ pretty body)) toCore body
252266
-- case with no pattern matching
253267
I.FunctionData{..}
254268
| isNothing (maybeRight _funProjection >>= I.projProper) -- discard record projections
255269
, [cl] <- _funClauses
256270
, vars <- I.clausePats cl
257271
, Just body <- I.clauseBody cl
258272
-- -> Core.FunctionDefn <$> toCore body
259-
-> trace ("matched on I.FunctionData with vars=" <> (show (I.clausePats cl))) (throwError "only definitions via λ are supported")
273+
-> (throwError "only definitions via λ are supported")
260274

261275
-- case with pattern matching variables
262276
I.FunctionData{..}
@@ -336,6 +350,7 @@ instance ToCore I.Definition where
336350
-- Others
337351
instance (Subst a, ToCore a) => ToCore (I.Abs a) where
338352
type CoreOf (I.Abs a) = CoreOf a
353+
toCore :: (Subst a, ToCore a) => I.Abs a -> ToCoreM (CoreOf (I.Abs a))
339354
toCore = toCore . absBody
340355

341356

app/Main.hs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -224,9 +224,10 @@ agdaCoreCompile env _ _ def = do
224224
liftIO $ writeIORef ioNames nnames
225225
liftIO $ writeIORef ioIndex (Suc index)
226226

227+
defTypeDoc <- prettyTCM defType
227228
reportSDoc "agda-core.check" 4 $ text " Agda type: " <> prettyTCM defType
228229
reportSDoc "agda-core.check" 5 $ text " Agda definition: " <> text (show $ Pretty.pretty theDef)
229-
230+
-- reportSDoc "agda-core.check" 5 $ text " Agda definition: " <> text (show theDef)
230231

231232

232233
case convert ntcg def of
@@ -237,8 +238,8 @@ agdaCoreCompile env _ _ def = do
237238
return $ throwError name
238239
Right def'-> do
239240
let Core.Definition{defType = ty', theDef = defn'} = def'
240-
reportSDoc "agda-core.check" 4 $ text $ " Type: " <> prettyCore nnames ty'
241-
reportSDoc "agda-core.check" 4 $ text $ " Definition: " <> prettyCore nnames defn'
241+
reportSDoc "agda-core.check" 4 $ text $ " Agda Core Type: " <> prettyCore nnames ty'
242+
reportSDoc "agda-core.check" 4 $ text $ " Agda Core Definition: " <> prettyCore nnames defn'
242243

243244
reportSDoc "agda-core.debug" 10 $ text ("Index of definition being translated: " <> show (indexToNat index))
244245
reportSDoc "agda-core.debug" 10 $ text ""
@@ -309,8 +310,6 @@ agdaCorePostModule ACEnv{toCorePreSignature = ioPreSig} nameMap _ tlm defs = do
309310
Left n -> reportSDocFailure "agda-core.check" $ text $ "Skiped " <> n <> " : term not compiled"
310311
Right Core.Definition{ defName, theDef = Core.FunctionDefn funBody, defType } -> do
311312
reportSDoc "agda-core.check" 2 $ text $ "Typechecking of " <> defName <> " :"
312-
reportSDoc "agda-core.check" 10 $ text $ defName <> " has funBody: " <> show funBody
313-
reportSDoc "agda-core.check" 10 $ text $ defName <> " has defType: " <> show defType <> "\n"
314313
preSig <- liftIO $ readIORef ioPreSig
315314
let sig = preSignatureToSignature preSig
316315
let fl = Core.More fl

test/EtaFunctions.agda

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,22 +15,22 @@ data Nat : Set where
1515
comp : (A B C : Set) (B C) (A B) A C
1616
comp = λ (A B C : Set) λ f λ g λ x f (g x)
1717

18+
const : Nat Nat Nat
19+
const = λ x λ y x
20+
1821
addOne : Nat -> Nat
19-
addOne = λ x suc x
22+
addOne = suc
2023

2124
addTwo : Nat Nat
2225
addTwo = λ x (suc (suc x))
2326

2427
addTwoAfterAddOne : Nat Nat
2528
addTwoAfterAddOne = λ x (comp Nat Nat Nat addTwo addOne x)
2629

27-
28-
2930
eta-higher : (A B C : Set) (f : A B C) (λ x λ y f x y) ≡ f
3031
eta-higher = λ A B C λ f refl
3132

32-
-- In this case, the type which Agda infers is addTwoAfterAddOne ≡ comp Nat Nat Nat addTwo addOne
33-
-- So the agda-core typechecker would expand `addTwoAfterAddOne`, which expands to λ x → (comp Nat Nat Nat addTwo addOne x)
34-
-- and the remaining equation would need to be solved by either eta-reduction or eta-expansion
35-
eta-counterexample : addTwoAfterAddOne ≡ (λ x (comp Nat Nat Nat addTwo addOne) x)
36-
eta-counterexample = refl
33+
34+
eta-counterexample-simple : addOne ≡ (λ x (suc (const x x)))
35+
eta-counterexample-simple = refl
36+

test/EtaFunctionsChurch.agda

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,60 @@
11
module EtaFunctionsChurch where
22

3-
data Bool : Set where
4-
true : Bool
5-
false : Bool
3+
-- data Bool : Set where
4+
-- true : Bool
5+
-- false : Bool
66

77
data Nat : Set where
88
zero : Nat
99
suc : Nat Nat
1010

11-
11+
-- an x of type A is equal to another element of type A,
12+
-- if, for all predicates `P : A → Set`, if `P x` holds then `P y` also holds
13+
-- The result of an `Id A x x` is a `Set₁`, because we are quantifying over all `Set`'s
1214
Id : (A : Set) (x : A) A Set₁
1315
Id = λ A x y (P : A Set) P x P y
1416

1517
refl : (A : Set) (x : A) Id A x x
1618
refl = λ A x P p p
1719

18-
idbool : Bool Bool
19-
idbool = λ b b
20+
-- idbool : Bool → Bool
21+
-- idbool = λ b → b
2022

21-
-- Composition operator ∘
22-
comp : (A B C : Set) (B C) (A B) A C
23-
comp = λ (A B C : Set) λ f λ g λ x f (g x)
23+
const : Nat Nat Nat
24+
const = λ x λ y x
2425

25-
addOne : Nat -> Nat
26-
addOne = λ x suc x
26+
addOne : Nat Nat
27+
addOne = suc
2728

28-
addTwo : Nat Nat
29-
addTwo = λ x (suc (suc x))
29+
-- Composition operator ∘
30+
-- comp : (A B C : Set) → (B → C) → (A → B) → A → C
31+
-- comp = λ (A B C : Set) → λ f → λ g → λ x → f (g x)
3032

31-
addTwoAfterAddOne : Nat Nat
32-
addTwoAfterAddOne = λ x (comp Nat Nat Nat addTwo addOne x)
33+
-- addTwo : Nat → Nat
34+
-- addTwo = λ x → (suc (suc x))
3335

34-
eta-functions_expl : (A B : Set) (f : A B) (Id (A B) f (λ x f x))
35-
eta-functions_expl = λ A B λ f refl (A B) f
36+
-- addTwoAfterAddOne : Nat → Nat
37+
-- addTwoAfterAddOne = λ x → (comp Nat Nat Nat addTwo addOne x)
3638

37-
eta-functions_two : (A B C : Set) (f : B C) (g : A B) (Id (A C) (comp A B C f g) (λ x (comp A B C f g) x))
38-
eta-functions_two = λ A B C λ f λ g refl (A C) (comp A B C f g)
39+
-- eta-functions_expl : (A B : Set) (f : A → B) → (Id (A → B) f (λ x → f x))
40+
-- eta-functions_expl = λ A B → λ f → refl (A → B) f
41+
42+
-- eta-functions_two : (A B C : Set) (f : B → C) → (g : A → B) → (Id (A → C) (comp A B C f g) (λ x → (comp A B C f g) x))
43+
-- eta-functions_two = λ A B C → λ f → λ g → refl (A → C) (comp A B C f g)
3944

4045
-- apply : (A B : Set) → (A → B) → A → B
4146
-- apply = λ A B → λ f → λ x → f x
4247

4348
-- eta-apply : (A B : Set) → (f : A → B) → Id (apply f) f
4449

50+
eta-functions_expl : (A B : Set) (f : A B) (Id (A B) f (λ x f x))
51+
eta-functions_expl = λ A B λ f refl (A B) f
4552

46-
eta-counterexample : Id (Nat Nat) addTwoAfterAddOne (λ x (comp Nat Nat Nat addTwo addOne) x)
47-
eta-counterexample = refl (Nat Nat) addTwoAfterAddOne
48-
53+
-- eta-counterexample : Id (Nat → Nat) addTwoAfterAddOne (λ x → (comp Nat Nat Nat addTwo addOne) x)
54+
-- eta-counterexample = refl (Nat → Nat) addTwoAfterAddOne
4955

50-
eta-counterexample-simple : Id (Nat Nat) addOne (λ y (λ x (suc x)) y)
56+
eta-counterexample-simple : Id (Nat Nat) addOne (λ x suc (const x x))
5157
eta-counterexample-simple = refl (Nat Nat) addOne
5258

53-
5459
-- eta-higher : (A B C : Set) → (f : A → B → C) → Id (λ x → λ y → f x y) f
5560
-- eta-higher = λ A B C → λ f → refl
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
Id : (A : Set) (x : A) A Set₁
2+
Id = λ A x y (P : A Set) P x P y
3+
4+
refl : (A : Set) (x : A) Id A x x
5+
refl = λ A x P p p
6+
7+
const : (A : Set) A A A
8+
const = λ A λ x λ y x
9+
10+
eta-functions_expl : (A B : Set) (f : A B) (Id (A B) f (λ x (f (const A x x))))
11+
eta-functions_expl = λ A B λ f refl (A B) f
12+
13+
14+

0 commit comments

Comments
 (0)