Giter VIP home page Giter VIP logo

sprite-lang's Introduction

SPRITE

A tutorial-style implementation of liquid/refinement types for a subset of Ocaml/Reason.

Install

1. Get Z3

Download from here and make sure z3 is on your $PATH

2. Clone the repository

$ git clone [email protected]:ranjitjhala/sprite-lang.git
$ cd sprite-lang

3. Build

Using stack

$ stack build

or

$ cabal v2-build

Run on a single file

$ stack exec -- sprite 8 test/L8/pos/listSet.re

The 8 indicates the language-level -- see below.

Horn VC

When you run sprite N path/to/file.re the generated Horn-VC is saved in path/to/.liquid/file.re.smt2.

So for example

$ stack exec -- sprite 8 test/L8/pos/listSet.re

will generate a VC in

test/L8/pos/.liquid/listSet.re.smt2

Languages

  • [*] Lang1 : STLC + Annot (refinements 101)
  • [*] Lang2 : "" + Branches (path-sensitivity)
  • [*] Lang3 : "" + *-refinements (inference + qual-fixpoint)
  • [*] Lang4 : "" + T-Poly (type-polymorphism)
  • [*] Lang5 : "" + Data (datatypes & measures)
  • [*] Lang6 : "" + R-Poly (refinement-polymorphism)
  • [*] Lang7 : "" + Termination (metrics + invariants)
  • [*] Lang8 : "" + Reflection (proofs)

sprite-lang's People

Contributors

numairmansur avatar ranjitjhala avatar shingarov avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sprite-lang's Issues

unknown parameter 'model_partial'

Hi @ranjitjhala

Thanks for this tutorial introduction to refinement types. When I try to run the example in README, I get the following error:

✗ stack exec -- sprite 8 test/L8/pos/listSet.re
Crash!: :1:1-1:1: Error
  crash: SMTLIB2 respSat = Error "line 4 column 27: unknown parameter 'model_partial', this is an old parameter name, invoke 'z3 -p' to obtain the new parameter list"

I am using the fork I made at https://github.com/k4rtik/sprite-lang to be able to run the code on my M1 machine. Specifically, I am on ghc 8.10.7, Z3 version 4.11.2, and liquid-fixpoint commit: 92e434da5653c5d75e1f6f1bd687bc0dc9d8acdf

how can I see the "SMTLIB" queries generated to solve the horn constraints?

re: ucsd-progsys/liquidhaskell#2259 (comment)

I am doing

$ cabal run  -w /opt/ghc/ghc-9.4.7/bin/ghc sprite -- 1 test/L1/pos/inc02.re

the file that gets written, has extension .smt2 but the contents is not?

(constraint
 (and
  (forall ((x int) (true))
   (and
    (and
     (and
      (and)
      (forall ((VV int) (true))
       ((true))))
     (forall ((VV int) (VV == 1))
...

in the sense of

$ z3 test/L1/pos/.liquid/inc02.re.smt2
unsupported
; constraint line: 43 position: 17

Can't handle monomorphic Data because 0-arg constructors aren't wrapped in ETApp

Consider this example:

type list('a) =
  | Nil
  | Cons (x:'a, xs:list('a))
  ;
/*@ val emptylist : 'a => list('a) */
let emptylist = (x) => {
  let t = Nil;
  t
};

During elaborating let t = Nil; the EImm(Nil) gets wrapped in a ETApp and then synth gets rid of the Nil.

Similarly,

type coord =
  | CCCC (x:int)
  ;
/*@ val cassert : bool[b|b] => int */
let cassert = (b) => {
  0
};
/*@ val eat : coord => int */
let eat = (cc) => {
  1
};
/*@ val check : m:int => int */
let check = (m) => {
    let x = 1;
    let p = CCCC(x);
    let i = eat(p);
    let ok = i < 0;
    cassert(ok)
};

works because in let p = CCCC(x) the CCCC(x) is an EApp and again the synth gets rid of the free CCCC.

However, if we remove polymorphism on 'a in the first example, or the argument to CCCC in the second example, Sprite will crash. This is because the Imm does not get wrapped in neither EApp nor ETApp, it simply remains EImm, so the constraints contain the free variable Nil or CCCC, and Fixpoint crashes with Constraint with free vars.

I am wondering how to best fix this. ETApp and EApp follow the curried style, but this works for nArgs>0. I would best like to follow Lawvere's "elements as morphisms from void". Shall we introduce something like TVoid along TBase and friends so we can pass it as argument to ETApp?

sprite: Can't parse z3 version: [(3," - build hashcode 37fe9cc764b7c98788813a071b82a241b46b9ad7")]

in my PATH I had some z3 compiled from source, and got

$ cabal run  -w /opt/ghc/ghc-9.4.7/bin/ghc sprite -- 1 test/L1/pos/inc00.re
Resolving dependencies...
ELet (Decl (Bind "inc" ()) (EAnn (EFun (Bind "x" ()) (EApp (EApp (EImm (ECon (PBin BPlus) ()) ()) (EVar "x" ()) ()) (ECon (PInt 1) ()) ()) ()) (TFun "x" (TBase TInt true) (TBase TInt (v = (x + 1)))) ()) ()) (ELet (Decl (Bind "bar" ()) (EApp (EImm (EVar "inc" ()) ()) (ECon (PInt 10) ()) ()) ()) (EImm (ECon (PInt 0) ()) ()) ()) ()
Working   0% [.................................................................]
sprite: Can't parse z3 version: [(3," - build hashcode 37fe9cc764b7c98788813a071b82a241b46b9ad7")]
CallStack (from HasCallStack):
  error, called at src/Language/Fixpoint/Smt/Interface.hs:378:24 in liquid-fixpoint-0.8.10.7.1-77edf5a38216377da91c98bc9356c7f88b33cf290640f99110985bb91cae268c:Language.Fixpoint.Smt.Interface

$ z3 --version
Z3 version 4.12.3 - 64 bit - build hashcode 37fe9cc764b7c98788813a071b82a241b46b9ad7

the error does not happen with

$ z3 --version
Z3 version 4.12.4 - 64 bit

Unable to handle inductive examples from ESOP-13

In an ideal world, Sprite is supposed to cover all of Vazou–Rondon–Jhala's ESOP-13 paper Abstract Refinement Types.
But I am having difficulty with foldr on p.10:

foldr :: forall <p :: [a] -> b -> Bool>.
             (xs:[a] -> x:a -> b <p xs> -> <p (x:xs)>)
          -> b<p []>
          -> ys:[a]
          -> b<p ys>
foldr op b [] = b
foldr op b (x:xs) = op xs x (foldr op b xs)

This would naïvely transliterate into Sprite like this:

type list('a) =
  | Nil
  | Cons (x:'a, xs:list('a))
  ;

/*@ val foldr : forall (p: list('a) => 'b => bool).
                (xs:list('a) => x:'a => acc:'b[v|p xs v] => 'b[v|p (Cons x xs) v])  =>
                seed:'b[v|p (Nil) v]                                                =>
                ys:list('a)                                                         =>
                'b[v|p ys v]                  */
let rec foldr = (op, seed, ys) => {
  switch (ys) {
  | Nil        => seed
  | Cons(h, t) => let nextb = foldr(op, seed, t);
                  op(t, h, nextb)
  }
};

which is of course not even well-formed Sprite, because args in ($p ... ) can only be variables, not anywhich Exprs. And for sure, the above crashes Sprite in rvarArgSymbol:

$ stack exec --profile -- sprite 6 listFoldr.re
Unexpected argument in ref-variable: p (Cons x xs) v EApp (EApp (EVar "Cons") (EVar "x")) (EVar "xs")
CallStack (from -prof):
  Language.Sprite.L6.Types.rvarArgSymbol (src/Language/Sprite/L6/Types.hs:(467,1)-(468,124))
  Language.Sprite.L6.Types.isRVarApp (src/Language/Sprite/L6/Types.hs:(461,1)-(464,36))
  Language.Fixpoint.Misc.mapEither (src/Language/Fixpoint/Misc.hs:(330,1)-(335,48))
  Language.Sprite.L6.Types.refactorAppP.(...) (src/Language/Sprite/L6/Types.hs:458:5-58)
  Language.Sprite.L6.Types.refactorAppP (src/Language/Sprite/L6/Types.hs:(455,1)-(458,58))
  Language.Sprite.L6.Types.refactorAppR (src/Language/Sprite/L6/Types.hs:(450,1)-(451,33))
  Language.Sprite.L6.Types.fmap (src/Language/Sprite/L6/Types.hs:57:23-29)
  Language.Sprite.L6.Types.refactorApp (src/Language/Sprite/L6/Types.hs:(428,1)-(432,30))
  Language.Sprite.L6.Types.generalize (src/Language/Sprite/L6/Types.hs:326:1-41)
  Language.Sprite.L6.Parse.mkDecl (src/Language/Sprite/L6/Parse.hs:(249,1)-(255,24))

This seems reasonable, so I went a bit further and tried to get around this limitation by introducing two additional ghosts, nil:list('a)[v| nil = Nil] and cns:list('a)[v | cns = Cons(x,xs) ] — the idea being that the offending applications ($p (Consx,xs) v) would become ($p cns v) — but this only kicks the can down the road because you can't use (Cons x xs) in a predicate like that either (so this crashes Sprite too).

So I went another step and tried to generalize ($p ... ) to take arbitrary Exprs under the hypothesis that those H.Vars ultimately all become PKVars, like in shingarov@84d2ea6 which doesn't work either because those ($p ... ) H.Vars do NOT become PKVars but get picked out into $k##1 etc.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.