@@ -130,7 +130,7 @@ data FixDecl = Fix Fixity String
130130instance Ord FixDecl where
131131 compare (Fix x _) (Fix y _) = compare (prec x) (prec y)
132132
133−data Plicity = Imp | Exp deriving Show
133+data Plicity = Imp | Exp deriving (Show, Eq)
134134
135135data PDecl' t = PFix FC Fixity [String] -- fixity declaration
136136 | PTy FC Name t -- type declaration
@@ -187,14 +187,16 @@ data PTerm = PQuote Raw
187187 | PReturn FC
188188 | PMetavar Name
189189 | PElabError String -- error to report on elaboration
190+ deriving Eq
190191
191192data PDo = DoExp FC PTerm
192193 | DoBind FC Name PTerm
193194 | DoLet FC Name PTerm
195+ deriving Eq
194196
195197data PArg' t = PImp { pname :: Name, getTm :: t }
196198 | PExp { getTm :: t }
197− deriving (Show, Functor)
199+ deriving (Show, Eq, Functor)
198200
199201type PArg = PArg' PTerm
200202
@@ -525,3 +527,52 @@ dumpDecl (PParams _ ns ps) = "params {" ++ show ns ++ "\n" ++ dumpDecls ps ++ "}
525527dumpDecl (PSyntax _ syn) = "syntax " ++ show syn
526528-- dumpDecl (PImport i) = "import " ++ i
527529
530+-- syntactic match of a against b, returning pair of variables in a
531+-- and what they match. Returns 'Nothing' if not a match.
532+
533+matchClause :: PTerm -> PTerm -> Maybe [(Name, PTerm)]
534+matchClause x y = match x y where
535+ matchArg x y = match (getTm x) (getTm y)
536+
537+ match (PApp _ f args) (PApp _ f' args')
538+ | length args == length args'
539+ = do mf <- match f f'
540+ ms <- zipWithM matchArg args args'
541+ return (mf ++ concat ms)
542+ match (PRef _ n) (PRef _ n') | n == n' = return []
543+ | otherwise = Nothing
544+ match (PRef _ n) tm = return [(n, tm)]
545+ match (PPair _ l r) (PPair _ l' r') = do ml <- match l l'
546+ mr <- match r r'
547+ return (ml ++ mr)
548+ match (PDPair _ l r) (PDPair _ l' r') = do ml <- match l l'
549+ mr <- match r r'
550+ return (ml ++ mr)
551+ match (PTrue _) (PTrue _) = return []
552+ match (PFalse _) (PFalse _) = return []
553+ match (PReturn _) (PReturn _) = return []
554+ match (PPi _ _ t s) (PPi _ _ t' s') = do mt <- match t t'
555+ ms <- match s s'
556+ return (mt ++ ms)
557+ match (PLam _ t s) (PLam _ t' s') = do mt <- match t t'
558+ ms <- match s s'
559+ return (mt ++ ms)
560+ match (PHidden x) (PHidden y) = match x y
561+ match a b | a == b = return []
562+ | otherwise = Nothing
563+
564+substMatches :: [(Name, PTerm)] -> PTerm -> PTerm
565+substMatches [] t = t
566+substMatches ((n,tm):ns) t = substMatch n tm (substMatches ns t)
567+
568+substMatch :: Name -> PTerm -> PTerm -> PTerm
569+substMatch n tm t = sm t where
570+ sm (PRef _ n') | n == n' = tm
571+ sm (PLam x t sc) = PLam x (sm t) (sm sc)
572+ sm (PPi p x t sc) = PPi p x (sm t) (sm sc)
573+ sm (PApp f x as) = PApp f (sm x) (map (fmap sm) as)
574+ sm (PPair f x y) = PPair f (sm x) (sm y)
575+ sm (PDPair f x y) = PDPair f (sm x) (sm y)
576+ sm (PHidden x) = PHidden (sm x)
577+ sm x = x
578+