Skip to content

Commit

Permalink
Isabelle/HOL name quoting (#2951)
Browse files Browse the repository at this point in the history
* Closes #2941 
* Depends on #2950
  • Loading branch information
lukaszcz authored Aug 14, 2024
1 parent fcd52a4 commit d60bccc
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 13 deletions.
44 changes: 37 additions & 7 deletions src/Juvix/Compiler/Backend/Isabelle/Translation/FromTyped.hs
Original file line number Diff line number Diff line change
Expand Up @@ -882,15 +882,45 @@ goModule onlyTypes infoTable Internal.Module {..} =
names :: HashSet Text
names =
HashSet.fromList $
map (^. Internal.functionInfoName . namePretty) (filter (not . (^. Internal.functionInfoIsLocal)) (HashMap.elems (infoTable ^. Internal.infoFunctions)))
++ map (^. Internal.constructorInfoName . namePretty) (HashMap.elems (infoTable ^. Internal.infoConstructors))
++ map (^. Internal.inductiveInfoName . namePretty) (HashMap.elems (infoTable ^. Internal.infoInductives))
++ map (^. Internal.axiomInfoDef . Internal.axiomName . namePretty) (HashMap.elems (infoTable ^. Internal.infoAxioms))
map quote $
map (^. Internal.functionInfoName . namePretty) (filter (not . (^. Internal.functionInfoIsLocal)) (HashMap.elems (infoTable ^. Internal.infoFunctions)))
++ map (^. Internal.constructorInfoName . namePretty) (HashMap.elems (infoTable ^. Internal.infoConstructors))
++ map (^. Internal.inductiveInfoName . namePretty) (HashMap.elems (infoTable ^. Internal.infoInductives))
++ map (^. Internal.axiomInfoDef . Internal.axiomName . namePretty) (HashMap.elems (infoTable ^. Internal.infoAxioms))

quote :: Text -> Text
quote txt = case Text.uncons txt of
Just (c, txt') | not (isLetter c) -> txt'
_ -> txt
quote = quote' . Text.filter isLatin1 . Text.filter (isLetter .||. isDigit .||. (== '_') .||. (== '\''))

quote' :: Text -> Text
quote' txt
| HashSet.member txt reservedNames = quote' (prime txt)
| txt == "_" = "v"
| otherwise = case Text.uncons txt of
Just (c, _) | not (isLetter c) -> quote' ("v_" <> txt)
_ -> case Text.unsnoc txt of
Just (_, c) | not (isAlphaNum c || c == '\'') -> quote' (txt <> "'")
_ -> txt

reservedNames :: HashSet Text
reservedNames =
HashSet.fromList
[ "begin",
"bool",
"case",
"else",
"end",
"if",
"imports",
"in",
"int",
"let",
"list",
"nat",
"of",
"option",
"theory",
"then"
]

filterTypeArgs :: Int -> Internal.Expression -> [a] -> [a]
filterTypeArgs paramsNum ty args =
Expand Down
2 changes: 1 addition & 1 deletion tests/positive/Isabelle/Program.juvix
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ qfst : {A : Type} → Queue A → List A
| (queue x _) := x;

qsnd : {A : Type} → Queue A → List A
| (queue _ x) := x;
| (queue _ v) := v;

pop_front {A} (q : Queue A) : Queue A :=
let
Expand Down
10 changes: 5 additions & 5 deletions tests/positive/Isabelle/isabelle/Program.thy
Original file line number Diff line number Diff line change
Expand Up @@ -55,18 +55,18 @@ datatype 'A Queue
= queue "'A list" "'A list"

fun qfst :: "'A Queue \<Rightarrow> 'A list" where
"qfst (queue x ω) = x"
"qfst (queue x v) = x"

fun qsnd :: "'A Queue \<Rightarrow> 'A list" where
"qsnd (queue ω x) = x"
"qsnd (queue v v') = v'"

fun pop_front :: "'A Queue \<Rightarrow> 'A Queue" where
"pop_front q =
(let
q' = queue (tl (qfst q)) (qsnd q)
in case qfst q' of
[] \<Rightarrow> queue (rev (qsnd q')) [] |
ω \<Rightarrow> q')"
v \<Rightarrow> q')"

fun push_back :: "'A Queue \<Rightarrow> 'A \<Rightarrow> 'A Queue" where
"push_back q x =
Expand All @@ -80,8 +80,8 @@ fun is_empty :: "'A Queue \<Rightarrow> bool" where
[] \<Rightarrow>
(case qsnd q of
[] \<Rightarrow> True |
ω \<Rightarrow> False) |
ω \<Rightarrow> False)"
v \<Rightarrow> False) |
v \<Rightarrow> False)"

definition empty :: "'A Queue" where
"empty = queue [] []"
Expand Down

0 comments on commit d60bccc

Please sign in to comment.