open import 1Lab.Reflection
open import 1Lab.Path
open import 1Lab.Type
open import Data.Maybe.Base
open import Prim.Data.Nat
module 1Lab.Reflection.Marker where
⌜_⌝ : ∀ {ℓ} {A : Type ℓ} → A → A
⌜ x ⌝ = x
{-# NOINLINE ⌜_⌝ #-}
abstract-marker : Term → Maybe Term
abstract-marker = go 0 where
go : Nat → Term → Maybe Term
go* : Nat → List (Arg Term) → Maybe (List (Arg Term))
go k (var j args) = var j' <$> go* k args
where
j' : Nat
j' with j < k
... | false = suc j
... | true = j
go k (con c args) = con c <$> go* k args
go k (def f args) with f
... | quote ⌜_⌝ = pure (var k [])
... | x = def f <$> go* k args
go k (lam v (abs x t)) = lam v ∘ abs x <$> go (suc k) t
go k (pat-lam cs args) = nothing
go k (pi (arg i a) (abs x t)) = do
t ← go (suc k) t
a ← go k a
pure (pi (arg i a) (abs x t))
go k (agda-sort s) with s
... | set t = agda-sort ∘ set <$> go k t
... | lit n = pure (agda-sort (lit n))
... | prop t = agda-sort ∘ prop <$> go k t
... | propLit n = pure (agda-sort (propLit n))
... | inf n = pure (agda-sort (inf n))
... | unknown = pure (agda-sort unknown)
go k (lit l) = pure (lit l)
go k (meta m args) = meta m <$> go* k args
go k unknown = pure unknown
go* k [] = pure []
go* k (arg i x ∷ xs) = do
x ← go k x
xs ← go* k xs
pure (arg i x ∷ xs)
private
record ap-data {ℓ} {A : Type ℓ} (x y : A) : Typeω where
no-eta-equality ; pattern ; constructor mkapdata
field
ℓ-mark : Level
mark : Type ℓ-mark
from : mark → x ≡ y
ap-worker : ∀ {ℓ} {A : Type ℓ} (x : A) → Term → TC ⊤
ap-worker x goal = withNormalisation false do
`x ← wait-for-type =<< quoteTC x
case abstract-marker `x of λ where
(just l) → do
debugPrint "1lab.marked-ap" 10
[ "original " , termErr `x , "\n"
, "abstracted" , termErr (lam visible (abs "x" l))
]
unify goal (con (quote mkapdata) (unknown v∷ unknown v∷ def (quote ap) (lam visible (abs "x" l) v∷ []) v∷ []))
nothing → typeError [ "Failed to abstract over marker in term" , termErr `x ]
open ap-data
ap!-wrapper : ∀ {ℓ} {A : Type ℓ} {x y : A} {@(tactic ap-worker x) it : ap-data x y} → it .mark → x ≡ y
ap!-wrapper {it = mkapdata _ _ f} = f
ap¡-wrapper : ∀ {ℓ} {A : Type ℓ} {x y : A} {@(tactic ap-worker y) it : ap-data x y} → it .mark → x ≡ y
ap¡-wrapper {it = mkapdata _ _ f} = f
macro
ap! : Term → TC ⊤
ap! g = unify g (def (quote ap!-wrapper) [])
ap¡ : Term → TC ⊤
ap¡ g = unify g (def (quote ap¡-wrapper) [])
module _ {ℓ} {A : Type ℓ} {x y : A} {p : x ≡ y} {f : A → (A → A) → A} where
private
q : f x (λ y → x) ≡ f y (λ z → y)
q =
f ⌜ x ⌝ (λ _ → ⌜ x ⌝) ≡⟨ ap! p ⟩
f y (λ _ → y) ∎
r : f y (λ _ → y) ≡ f x (λ _ → x)
r =
f ⌜ y ⌝ (λ _ → ⌜ y ⌝) ≡˘⟨ ap¡ p ⟩
f x (λ _ → x) ∎