rest-rewrite-0.4.5: testlib/Language/REST/ProofGen.hs
{-# LANGUAGE OverloadedStrings #-}
module Language.REST.ProofGen where
import qualified Data.HashMap.Strict as M
import qualified Data.List as L
import qualified Data.Text as T
import Text.Printf
import Language.REST.Path
import Language.REST.Internal.Rewrite
import Language.REST.RuntimeTerm
import Language.REST.Op
-- Hardcoded
opToLH :: Op -> String
opToLH (Op "union") = "mp"
opToLH (Op "toMS") = "multiset_of"
opToLH (Op op) = T.unpack op
withParens :: Bool -> String -> String
withParens True t = "(" ++ t ++ ")"
withParens False t = t
toLH :: Bool -> RuntimeTerm -> String
-- Hardcoded rules
toLH parens (App "m" [arg]) = withParens parens $ printf "Multiset [%s]" (toLH False arg)
toLH parens (App "cons" [x, xs]) = withParens parens $ printf "%s:%s" (toLH True x) (toLH True xs)
toLH _ (App op []) = opToLH op
toLH parens (App op args) =
withParens parens $ printf "%s %s" (opToLH op) (unwords $ map (toLH True) args)
toProof :: Path Rewrite RuntimeTerm a -> String
toProof (steps, PathTerm result _) = " " ++ L.intercalate "\n=== " (proofSteps ++ [toLH False result]) ++ "\n*** QED"
where
proofSteps :: [String]
proofSteps = zipWith (curry proofStep) steps [0..]
proofStep (Step (PathTerm t _) _ _ True, _) = toLH False t
proofStep (Step (PathTerm t _) (Rewrite lhs rhs name) _ False, i) = toLH False t ++ " ? " ++ toLemma lemma
where
lemma = go (subTerms t)
lemmaName = maybe "lemma" T.pack name
toLemma s = toLH False (App (Op lemmaName) (map snd $ L.sort $ M.toList s))
go [] = undefined
go ((st, f): _) | Just su <- unify lhs st M.empty
, f (subst su rhs) == nextTerm
= su
go (_:xs) = go xs
nextTerm = if i < (length steps - 1) then (pathTerm . term) (steps !! (i + 1)) else result