{-# OPTIONS --without-K --safe #-} open import Algebra using (Monoid) module Data.FingerTree.MonoidSolver {ℓ₁ ℓ₂} (mon : Monoid ℓ₁ ℓ₂) where open import Data.Nat as ℕ using (ℕ; suc; zero) open import Data.List as List using (List; _∷_; []; foldr; _++_) open import Data.Vec as Vec using (Vec; _∷_; []) open import Data.Fin as Fin using (Fin) open import Data.String as String using (String) open import Data.Maybe as Maybe using (Maybe; just; nothing) open import Relation.Nullary using (Dec; yes; no) open import Data.Unit using (⊤; tt) open import Relation.Binary using (Setoid) open import Function open import Reflection open import Agda.Builtin.Reflection open Monoid mon data Expr : Set ℓ₁ where K : Carrier → Expr _⊕_ : Expr → Expr → Expr E : Expr ⟦_⟧ : Expr → Carrier ⟦ K x ⟧ = x ⟦ x ⊕ y ⟧ = ⟦ x ⟧ ∙ ⟦ y ⟧ ⟦ E ⟧ = ε Normal : Set ℓ₁ Normal = List Carrier norm : Expr → Normal norm (K x) = x ∷ [] norm (x ⊕ y) = norm x ++ norm y norm E = [] ⟦_,_⟧⁺⇓ : Carrier → Normal → Carrier ⟦ x , [] ⟧⁺⇓ = x ⟦ x₁ , x₂ ∷ xs ⟧⁺⇓ = x₁ ∙ ⟦ x₂ , xs ⟧⁺⇓ ⟦_⟧⇓ : Normal → Carrier ⟦ [] ⟧⇓ = ε ⟦ x ∷ xs ⟧⇓ = ⟦ x , xs ⟧⁺⇓ ++-homo : (xs ys : Normal) → ⟦ xs ++ ys ⟧⇓ ≈ ⟦ xs ⟧⇓ ∙ ⟦ ys ⟧⇓ ++-homo [] ys = sym (identityˡ ⟦ ys ⟧⇓) ++-homo (x ∷ xs) ys = go x xs ys where go : ∀ x xs ys → ⟦ x , xs ++ ys ⟧⁺⇓ ≈ ⟦ x , xs ⟧⁺⇓ ∙ ⟦ ys ⟧⇓ go x [] [] = sym (identityʳ x) go x [] (y ∷ ys) = refl go x₁ (x₂ ∷ xs) ys = ∙-cong refl (go x₂ xs ys) ⟨ trans ⟩ sym (assoc _ _ _) open import Data.FingerTree.Relation.Binary.Reasoning.FasterInference.Setoid setoid correct : (e : Expr) → ⟦ norm e ⟧⇓ ≈ ⟦ e ⟧ correct (K x) = refl correct (x ⊕ y) = ++-homo (norm x) (norm y) ⟨ trans ⟩ (correct x ⟨ ∙-cong ⟩ correct y ) correct E = refl infixr 5 _⟨∷⟩_ _⟅∷⟆_ pattern _⟨∷⟩_ x xs = arg (arg-info visible relevant) x ∷ xs pattern _⟅∷⟆_ x xs = arg (arg-info hidden relevant) x ∷ xs mutual E₂ : List (Arg Term) → Term E₂ (x ⟨∷⟩ y ⟨∷⟩ []) = quote _⊕_ ⟨ con ⟩ E′ x ⟨∷⟩ E′ y ⟨∷⟩ [] E₂ (x ∷ xs) = E₂ xs E₂ _ = unknown E′ : Term → Term E′ (def (quote Monoid._∙_) xs) = E₂ xs E′ (def (quote Monoid.ε) _) = quote E ⟨ con ⟩ [] E′ t = quote K ⟨ con ⟩ (t ⟨∷⟩ []) getVisible : Arg Term → Maybe Term getVisible (arg (arg-info visible relevant) x) = just x getVisible (arg (arg-info visible irrelevant) x) = nothing getVisible (arg (arg-info hidden r) x) = nothing getVisible (arg (arg-info instance′ r) x) = nothing getArgs : ∀ n → Term → Maybe (Vec Term n) getArgs n (def _ xs) = Maybe.map Vec.reverse (List.foldl f b (List.mapMaybe getVisible xs) n) where f : (∀ n → Maybe (Vec Term n)) → Term → ∀ n → Maybe (Vec Term n) f xs x zero = just Vec.[] f xs x (suc n) = Maybe.map (x Vec.∷_) (xs n) b : ∀ n → Maybe (Vec Term n) b zero = just Vec.[] b (suc _ ) = nothing getArgs _ _ = nothing infixr 5 _⋯⟅∷⟆_ _⋯⟅∷⟆_ : ℕ → List (Arg Term) → List (Arg Term) zero ⋯⟅∷⟆ xs = xs suc i ⋯⟅∷⟆ xs = unknown ⟅∷⟆ i ⋯⟅∷⟆ xs constructSoln : Term → Term → Term → Term constructSoln mon lhs rhs = quote Monoid.trans ⟨ def ⟩ 2 ⋯⟅∷⟆ mon ⟨∷⟩ (quote Monoid.sym ⟨ def ⟩ 2 ⋯⟅∷⟆ mon ⟨∷⟩ (quote correct ⟨ def ⟩ 2 ⋯⟅∷⟆ mon ⟨∷⟩ E′ lhs ⟨∷⟩ []) ⟨∷⟩ []) ⟨∷⟩ (quote correct ⟨ def ⟩ 2 ⋯⟅∷⟆ mon ⟨∷⟩ E′ rhs ⟨∷⟩ []) ⟨∷⟩ [] _>>=_ : ∀ {a b} {A : Set a} {B : Set b} → TC A → (A → TC B) → TC B _>>=_ = bindTC _>>_ : ∀ {a b} {A : Set a} {B : Set b} → TC A → TC B → TC B xs >> ys = xs >>= λ _ → ys solve-macro : Term → Term → TC ⊤ solve-macro mon hole = do hole′ ← inferType hole >>= normalise just (lhs ∷ rhs ∷ []) ← returnTC (getArgs 2 hole′) where nothing → typeError (termErr hole′ ∷ []) let soln = constructSoln mon lhs rhs unify hole soln