-------------------------------------------------------------------------
-- Functions for adding the PreAlphabet datatype to an Isabelle theory --
-------------------------------------------------------------------------
-- | Add the PreAlphabet (built from a list of sorts) to an Isabelle
addPreAlphabet :: [SORT] -> IsaTheory -> IsaTheory
addPreAlphabet sortList isaTh =
let preAlphabetDomainEntry = mkPreAlphabetDE sortList
-- Add to the isabelle signature the new domain entry
in updateDomainTab preAlphabetDomainEntry isaTh
-- | Make a Domain Entry for the PreAlphabet from a list of sorts.
mkPreAlphabetDE :: [SORT] -> DomainEntry
(Type {typeId = preAlphabetS, typeSort = [isaTerm], typeArgs = []},
(mkVName (mkPreAlphabetConstructor sort),
[Type {typeId = convertSort2String sort,
----------------------------------------------------------------
-- Functions for adding the eq functions and the compare_with --
-- functions to an Isabelle theory --
----------------------------------------------------------------
-- | Add the eq function to an Isabelle theory using a list of sorts
addEqFun :: [SORT] -> IsaTheory -> IsaTheory
addEqFun sortList isaTh =
let eqtype = mkFunType preAlphabetType $ mkFunType preAlphabetType boolType
isaThWithConst = addConst eq_PreAlphabetS eqtype isaTh
lhs = binEq_PreAlphabet lhs_a y
lhs_a = termAppl (conDouble (mkPreAlphabetConstructor sort)) x
rhs_a = termAppl (conDouble (mkCompareWithFunName sort)) x
in addPrimRec eqs isaThWithConst
-- | Add all compare_with functions for a given list of sorts to an
-- Isabelle theory. We need to know about the casl signature (data
-- part of a CspCASL spec) so that we can pass it on to the
-- addCompareWithFun function
addAllCompareWithFun caslSign isaTh =
in foldl (addCompareWithFun caslSign) isaTh sortList
-- | Add a single compare_with function for a given sort to an
-- Isabelle theory. We need to know about the casl signature (data
-- part of a CspCASL spec) to work out the RHS of the equations.
addCompareWithFun caslSign isaTh sort =
sortType = Type {typeId = convertSort2String sort, typeSort = [],
funName = mkCompareWithFunName sort
funType = mkFunType sortType $ mkFunType preAlphabetType boolType
isaThWithConst = addConst funName funType isaTh
sort'Constructor = mkPreAlphabetConstructor sort'
lhs = termAppl lhs_a lhs_b
lhs_a = termAppl (conDouble funName) x
lhs_b = termAppl (conDouble (sort'Constructor)) y
-- If there are no tests then the rhs=false else
-- combine all tests using binConj
else foldr1 binConj allTests
-- The tests produce a list of equations for each test
-- Test 1 = test equality at: current sort vs current sort
-- Test 2 = test equality at: current sort vs super sorts
-- Test 3 = test equality at: super sorts vs current sort
-- Test 4 = test equality at: super sorts vs super sorts
allTests = concat [test1, test2, test3, test4]
test1 = if (sort == sort') then [binEq x y] else []
then [binEq x (mkInjection sort' sort y)]
then [binEq (mkInjection sort sort' x) y]
test4 = if (null commonSuperList)
else map test4_atSort commonSuperList
test4_atSort s = binEq (mkInjection sort s x)
in addPrimRec eqs isaThWithConst
--------------------------------------------------------
-- Functions for producing the Justification theorems --
--------------------------------------------------------
-- | Add all justification theorems to an Isabelle Theory. We need to
-- the CASL signature (from the datapart) and the PFOL Signature to
-- pass it on. We could recalculate the PFOL signature from the CASL
-- signature here, but we dont as it can be passed in. We need the
-- PFOL signature which is the data part CASL signature afetr
-- translation to PCFOL (
i.e. without subsorting)
addJustificationTheorems caslSign pfolSign isaTh =
in addTransitivityTheorem sorts sortRel
$ addAllInjectivityTheorems pfolSign sorts sortRel
$ addAllDecompositionTheorem pfolSign sorts sortRel
$ addSymmetryTheorem sorts
-- | Add the reflexivity theorem and proof to an Isabelle Theory
addReflexivityTheorem :: IsaTheory -> IsaTheory
addReflexivityTheorem isaTh =
let name = reflexivityTheoremS
thmConcl = binEq_PreAlphabet x x
proof = [Apply (Induct x),
in addTheoremWithProof name thmConds thmConcl proof' isaTh
-- | Add the symmetry theorem and proof to an Isabelle Theory. We need
-- to know the number of sorts, but instead we are given a list of
addSymmetryTheorem :: [SORT] -> IsaTheory -> IsaTheory
addSymmetryTheorem sorts isaTh =
let numSorts = length(sorts)
thmConds = [binEq_PreAlphabet x y]
thmConcl = binEq_PreAlphabet y x
inductY = concat $ map (\i -> [Prefer (i*numSorts+1),
proof = [Apply (Induct x)] ++ inductY ++ [Apply Auto],
in addTheoremWithProof name thmConds thmConcl proof' isaTh
-- | Add all the decoposition theorems and proofs
addAllDecompositionTheorem pfolSign sorts sortRel isaTh =
let tripples = [(s1,s2,s3) |
(s1,s2) <- sortRel, (s2',s3) <- sortRel, s2==s2']
in foldl (addDecompositionTheorem pfolSign sorts sortRel) isaTh tripples
-- | Add the decomposition theorem and proof which should be deduced
-- from the transitivity axioms from the translation CASL2PCFOL;
-- CASL2SubCFOL for a pair of injections represented as a tripple of
-- sorts.
e.g. (S,T,U) means produce the lemma and proof for
-- inj_T_U(inj_S_T(x)) = inj_S_U(x). As a work around, we need to
-- know all sorts to pass them on.
IsaTheory -> (SORT,SORT,SORT) -> IsaTheory
addDecompositionTheorem pfolSign sorts sortRel isaTh (s1,s2,s3) =
-- These 5 lines make use of currying
injOp_s1_s2 = mkInjection s1 s2
injOp_s2_s3 = mkInjection s2 s3
injOp_s1_s3 = mkInjection s1 s3
inj_s1_s2_s3_x = injOp_s2_s3 (injOp_s1_s2 x)
inj_s1_s3_x = injOp_s1_s3 x
definedOp_s1 = getDefinedOp sorts s1
definedOp_s3 = getDefinedOp sorts s3
collectionTransAx = getCollectionTransAx sortRel
collectionTotAx = getCollectionTotAx pfolSign
collectionNotDefBotAx = getCollectionNotDefBotAx sorts
name = getDecompositionThmName(s1, s2, s3)
concl = binEq inj_s1_s2_s3_x inj_s1_s3_x
proof' = IsaProof [Apply(CaseTac (definedOp_s3 inj_s1_s2_s3_x)),
Apply(SubgoalTac(definedOp_s1 x)),
Apply(Insert collectionTransAx),
Apply(SimpAdd Nothing collectionTotAx),
termAppl notOp(definedOp_s3 inj_s1_s3_x))),
Apply(SimpAdd Nothing collectionNotDefBotAx),
Apply(SimpAdd Nothing collectionTotAx)]
in addTheoremWithProof name conds concl proof' isaTh
-- | Add all the injectivity theorems and proofs
addAllInjectivityTheorems pfolSign sorts sortRel isaTh =
foldl (addInjectivityTheorem pfolSign sorts sortRel) isaTh sortRel
-- | Add the injectivity theorem and proof which should be deduced
-- from the embedding_Injectivity axioms from the translation
-- CASL2PCFOL; CASL2SubCFOL for a single injection represented as a
-- pair of sorts. As a work around, we need to know all sorts to
IsaTheory -> (SORT,SORT) -> IsaTheory
addInjectivityTheorem pfolSign sorts sortRel isaTh (s1,s2) =
injX = mkInjection s1 s2 x
injY = mkInjection s1 s2 y
definedOp_s1 = getDefinedOp sorts s1
definedOp_s2 = getDefinedOp sorts s2
collectionEmbInjAx = getCollectionEmbInjAx sortRel
collectionTotAx = getCollectionTotAx pfolSign
collectionNotDefBotAx = getCollectionNotDefBotAx sorts
name = getInjectivityThmName(s1, s2)
conds = [binEq injX injY]
proof' = IsaProof [Apply(CaseTac (definedOp_s2 injX)),
Apply(SubgoalTac(definedOp_s1 x)),
Apply(SubgoalTac(definedOp_s1 y)),
Apply(Insert collectionEmbInjAx),
Apply(SimpAdd Nothing collectionTotAx),
Apply(SimpAdd (Just No_asm_use) collectionTotAx),
Apply(SubgoalTac(termAppl notOp (definedOp_s1 x))),
Apply(SubgoalTac(termAppl notOp(definedOp_s1 y))),
Apply(SimpAdd Nothing collectionNotDefBotAx),
Apply(SimpAdd Nothing collectionTotAx),
Apply(SimpAdd (Just No_asm_use) collectionTotAx)]
in addTheoremWithProof name conds concl proof' isaTh
-- | Add the transitivity theorem and proof to an Isabelle Theory. We
-- need to know the number of sorts to know how much induction to
-- perfom and also the sub-sort relation to build the collection of
-- injectivity theorem names
addTransitivityTheorem :: [SORT] -> [(SORT,SORT)] -> IsaTheory -> IsaTheory
addTransitivityTheorem sorts sortRel isaTh =
let colInjThmNames = getColInjectivityThmName sortRel
colDecompThmNames = getColDecompositionThmName sortRel
thmConds = [binEq_PreAlphabet x y, binEq_PreAlphabet y z]
thmConcl = binEq_PreAlphabet x z
inductY = concat $ map (\i -> [Prefer (i*numSorts+1),
inductZ = concat $ map (\i -> [Prefer (i*numSorts+1),
[0..((numSorts^(2::Int))-1)]
proof = [Apply (Induct x)] ++
[Apply (AutoSimpAdd Nothing
(colDecompThmNames ++ colInjThmNames))],
in addTheoremWithProof name thmConds thmConcl proof' isaTh
--------------------------------------------------------------
-- Functions for producing instances of equivalence classes --
--------------------------------------------------------------
-- | Function to add preAlphabet as an equivalence relation to an
addInstansanceOfEquiv :: IsaTheory -> IsaTheory
addInstansanceOfEquiv isaTh =
let eqvSort = [IsaClass eqvTypeClassS]
eqvProof = IsaProof [] (By (Other "intro_classes"))
equivSort = [IsaClass equivTypeClassS]
equivProof = IsaProof [Apply (Other "intro_classes"),
Apply (Other ("unfold " ++ preAlphabetSimS
Apply (Other ("rule " ++ reflexivityTheoremS)),
Apply (Other ("rule " ++ transitivityS
Apply (Other ("rule " ++ symmetryTheoremS
defRhs = binEq_PreAlphabet x y
in addInstanceOf preAlphabetS [] equivSort equivProof
$ addDef preAlphabetSimS defLhs defRhs
$ addInstanceOf preAlphabetS [] eqvSort eqvProof
-------------------------------------------------------------
-- Functions for producing the alphabet type --
-------------------------------------------------------------
-- | Function to add the Alphabet type (type synonym) to an Isabelle theory
addAlphabetType :: IsaTheory -> IsaTheory
let isaTh_sign = fst isaTh
isaTh_sign_tsig = tsig isaTh_sign
myabbrs = abbrs isaTh_sign_tsig
abbrsNew =
Map.insert alphabetS ([], preAlphabetQuotType) myabbrs
isaTh_sign_updated = isaTh_sign {
tsig = (isaTh_sign_tsig {abbrs =abbrsNew})
in (isaTh_sign_updated, snd isaTh)
-------------------------------------------------------------
-- Functions for producing the bar types --
-------------------------------------------------------------
-- | Function to add all the bar types to an Isabelle theory.
addAllBarTypes :: [SORT] -> IsaTheory -> IsaTheory
addAllBarTypes sorts isaTh = foldl addBarType isaTh sorts
-- | Function to add the bar types of a sort to an Isabelle theory.
addBarType :: IsaTheory -> SORT -> IsaTheory
let sortBarString = mkSortBarString sort
barType = Type {typeId = sortBarString, typeSort = [], typeArgs =[]}
rhs = termAppl (conDouble (mkPreAlphabetConstructor sort)) y
bin_eq = binEq x $ termAppl (conDouble classS ) rhs
exist_eq =termAppl (conDouble exS) (Abs y bin_eq NotCont)
subset = SubSet x alphabetType exist_eq
sen = TypeDef barType subset (IsaProof [] (By Auto))
namedSen = (makeNamed sortBarString sen)
in (isaTh_sign, isaTh_sen ++ [namedSen])
-------------------------------------------------------------
-- Functions for producing the choose functions --
-------------------------------------------------------------
-- | Add all choose functions for a given list of sorts to an Isabelle
addAllChooseFunctions :: [SORT] -> IsaTheory -> IsaTheory
addAllChooseFunctions sorts isaTh =
let isaTh' = foldl addChooseFunction isaTh sorts --add function and def
in foldl addChooseFunctionLemma isaTh' sorts --add theorem and proof
-- | Add a single choose function for a given sort to an Isabelle
-- theory. The following Isabelle code is produced by this function:
-- consts choose_Nat :: "Alphabet => Nat"
-- defs choose_Nat_def: "choose_Nat x == contents{y . class(C_Nat y) = x}"
addChooseFunction :: IsaTheory -> SORT -> IsaTheory
addChooseFunction isaTh sort =
sortType = Type {typeId = convertSort2String sort,
chooseFunName = mkChooseFunName sort
chooseFunType = mkFunType alphabetType sortType
contentsOp = termAppl (conDouble "contents")
sortConsOp = termAppl (conDouble (mkPreAlphabetConstructor sort))
bin_eq = binEq (classOp $ sortConsOp y) x
subset = SubSet y sortType bin_eq
lhs = mkChooseFunOp sort $ x
rhs = contentsOp (Set subset)
in -- Add defintion to theory
addDef chooseFunName lhs rhs
-- Add constant to theory
$ addConst chooseFunName chooseFunType isaTh
-- | Add a single choose function lemma for a given sort to an
-- Isabelle theory. The following Isabelle code is produced by this
-- function: lemma "choose_Nat (class (C_Nat x)) = x". The proof is
addChooseFunctionLemma :: IsaTheory -> SORT -> IsaTheory
addChooseFunctionLemma isaTh sort =
let sortType = Type {typeId = convertSort2String sort,
chooseFunName = mkChooseFunName sort
sortConsOp = termAppl (conDouble (mkPreAlphabetConstructor sort))
subgoalTacTermLhsBinEq = binEq (classOp $ sortConsOp y)
subgoalTacTermLhs = Set $ SubSet y sortType subgoalTacTermLhsBinEq
subgoalTacTermRhs = Set $ FixedSet [x]
subgoalTacTerm = binEq subgoalTacTermLhs subgoalTacTermRhs
thmConcl = binEq (mkChooseFunOp sort $ classOp $ sortConsOp x) x
proof' = IsaProof [Apply (Other ("unfold " ++ chooseFunName ++ "_def")),
Apply (SubgoalTac subgoalTacTerm),
Apply(SimpAdd Nothing [quotEqualityS]),
Apply(Other ("unfold "++ preAlphabetSimS
in addTheoremWithProof chooseFunName thmConds thmConcl proof' isaTh
-------------------------------------------------------------
-- Functions for producing the integration theorems --
-------------------------------------------------------------
-- | Add all the integration theorems. We need to know all the sorts
-- to produce all the theorems. We need to know the CASL signature
-- of the data part to pass it on as an argument.
addAllIntegrationTheorems sorts caslSign isaTh =
let pairs = [(s1,s2) | s1 <- sorts, s2 <- sorts]
in foldl (addIntegrationTheorem_A caslSign) isaTh pairs
-- | Add Integration theorem A -- Compare to elements of the Alphabet.
-- We add the integration theorem based on the sorts of both
-- elements of the alphabet. We need to know the subsort relation to
-- find the highest common sort, but we pass in the CASL signature
addIntegrationTheorem_A caslSign isaTh (s1,s2) =
s1ConsOp = termAppl (conDouble (mkPreAlphabetConstructor s1))
s2ConsOp = termAppl (conDouble (mkPreAlphabetConstructor s2))
rhs = binEq (classOp $ s1ConsOp x) (classOp $ s2ConsOp y)
lhs = if (null commonSuperList)
-- BUG pick any common sort for now (this does hold
-- and is valid) we should pick the top most one.
let s' = head commonSuperList
in binEq (mkInjection s1 s' x) (mkInjection s2 s' y)
-- theorem names for proof
colInjThmNames = getColInjectivityThmName sortRel
colDecompThmNames = getColDecompositionThmName sortRel
proof' = IsaProof [Apply (SimpAdd Nothing [quotEqualityS]),
Apply (Other ("unfold " ++ preAlphabetSimS
Apply (AutoSimpAdd Nothing
(colDecompThmNames ++ colInjThmNames))]
in addTheoremWithProof "IntegrationTheorem_A"
thmConds thmConcl proof' isaTh
--------------------------------------------------------------------------
-- Functions for adding the process name datatype to an Isabelle theory --
--------------------------------------------------------------------------
-- | Add process name datatype which has a constructor for each
-- process name (along with the arguments for the process) in the
-- CspCASL Signature to an Isabelle theory
addProcNameDatatype :: CspSign -> IsaTheory -> IsaTheory
addProcNameDatatype cspSign isaTh =
let -- Create a list of pairs of process names and thier profiles
procNameDomainEntry = mkProcNameDE procSetList
in updateDomainTab procNameDomainEntry isaTh
-- | Make a proccess name Domain Entry from a list of a Process name and profile
-- pair. This creates a data type for the process names.
mkProcNameDE :: [(PROCESS_NAME, ProcProfile)] -> DomainEntry
let -- The a list of pairs of constructors and their arguments
constructors = map mk_cons processes
-- Take a proccess name and its argument sorts (also its
-- commAlpha - thrown away) and make a pair representing the
-- constructor and the argument types
mk_cons (procName, (ProcProfile sorts _)) =
(mkVName (mkProcNameConstructor procName), map sortToTyp sorts)
-- Turn a sort in to a Typ suitable for the domain entry The
-- processes need to have arguments of the bar variants of
-- the sorts not the original sorts
sortToTyp sort = Type {typeId = mkSortBarString sort,
(procNameType, constructors)
-------------------------------------------------------------------------
-- Functions adding the process map function to an Isabelle theory --
-------------------------------------------------------------------------
-- | Add the function procMap to an Isabelle theory. This function maps process
-- names to real processes build using the same names and the alphabet
i.e.,
-- ProcName => (ProcName, Alphabet) proc. We need to know the CspCASL
-- sentences and the casl signature (data part). We need the PCFOL and CFOL
-- signatures of the data part after translation to PCFOL and CFOL to pass
-- along the process translation.
addProcMap namedSens caslSign pcfolSign cfolSign isaTh =
-- Translate a fully qualified variable (CASL term) to Isabelle
caslSign tyToks trForm strs) fqVar
-- Extend Isabelle theory with additional constant
isaThWithConst = addConst procMapS procMapType isaTh
-- Get the plain sentences from the named senetences
sens = map (\namedsen -> sentence namedsen) namedSens
-- Filter so we only have proccess equations and no CASL senetences
processEqs = filter isProcessEq sens
-- the term representing the procMap that tajes a term as a
procMapTerm = termAppl (conDouble procMapS)
-- Make a single equation for the primrec from a process equation
mkEq (ProcessEq procName fqVars _ proc) =
let -- Make the name (string) for this process
procNameString = convertProcessName2String procName
-- Change the name to a term
procNameTerm = conDouble procNameString
-- Turn the list of variables into a list of Isabelle
varTerms = map transVar fqVars
lhs = procMapTerm (foldl termAppl (procNameTerm) varTerms)
rhs = transProcess caslSign pcfolSign cfolSign fqVars proc
-- to avoid warnings we specify the behaviour on CASL sentences. This
-- should never be called as they have been filtered out.
-- Build equations for primrec using process equations
eqs = map mkEq processEqs
in addPrimRec eqs isaThWithConst
------------------------------------------------------------
-- Basic function to help keep strings consistent --
------------------------------------------------------------
-- | Return the list of strings of all gn_totality axiom names. This
-- function is not implemented in a satisfactory way.
getCollectionTotAx pfolSign =
-- This filter is not quite right
totFilter (_,setOpType) = let listOpType =
Set.toList setOpType
totList = filter totFilter opList
mkTotAxName = (\i -> "ga_totality"
in map mkTotAxName [0 .. (length(totList) - 1)]
-- | Return the name of the definedness function for a sort. We need
-- to know all sorts to perform this workaround
-- This function is not implemented in a satisfactory way
getDefinedName :: [SORT] -> SORT -> String
-- | Return the name of the injection as it is used in the alternative
-- syntax of the injection from one sort to another.
-- This function is not implemented in a satisfactory way
getInjectionName :: SORT -> SORT -> String
-- | Return the injection name of the injection from one sort to another
-- This function is not implemented in a satisfactory way
getDefinedOp :: [SORT] -> SORT -> Term -> Term
termAppl (con $ VName (getDefinedName sorts s) $ Nothing) t
-- | Return the term representing the injection of a term from one sort to
-- another. Note: the term is returned if both sorts are the same. This
-- function is not implemented in a satisfactory way.
mkInjection :: SORT -> SORT -> Term -> Term
let injName = getInjectionName s s'
replace string c s1 = concat (map (\x -> if x==c
((replace injName '_' "'_")
typeSort = [IsaClass "type"],
-- | Return the list of string of all embedding_injectivity axioms
-- produced by the translation CASL2PCFOL; CASL2SubCFOL. This
-- function is not implemented in a satisfactory way.
getCollectionEmbInjAx :: [(SORT,SORT)] -> [String]
getCollectionEmbInjAx sortRel =
let mkEmbInjAxName = (\i -> "ga_embedding_injectivity"
in map mkEmbInjAxName [0 .. (length(sortRel) - 1)]
-- | Return the list of strings of all ga_notDefBottom axioms. This function is
-- not implemented in a satisfactory way
getCollectionNotDefBotAx :: [SORT] -> [String]
getCollectionNotDefBotAx sorts =
let mkNotDefBotAxName = (\i -> "ga_notDefBottom"
in map mkNotDefBotAxName [0 .. (length(sorts) - 1)]
-- | Return the list of string of all decomposition theorem names that we
-- generate. This function is not implemented in a satisfactory way
getColDecompositionThmName :: [(SORT,SORT)] -> [String]
getColDecompositionThmName sortRel =
let tripples = [(s1,s2,s3) |
(s1,s2) <- sortRel, (s2',s3) <- sortRel, s2==s2']
in map getDecompositionThmName tripples
-- | Produce the theorem name of the decomposition theorem that we produce for a
-- gievn tripple of sorts.
getDecompositionThmName :: (SORT,SORT,SORT) -> String
getDecompositionThmName (s, s', s'') =
"decomposition_" ++ (convertSort2String s) ++ "_" ++ (convertSort2String s')
++ "_" ++ (convertSort2String s'')
-- | Return the list of strings of the injectivity theorem names that we
-- generate. This function is not implemented in a satisfactory way
getColInjectivityThmName :: [(SORT,SORT)] -> [String]
getColInjectivityThmName sortRel = map getInjectivityThmName sortRel
-- | Produce the theorem name of the injectivity theorem that we produce for a
getInjectivityThmName :: (SORT,SORT) -> String
getInjectivityThmName (s, s') =
"injectivity_" ++ (convertSort2String s) ++ "_" ++ (convertSort2String s')
-- | Return the list of strings of all the transitivity axioms names produced by
-- the translation CASL2PCFOL; CASL2SubCFOL. This function is not implemented
-- in a satisfactory way.
getCollectionTransAx :: [(SORT,SORT)] -> [String]
getCollectionTransAx sortRel =
let tripples = [(s1,s2,s3) |
(s1,s2) <- sortRel, (s2',s3) <- sortRel, s2==s2']
mkEmbInjAxName = (\i -> "ga_transitivity"
in map mkEmbInjAxName [0 .. (length(tripples) - 1)]