rest-rewrite-0.2.0: 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) (L.intercalate " " $ 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 = map proofStep $ zip 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 =
case name of
Just n -> T.pack n
Nothing -> "lemma"
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