Skip to content

Commit

Permalink
crucible-syntax: Allow exotic characters in fresh atom names
Browse files Browse the repository at this point in the history
Previously, we used `userSymbol` to create fresh atom names, but `userSymbol`
will fail if given any characters outside of the very narrow range of
characters allowed in What4 solver names. Instead, we now use `safeSymbol`,
which will Z-encode any unallowable characters into something that is allowed
in a What4 solver name. This ensures (among other things) that we can write
things like `(let i-3 (fresh Bool))`, as hyphens are not allowed in What4
solver names without Z-encoding them.

Fixes #1024.
  • Loading branch information
RyanGlScott committed Nov 26, 2024
1 parent d0c27a1 commit 8be1cd0
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 15 deletions.
33 changes: 18 additions & 15 deletions crucible-syntax/src/Lang/Crucible/Syntax/Concrete.hs
Original file line number Diff line number Diff line change
Expand Up @@ -1564,21 +1564,24 @@ atomSetter (AtomName anText) =

fresh =
do t <- reading (unary Fresh isType)
describe "user symbol" $
case userSymbol (T.unpack anText) of
Left err -> describe (T.pack (show err)) empty
Right nm ->
do loc <- position
case t of
Some (FloatRepr fi) ->
Some <$>
freshAtom loc (FreshFloat fi (Just nm))
Some NatRepr ->
Some <$> freshAtom loc (FreshNat (Just nm))
Some tp
| AsBaseType bt <- asBaseType tp ->
Some <$> freshAtom loc (FreshConstant bt (Just nm))
| otherwise -> describe "atomic type" $ empty
-- Note that we are using safeSymbol below to create a What4 symbol
-- name, which will Z-encode names that aren't legal solver names. This
-- includes names that include hyphens, which are very common in
-- S-expression syntax. This is fine to do, since the Z-encoded name
-- name is only used for solver purposes; the original, unencoded name
-- is recorded separately.
let nm = safeSymbol (T.unpack anText)
loc <- position
case t of
Some (FloatRepr fi) ->
Some <$>
freshAtom loc (FreshFloat fi (Just nm))
Some NatRepr ->
Some <$> freshAtom loc (FreshNat (Just nm))
Some tp
| AsBaseType bt <- asBaseType tp ->
Some <$> freshAtom loc (FreshConstant bt (Just nm))
| otherwise -> describe "atomic type" $ empty

evaluated =
do Pair _ e' <- reading synth
Expand Down
10 changes: 10 additions & 0 deletions crucible-syntax/test-data/exotic-fresh-names.cbl
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
; A regression test for #1024.

(defun @exotic-fresh-names () Bool
(start start:
; Although the list of allowable characters in What4 solver names is very
; small, we can nevertheless define atom names with unallowable characters
; by Z-encoding them under the hood.
(let ω (fresh Bool)) ; Fancy Unicode characters
(let hyphens-are-fine (fresh Bool)) ; Hyphens
(return (and ω hyphens-are-fine))))
17 changes: 17 additions & 0 deletions crucible-syntax/test-data/exotic-fresh-names.out.good
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
(defun @exotic-fresh-names () Bool
(start start:
(let ω (fresh Bool))
(let hyphens-are-fine (fresh Bool))
(return (and ω hyphens-are-fine))))

exotic-fresh-names
%0
% 8:12
$0 = fresh BaseBoolRepr zenc!z3c9U
% 9:27
$1 = fresh BaseBoolRepr zenc!hyphenszmarezmfine
% 10:13
$2 = and($0, $1)
% 10:5
return $2
% no postdom

0 comments on commit 8be1cd0

Please sign in to comment.