Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

remove fv distinct shim #1154

Merged
merged 2 commits into from
Mar 5, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions docs/en/pact-properties-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -731,6 +731,19 @@ filter a list by keeping the values for which `f` returns `true`

Supported in either invariants or properties.

### distinct {#FDistinct}

```lisp
(distinct xs)
```

* takes `xs`: [_a_]
* produces [_a_]

returns a list of distinct values

Supported in either invariants or properties.

### fold {#FFold}

```lisp
Expand Down
7 changes: 6 additions & 1 deletion src-tool/Pact/Analyze/Eval/Core.hs
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,11 @@ evalCore (LiteralList ty xs) = withSymVal ty $ withSing ty $ do
vals <- traverse (fmap _sSbv . eval) xs
pure $ sansProv $ SBVL.implode vals

evalCore (ListDistinct ty list) = withSymVal ty $ withSing ty $ withEq ty $ do
S _ list' <- eval list
pure $ sansProv (SBVL.reverse (bfoldr listBound (\a b -> ite (SBVL.elem a b) b (a SBVL..: b)) SBVL.nil list'))


evalCore (ListDrop ty n list) = withSymVal ty $ withSing ty $ do
S _ n' <- eval n
S _ list' <- eval list
Expand Down Expand Up @@ -296,7 +301,7 @@ evalCore (ListFilter tya (Open vid _ f) as)
(\sbva svblst -> do
S _ x' <- withVar vid (mkAVal' sbva) (eval f)
pure $ ite x' (sbva .: svblst) svblst)
(literal [])
SBVL.nil
sansProv <$> bfilterM as'

evalCore (ListFold tya tyb (Open vid1 _ (Open vid2 _ f)) a bs)
Expand Down
18 changes: 18 additions & 0 deletions src-tool/Pact/Analyze/Feature.hs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ data Feature
| FMakeList
| FMap
| FFilter
| FDistinct
| FFold
-- String operators
| FStringLength
Expand Down Expand Up @@ -1069,6 +1070,22 @@ doc FFilter = Doc
]
(TyList' a)
]

doc FDistinct = Doc
"distinct"
CList
InvAndProp
"returns a list of distinct values"
[ let a = TyVar $ TypeVar "a"
in Usage
"(distinct xs)"
Map.empty
$ Fun
Nothing
[ ("xs", TyList' a)
]
(TyList' a)
]
doc FFold = Doc
"fold"
CList
Expand Down Expand Up @@ -1722,6 +1739,7 @@ PAT(SContains, FContains)
PAT(SReverse, FReverse)
PAT(SSort, FSort)
PAT(SListDrop, FListDrop)
PAT(SDistinct, FDistinct)
PAT(SListTake, FListTake)
PAT(SMakeList, FMakeList)
PAT(SMap, FMap)
Expand Down
2 changes: 2 additions & 0 deletions src-tool/Pact/Analyze/PrenexNormalize.hs
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,8 @@ singFloat ty p = case p of
-> CoreProp . ListReverse ty' <$> singFloat (SList ty') lst
CoreProp (ListSort ty' lst)
-> CoreProp . ListSort ty' <$> singFloat (SList ty') lst
CoreProp (ListDistinct ty' lst)
-> CoreProp . ListDistinct ty' <$> singFloat (SList ty') lst
CoreProp (ListDrop ty' a b)
-> CoreProp <$> (ListDrop ty' <$> float a <*> singFloat (SList ty') b)
CoreProp (ListTake ty' a b)
Expand Down
5 changes: 2 additions & 3 deletions src-tool/Pact/Analyze/Translate.hs
Original file line number Diff line number Diff line change
Expand Up @@ -1708,9 +1708,8 @@ translateNode astNode = withAstContext astNode $ case astNode of
-- elide translation of event capability
shimNative astNode node fn []

AST_NFun node fn@"distinct" [xs] -> translateNode xs >>= \xs' -> case xs' of
Some (SList _) _ ->
shimNative' node fn [] "original list" xs'
AST_NFun _ "distinct" [xs] -> translateNode xs >>= \xs' -> case xs' of
Some ty@(SList elemTy) l -> pure $ Some ty $ CoreTerm $ ListDistinct elemTy l
_ -> unexpectedNode astNode

AST_NFun node fn@"enumerate" args ->
Expand Down
10 changes: 10 additions & 0 deletions src-tool/Pact/Analyze/Types/Languages.hs
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,8 @@ data Core (t :: Ty -> K.Type) (a :: Ty) where
ListEqNeq :: SingTy a -> EqNeq -> t ('TyList a) -> t ('TyList a) -> Core t 'TyBool
ListAt :: SingTy a -> t 'TyInteger -> t ('TyList a) -> Core t a
ListContains :: SingTy a -> t a -> t ('TyList a) -> Core t 'TyBool

ListDistinct :: SingTy a -> t ('TyList a) -> Core t ('TyList a)

ListLength :: SingTy a -> t ('TyList a) -> Core t 'TyInteger

Expand Down Expand Up @@ -843,6 +845,11 @@ showsPrecCore ty p core = showParen (p > 10) $ case core of
. showsPrec 11 ty'
. showChar ' '
. singShowsTmList ty' 11 a
ListDistinct ty' a ->
showString "ListDistinct "
. showsPrec 11 ty'
. showChar ' '
. singShowsTmList ty' 11 a
ListDrop ty' i l ->
showString "ListDrop "
. showsPrec 11 ty'
Expand Down Expand Up @@ -980,6 +987,7 @@ prettyCore ty = \case
ListLength ty' x -> parensSep [pretty SListLength, singPrettyTmList ty' x]
ListReverse ty' lst -> parensSep [pretty SReverse, singPrettyTmList ty' lst]
ListSort ty' lst -> parensSep [pretty SSort, singPrettyTmList ty' lst]
ListDistinct ty' lst -> parensSep [pretty SDistinct, singPrettyTmList ty' lst]
ListDrop ty' n lst -> parensSep [pretty SListDrop, prettyTm n, singPrettyTmList ty' lst]
ListTake ty' n lst -> parensSep [pretty SListTake, prettyTm n, singPrettyTmList ty' lst]
ListConcat ty' x y -> parensSep [pretty SConcatenation, singPrettyTmList ty' x, singPrettyTmList ty' y]
Expand Down Expand Up @@ -1862,6 +1870,8 @@ propToInvariant (CoreProp core) = CoreInvariant <$> case core of
ListReverse ty <$> f tm
ListSort ty tm ->
ListSort ty <$> f tm
ListDistinct ty tm ->
ListDistinct ty <$> f tm
ListConcat ty tm1 tm2 ->
ListConcat ty <$> f tm1 <*> f tm2
ListDrop ty tm1 tm2 ->
Expand Down
10 changes: 10 additions & 0 deletions tests/AnalyzeSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -3859,6 +3859,16 @@ spec = describe "analyze" $ do
(min a (min b c)))
|]

describe "list distinct" $ do
let code9 model = [text|
(defun test:[integer] (a:integer b:integer)
@model $model
(enforce (not (= a b)) "")
(distinct [a b a]))
|]
expectVerified $ code9 "[(property (= result [a b]))]"
expectFalsified $ code9 "[(property (= result [a b a]))]"

describe "identity" $ do
expectVerified [text|
(defun test:integer ()
Expand Down