├── project └── assembly.sbt ├── misc ├── suslik-logo.png ├── robosuslik-logo.png ├── suslik-logo-200.png ├── SuSlik_logo_64x64.png └── suslik-logo-small.png ├── suslik ├── .jvmopts ├── src ├── test │ ├── resources │ │ ├── synthesis │ │ │ ├── packed-tree │ │ │ │ ├── delete.syn │ │ │ │ └── unpack.syn │ │ │ ├── regression │ │ │ │ ├── not_equal.syn │ │ │ │ ├── be_or_not_be.syn │ │ │ │ ├── pure_syn1.syn │ │ │ │ ├── pure_syn2.syn │ │ │ │ ├── pure_syn3.syn │ │ │ │ └── extra_pure.syn │ │ │ ├── account │ │ │ │ ├── account.def │ │ │ │ ├── free-struct.syn │ │ │ │ ├── alloc-struct.syn │ │ │ │ └── update-struct.syn │ │ │ ├── certification │ │ │ │ ├── account │ │ │ │ │ ├── common.def │ │ │ │ │ └── mk-acc.syn │ │ │ │ ├── ints │ │ │ │ │ ├── max.syn │ │ │ │ │ ├── swap.syn │ │ │ │ │ ├── min2.syn │ │ │ │ │ └── swap2.syn │ │ │ │ ├── list │ │ │ │ │ ├── listcopy.syn │ │ │ │ │ ├── listmorph.syn │ │ │ │ │ ├── listfree.syn │ │ │ │ │ └── common.def │ │ │ │ ├── sll │ │ │ │ │ ├── common.def │ │ │ │ │ ├── sll-free.syn │ │ │ │ │ ├── sll-init.syn │ │ │ │ │ ├── sll-singleton.syn │ │ │ │ │ ├── sll-dupleton.syn │ │ │ │ │ ├── sll-append.syn │ │ │ │ │ └── sll-copy.syn │ │ │ │ ├── tree │ │ │ │ │ ├── tree-free.syn │ │ │ │ │ ├── tree-size.syn │ │ │ │ │ ├── tree-flatten-acc.syn │ │ │ │ │ ├── tree-copy.syn │ │ │ │ │ └── common.def │ │ │ │ ├── sll-bounds │ │ │ │ │ ├── common.def │ │ │ │ │ ├── sll-len.syn │ │ │ │ │ ├── sll-min.syn │ │ │ │ │ └── sll-max.syn │ │ │ │ ├── dll │ │ │ │ │ ├── dll-singleton.syn │ │ │ │ │ ├── common.def │ │ │ │ │ ├── dll-dupleton.syn │ │ │ │ │ └── dll-append.syn │ │ │ │ ├── srtl │ │ │ │ │ ├── srtl-prepend.syn │ │ │ │ │ ├── insertion-sort-free.syn │ │ │ │ │ ├── insertion-sort.syn │ │ │ │ │ └── common.def │ │ │ │ └── bst │ │ │ │ │ ├── common.def │ │ │ │ │ ├── bst-find-smallest.syn │ │ │ │ │ ├── bst-right-rotate.syn │ │ │ │ │ └── bst-left-rotate.syn │ │ │ ├── simple │ │ │ │ ├── emp.syn │ │ │ │ ├── frame.syn │ │ │ │ ├── write1.syn │ │ │ │ ├── free.syn │ │ │ │ ├── frame-write.syn │ │ │ │ ├── read-frame-write.syn │ │ │ │ ├── write2.syn │ │ │ │ ├── alloc.syn │ │ │ │ ├── free-block.syn │ │ │ │ ├── kareem1.syn │ │ │ │ ├── swap.syn │ │ │ │ ├── pointer1.syn │ │ │ │ ├── frame-backtrack2.syn │ │ │ │ ├── frame-backtrack.syn │ │ │ │ ├── blocks.syn │ │ │ │ ├── kareem.syn │ │ │ │ ├── swap1.syn │ │ │ │ ├── kareem2.syn │ │ │ │ └── swap2.syn │ │ │ ├── online │ │ │ │ ├── swap.syn │ │ │ │ ├── swap.sus │ │ │ │ ├── list-dispose.sus │ │ │ │ ├── tree-dispose.syn │ │ │ │ ├── tree-dispose.sus │ │ │ │ ├── list-append.sus │ │ │ │ ├── list-append.syn │ │ │ │ ├── list-copy.sus │ │ │ │ ├── tree-flatten.sus │ │ │ │ └── sorted-insert.syn │ │ │ ├── proofs │ │ │ │ ├── lseg.def │ │ │ │ └── induction.syn │ │ │ ├── entail │ │ │ │ ├── exists.syn │ │ │ │ ├── tauto.syn │ │ │ │ ├── inconsistency3.syn │ │ │ │ ├── star-partial.syn │ │ │ │ ├── subst-right.syn │ │ │ │ ├── inconsistency2.syn │ │ │ │ ├── subst-left.syn │ │ │ │ ├── strip-eq-l.syn │ │ │ │ ├── inconsistency.syn │ │ │ │ ├── nil-not-lval.syn │ │ │ │ ├── non-triv-pure.syn │ │ │ │ └── duplicator.syn │ │ │ ├── overloaded-ops │ │ │ │ ├── type-helper.syn │ │ │ │ ├── leq.syn │ │ │ │ ├── not-equal.syn │ │ │ │ ├── ambiguity.syn │ │ │ │ ├── bool-equality1.syn │ │ │ │ ├── star-multiply.syn │ │ │ │ ├── unary-minus.syn │ │ │ │ └── intervals.syn │ │ │ ├── copy │ │ │ │ ├── lseg.def │ │ │ │ ├── c1-copy-nil.syn │ │ │ │ ├── c2-no-copy-same.syn │ │ │ │ ├── c3-no-copy-unfold.syn │ │ │ │ ├── c5-alloc_value.syn │ │ │ │ ├── c6-alloc_head.syn │ │ │ │ ├── c4-copy_strip_frame.syn │ │ │ │ ├── list-append.syn │ │ │ │ ├── c8-alloc-close.syn │ │ │ │ ├── list_copy.syn │ │ │ │ ├── list_copy_hard.syn │ │ │ │ └── c7-frame-alloc-head.syn │ │ │ ├── sets │ │ │ │ ├── lseg.def │ │ │ │ ├── unify1.syn │ │ │ │ ├── exists_nil.syn │ │ │ │ ├── set_unify1.syn │ │ │ │ ├── addelem.syn │ │ │ │ ├── list_skip.syn │ │ │ │ ├── addelem1.syn │ │ │ │ └── unify2.syn │ │ │ ├── paper-benchmarks │ │ │ │ ├── sll │ │ │ │ │ ├── common.def │ │ │ │ │ ├── sll-free.syn │ │ │ │ │ ├── sll-init.syn │ │ │ │ │ ├── sll-singleton.syn │ │ │ │ │ ├── sll-dupleton.syn │ │ │ │ │ ├── sll-append.syn │ │ │ │ │ ├── sll-copy.syn │ │ │ │ │ └── sll-delete-all.syn │ │ │ │ ├── ints │ │ │ │ │ ├── swap.syn │ │ │ │ │ └── min2.syn │ │ │ │ ├── tree │ │ │ │ │ ├── tree-free.syn │ │ │ │ │ ├── tree-size.syn │ │ │ │ │ ├── tree-flatten-acc.syn │ │ │ │ │ ├── tree-copy.syn │ │ │ │ │ └── common.def │ │ │ │ ├── sll-bounds │ │ │ │ │ ├── common.def │ │ │ │ │ ├── sll-len.syn │ │ │ │ │ ├── sll-max.syn │ │ │ │ │ └── sll-min.syn │ │ │ │ ├── dll │ │ │ │ │ ├── dll-dupleton.syn │ │ │ │ │ ├── dll-singleton.syn │ │ │ │ │ ├── definitions.def │ │ │ │ │ └── dll-append.syn │ │ │ │ ├── srtl │ │ │ │ │ ├── srtl-prepend.syn │ │ │ │ │ ├── insertion-sort-free.syn │ │ │ │ │ ├── insertion-sort.syn │ │ │ │ │ └── common.def │ │ │ │ └── bst │ │ │ │ │ ├── common.def │ │ │ │ │ ├── bst-find-smallest.syn │ │ │ │ │ ├── bst-left-rotate.syn │ │ │ │ │ └── bst-right-rotate.syn │ │ │ ├── certification-benchmarks │ │ │ │ ├── ints │ │ │ │ │ ├── max.syn │ │ │ │ │ ├── swap2.syn │ │ │ │ │ ├── min.syn │ │ │ │ │ └── swap4.syn │ │ │ │ ├── sll │ │ │ │ │ ├── common.def │ │ │ │ │ ├── sll-free.syn │ │ │ │ │ ├── sll-singleton.syn │ │ │ │ │ ├── sll-append.syn │ │ │ │ │ └── sll-copy.syn │ │ │ │ ├── dll │ │ │ │ │ ├── common.def │ │ │ │ │ ├── dll-singleton.syn │ │ │ │ │ └── dll-append.syn │ │ │ │ ├── tree │ │ │ │ │ ├── tree-free.syn │ │ │ │ │ ├── tree-size.syn │ │ │ │ │ ├── tree-copy.syn │ │ │ │ │ └── common.def │ │ │ │ └── sll-bounds │ │ │ │ │ ├── common.def │ │ │ │ │ ├── sll-len.syn │ │ │ │ │ ├── sll-min.syn │ │ │ │ │ └── sll-max.syn │ │ │ ├── cyclic-benchmarks │ │ │ │ ├── rose-tree │ │ │ │ │ ├── rtree-free-simple.syn │ │ │ │ │ └── rose-tree-free.syn │ │ │ │ ├── dll │ │ │ │ │ ├── definitions.def │ │ │ │ │ └── multi-append.syn │ │ │ │ ├── sll │ │ │ │ │ ├── intersect.syn │ │ │ │ │ ├── predicates.def │ │ │ │ │ └── listfree2.syn │ │ │ │ ├── skiplist │ │ │ │ │ ├── skl-simple-flatten.syn │ │ │ │ │ └── skl-simple-free.syn │ │ │ │ ├── beyond │ │ │ │ │ ├── skl-len-length.syn │ │ │ │ │ ├── skil_to_srtl.syn │ │ │ │ │ ├── skl-simple-copy.syn │ │ │ │ │ ├── skl_to_bst.syn │ │ │ │ │ └── skl-free.syn │ │ │ │ ├── contrived │ │ │ │ │ ├── listfree.syn │ │ │ │ │ ├── treefree.syn │ │ │ │ │ ├── listfree2.syn │ │ │ │ │ ├── treelistfree.syn │ │ │ │ │ ├── treefree2.syn │ │ │ │ │ ├── predicates.def │ │ │ │ │ └── listfree3.syn │ │ │ │ ├── multi-list │ │ │ │ │ └── predicates.def │ │ │ │ └── tree │ │ │ │ │ ├── predicates.def │ │ │ │ │ └── treefree2.syn │ │ │ ├── copy-len │ │ │ │ ├── lseg.def │ │ │ │ ├── c1-copy-nil.syn │ │ │ │ ├── c2-no-copy-same.syn │ │ │ │ ├── c6-alloc-head.syn │ │ │ │ ├── c3-no-copy-unfold.syn │ │ │ │ ├── list-free-frame.syn │ │ │ │ ├── list-append-len.syn │ │ │ │ ├── list-free-ghost.syn │ │ │ │ ├── list-copy-len.syn │ │ │ │ ├── c8-alloc-close.syn │ │ │ │ ├── c7-frame-alloc-head.syn │ │ │ │ └── c4-copy-strip-frame.syn │ │ │ ├── certification-benchmarks-advanced │ │ │ │ ├── sll │ │ │ │ │ ├── common.def │ │ │ │ │ └── sll-dupleton.syn │ │ │ │ ├── srtl │ │ │ │ │ ├── srtl-prepend.syn │ │ │ │ │ ├── insertion-sort-free.syn │ │ │ │ │ ├── insertion-sort.syn │ │ │ │ │ └── common.def │ │ │ │ ├── dll │ │ │ │ │ ├── common.def │ │ │ │ │ └── dll-dupleton.syn │ │ │ │ └── bst │ │ │ │ │ ├── common.def │ │ │ │ │ ├── bst-find-smallest.syn │ │ │ │ │ ├── bst-right-rotate.syn │ │ │ │ │ └── bst-left-rotate.syn │ │ │ ├── paper-examples │ │ │ │ ├── 02-pick.syn │ │ │ │ ├── 04-urk.syn │ │ │ │ ├── 05-elem.syn │ │ │ │ ├── 01-swap.syn │ │ │ │ ├── 03-notsure.syn │ │ │ │ ├── 07-listfree.syn │ │ │ │ ├── predicates.def │ │ │ │ ├── 13-listmorph.syn │ │ │ │ └── 17-listcopy.syn │ │ │ ├── llist │ │ │ │ ├── list-semantic-frame.syn │ │ │ │ ├── llist-nil.syn │ │ │ │ ├── llist-free.syn │ │ │ │ ├── llist-free0.syn │ │ │ │ ├── llist-morph.syn │ │ │ │ ├── remove-last.syn │ │ │ │ ├── llist-free2.syn │ │ │ │ ├── list-len-ptr.syn │ │ │ │ ├── intersect_sll_with_2_elem_set.syn │ │ │ │ └── llist.def │ │ │ ├── cardio │ │ │ │ ├── cardio-frame.syn │ │ │ │ ├── cardio-close.syn │ │ │ │ ├── cardio-behead.syn │ │ │ │ ├── cardio-remove-last-base.syn │ │ │ │ ├── cardio-sll-copy.syn │ │ │ │ ├── cardio-fresh.syn │ │ │ │ └── cardio-remove-last-aux1.syn │ │ │ ├── smallfoot │ │ │ │ ├── business1.sf │ │ │ │ ├── tree_deallocate.sf │ │ │ │ ├── tree.sf │ │ │ │ └── queue.sf │ │ │ ├── ints │ │ │ │ ├── ints.syn │ │ │ │ └── inst2.syn │ │ │ ├── syntax │ │ │ │ └── accepts-new-syntax.sus │ │ │ ├── all-benchmarks │ │ │ │ ├── ints │ │ │ │ │ ├── swap.syn │ │ │ │ │ └── min2.syn │ │ │ │ ├── sll │ │ │ │ │ ├── free.syn │ │ │ │ │ ├── init.syn │ │ │ │ │ ├── singleton.syn │ │ │ │ │ ├── len.syn │ │ │ │ │ ├── append.syn │ │ │ │ │ ├── copy.syn │ │ │ │ │ ├── free2.syn │ │ │ │ │ ├── max.syn │ │ │ │ │ ├── min.syn │ │ │ │ │ ├── predicates.def │ │ │ │ │ └── delete-all.syn │ │ │ │ ├── rbt │ │ │ │ │ ├── rotate_c3.syn │ │ │ │ │ ├── is_red.syn │ │ │ │ │ └── size.syn │ │ │ │ ├── avl │ │ │ │ │ ├── free.syn │ │ │ │ │ ├── height.syn │ │ │ │ │ ├── size.syn │ │ │ │ │ └── copy.syn │ │ │ │ ├── tree │ │ │ │ │ ├── free.syn │ │ │ │ │ ├── size.syn │ │ │ │ │ ├── flatten-acc.syn │ │ │ │ │ ├── copy.syn │ │ │ │ │ └── free2.syn │ │ │ │ ├── srtl │ │ │ │ │ ├── prepend.syn │ │ │ │ │ ├── insertion-sort.syn │ │ │ │ │ └── insert.syn │ │ │ │ ├── dll │ │ │ │ │ ├── singleton.syn │ │ │ │ │ ├── definitions.def │ │ │ │ │ └── append.syn │ │ │ │ ├── multi-list │ │ │ │ │ └── predicates.def │ │ │ │ ├── bst │ │ │ │ │ ├── left-rotate.syn │ │ │ │ │ ├── right-rotate.syn │ │ │ │ │ ├── min.syn │ │ │ │ │ └── insert.syn │ │ │ │ ├── packed │ │ │ │ │ └── unpack.syn │ │ │ │ └── rose-tree │ │ │ │ │ └── free.syn │ │ │ ├── tree │ │ │ │ ├── tree-free.syn │ │ │ │ ├── tree-morph.syn │ │ │ │ ├── tree-size.syn │ │ │ │ ├── tree-size-ptr.syn │ │ │ │ ├── tree-copy-len-ptr.syn │ │ │ │ ├── tree-copy-len.syn │ │ │ │ ├── tree-copy.syn │ │ │ │ └── tree-copy-ptr.syn │ │ │ ├── dllist │ │ │ │ ├── dllist-set-prev.syn │ │ │ │ ├── llist-to-dllist-in-place.syn │ │ │ │ ├── dllist-to-llist.syn │ │ │ │ └── definitions.def │ │ │ ├── abduct │ │ │ │ ├── list-free-ptr.syn │ │ │ │ ├── tree-free-ptr.syn │ │ │ │ ├── list-copy-len-ptr.syn │ │ │ │ └── lseg.def │ │ │ └── flatten │ │ │ │ ├── definitions.def │ │ │ │ ├── tree-flatten-acc.syn │ │ │ │ └── tree-flatten.syn │ │ └── fixme-synthesis │ │ │ ├── failing-examples │ │ │ ├── one_or_two.syn │ │ │ ├── inc_or_dec.syn │ │ │ ├── free_incorrect.sus │ │ │ └── predicates.def │ │ │ ├── holes │ │ │ ├── malloc_free3.sus │ │ │ ├── swap_ghost.sus │ │ │ ├── if_ghost.sus │ │ │ ├── malloc_free1.sus │ │ │ ├── swap5.sus │ │ │ ├── swap6.sus │ │ │ ├── malloc_free2.sus │ │ │ ├── read_const.sus │ │ │ ├── swap1.sus │ │ │ ├── swap2.sus │ │ │ ├── swap3.sus │ │ │ ├── swap4.sus │ │ │ ├── destroy2.sus │ │ │ ├── read_offsets.sus │ │ │ ├── call_ghost_arg.sus │ │ │ ├── call_extra_arg.sus │ │ │ ├── call_insufficient_args.sus │ │ │ └── malloc_free4.sus │ │ │ └── failing-locally-for-ilya │ │ │ └── sll-delete-all.syn │ └── scala │ │ └── org │ │ └── tygus │ │ └── suslik │ │ ├── synthesis │ │ ├── CardioTests.scala │ │ ├── AccountTests.scala │ │ ├── AbductionTests.scala │ │ └── BasicSynthesisTests.scala │ │ ├── parsing │ │ └── TestNewSyntax.scala │ │ └── fixme │ │ └── FailingTests.scala ├── viz │ ├── tsconfig.json │ ├── index.html │ └── ts │ │ └── menu.css └── main │ └── scala │ └── org │ └── tygus │ └── suslik │ ├── language │ ├── package.scala │ ├── PrettyPrinting.scala │ └── HasExpressions.scala │ ├── certification │ ├── traversal │ │ ├── ProofTreePrinter.scala │ │ ├── Step.scala │ │ ├── ProofTree.scala │ │ ├── TranslatableOps.scala │ │ └── Interpreter.scala │ ├── Predicate.scala │ └── targets │ │ ├── htt │ │ ├── language │ │ │ ├── PrettyPrinting.scala │ │ │ └── package.scala │ │ └── translation │ │ │ ├── ProgramContext.scala │ │ │ ├── TranslatableOps.scala │ │ │ ├── ProofEvaluator.scala │ │ │ └── ProgramEvaluator.scala │ │ └── iris │ │ └── translation │ │ └── TranslatableOps.scala │ ├── SSLException.scala │ ├── synthesis │ ├── package.scala │ ├── tactics │ │ ├── Tactic.scala │ │ ├── ReplaySynthesis.scala │ │ └── InteractiveSynthesis.scala │ └── rules │ │ └── RuleUtils.scala │ ├── logic │ └── package.scala │ ├── util │ ├── StringUtil.scala │ └── OtherUtil.scala │ └── LanguageUtils.scala ├── examples ├── listfree.syn ├── treefree.syn ├── swap.syn ├── listmorph.syn ├── listcopy.syn ├── max.syn ├── mkacc.syn ├── append.syn ├── tree-flatten-acc.syn ├── srtl-insert.syn ├── tree-flatten.syn └── insertion-sort.syn ├── certify-benchmarks └── .ci └── install_z3.sh /project/assembly.sbt: -------------------------------------------------------------------------------- 1 | addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.7") -------------------------------------------------------------------------------- /misc/suslik-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TyGuS/suslik/HEAD/misc/suslik-logo.png -------------------------------------------------------------------------------- /misc/robosuslik-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TyGuS/suslik/HEAD/misc/robosuslik-logo.png -------------------------------------------------------------------------------- /misc/suslik-logo-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TyGuS/suslik/HEAD/misc/suslik-logo-200.png -------------------------------------------------------------------------------- /suslik: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | java -Dfile.encoding=UTF-8 -jar ./target/scala-2.12/suslik.jar $* 4 | -------------------------------------------------------------------------------- /misc/SuSlik_logo_64x64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TyGuS/suslik/HEAD/misc/SuSlik_logo_64x64.png -------------------------------------------------------------------------------- /misc/suslik-logo-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TyGuS/suslik/HEAD/misc/suslik-logo-small.png -------------------------------------------------------------------------------- /.jvmopts: -------------------------------------------------------------------------------- 1 | -Xms2048M 2 | -Xmx2048M 3 | -Xss6M 4 | -XX:ReservedCodeCacheSize=128m 5 | -XX:MaxMetaspaceSize=256m 6 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/packed-tree/delete.syn: -------------------------------------------------------------------------------- 1 | # -o 2 2 | 3 | ### 4 | 5 | { tree(x, sz, s) } 6 | void delete(loc x) 7 | { emp } -------------------------------------------------------------------------------- /examples/listfree.syn: -------------------------------------------------------------------------------- 1 | Listfree example 2 | 3 | ### 4 | 5 | {true; lseg(x, s)} 6 | void listfree(loc x) 7 | {true ; emp } 8 | 9 | ### -------------------------------------------------------------------------------- /examples/treefree.syn: -------------------------------------------------------------------------------- 1 | should be able to free a tree 2 | 3 | #### 4 | 5 | {true ; tree(x, s) } 6 | void treefree(loc x) 7 | {true ; emp } 8 | 9 | #### -------------------------------------------------------------------------------- /src/test/resources/synthesis/regression/not_equal.syn: -------------------------------------------------------------------------------- 1 | res != 5 2 | Runs out of rules 3 | ### 4 | { r:->was} 5 | void neq(loc r) 6 | { res != 5 ; r:->res} 7 | ### 8 | -------------------------------------------------------------------------------- /certify-benchmarks: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | scala -Dfile.encoding=UTF-8 -classpath target/scala-2.12/suslik.jar org.tygus.suslik.certification.CertificationBenchmarks $* 4 | -------------------------------------------------------------------------------- /examples/swap.syn: -------------------------------------------------------------------------------- 1 | Swapping example 2 | ### 3 | 4 | { x :-> a ** y :-> b } 5 | 6 | void swap(loc x, loc y) 7 | 8 | { x :-> b ** y :-> a } 9 | 10 | ### 11 | 12 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/account/account.def: -------------------------------------------------------------------------------- 1 | predicate account(loc x, int amount, int limit) { 2 | | true => { x :-> limit ** (x + 1) :-> amount ** [x, 2] } 3 | } 4 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification/account/common.def: -------------------------------------------------------------------------------- 1 | predicate account(loc x, int id, int bal) { 2 | | true => { [x, 2] ** x :-> id ** (x + 1) :-> bal } 3 | } 4 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/regression/be_or_not_be.syn: -------------------------------------------------------------------------------- 1 | Shakespeare 2 | runs out of rules 3 | ##### 4 | {true ; emp} 5 | void question(int v) 6 | { be \/ not be; emp} 7 | ##### -------------------------------------------------------------------------------- /src/test/resources/synthesis/simple/emp.syn: -------------------------------------------------------------------------------- 1 | should be able to synthesize an empty program 2 | ### 3 | {true; emp} void foo(loc x) {true ; emp} 4 | ### 5 | void foo (loc x) { 6 | } -------------------------------------------------------------------------------- /examples/listmorph.syn: -------------------------------------------------------------------------------- 1 | Morph lseg to lseg 2 2 | 3 | ### 4 | 5 | {r :-> 0 ** lseg(x, s)} 6 | 7 | void listmorph(loc x, loc r) 8 | 9 | {r :-> y ** lseg2(y, s) } 10 | 11 | ##### -------------------------------------------------------------------------------- /src/viz/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2019", 4 | "moduleResolution": "node", 5 | "allowSyntheticDefaultImports": true 6 | } 7 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/online/swap.syn: -------------------------------------------------------------------------------- 1 | swap values of two pointers 2 | 3 | ### 4 | 5 | {true; x :-> a ** y :-> b} void swap(loc x, loc y) {true ; x :-> b ** y :-> a} 6 | 7 | ### 8 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/online/swap.sus: -------------------------------------------------------------------------------- 1 | // swap values of two pointers 2 | 3 | void swap (loc x, loc y) 4 | {true ; x :-> a ** y :-> b } 5 | {true ; x :-> b ** y :-> a } 6 | { 7 | ?? 8 | } -------------------------------------------------------------------------------- /examples/listcopy.syn: -------------------------------------------------------------------------------- 1 | Copy a linked list 2 | 3 | ### 4 | 5 | { r :-> x ** lseg(x, s) } 6 | 7 | void listcopy(loc r) 8 | 9 | { true ; r :-> y ** lseg(x, s) ** lseg(y, s) } 10 | 11 | ##### -------------------------------------------------------------------------------- /examples/max.syn: -------------------------------------------------------------------------------- 1 | #. -b true 2 | maximum of two integers 3 | 4 | ### 5 | 6 | { r :-> null } 7 | 8 | void max (loc r, int x, int y) 9 | 10 | { x <= m /\ y <= m; r :-> m } 11 | 12 | ### 13 | -------------------------------------------------------------------------------- /examples/mkacc.syn: -------------------------------------------------------------------------------- 1 | #. -b true 2 | An account constructor 3 | 4 | ### 5 | 6 | { r :-> bal } 7 | 8 | void mk_acc (loc r, int id) 9 | 10 | { r :-> x ** account(x, id, bal) } 11 | 12 | ### 13 | -------------------------------------------------------------------------------- /src/test/resources/fixme-synthesis/failing-examples/one_or_two.syn: -------------------------------------------------------------------------------- 1 | one_or_two 2 | runs out of rules 3 | ##### 4 | {r :-> was} 5 | void one_or_two(loc r) 6 | { (ret == 1 ) \/ (ret == 2); r :-> ret} 7 | ##### -------------------------------------------------------------------------------- /src/test/resources/synthesis/proofs/lseg.def: -------------------------------------------------------------------------------- 1 | predicate lseg(loc x, loc y) { 2 | | x == y => { true ; emp } 3 | | not (x == y) => { true ; [x, 2] ** x :-> v ** (x + 1) :-> nxt ** lseg(nxt, y) } 4 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/entail/exists.syn: -------------------------------------------------------------------------------- 1 | should be able to synthesize existentials in the post 2 | ### 3 | { true ; x :-> e} 4 | void foo (loc x) 5 | { true ; x :-> a} 6 | ### 7 | void foo (loc x) { 8 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/simple/frame.syn: -------------------------------------------------------------------------------- 1 | should be able to synthesize an empty program with constant footprint 2 | ### 3 | {true; x :-> a} void foo(loc x) {true ; x :-> a} 4 | ### 5 | void foo (loc x) { 6 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/overloaded-ops/type-helper.syn: -------------------------------------------------------------------------------- 1 | type helper 2 | ##### 3 | 4 | {a==b; emp} 5 | void typing() [bool a, int k] 6 | { b == true \/ true; emp} 7 | ##### 8 | 9 | void typing () { 10 | } -------------------------------------------------------------------------------- /examples/append.syn: -------------------------------------------------------------------------------- 1 | singly-linked list: append 2 | 3 | ##### 4 | 5 | {true ; lseg(x1, s1) ** lseg(x2, s2) ** ret :-> x2} 6 | void lseg_append (loc x1, loc ret) 7 | {s =i s1 ++ s2 ; lseg(y, s) ** ret :-> y } 8 | 9 | ##### -------------------------------------------------------------------------------- /src/main/scala/org/tygus/suslik/language/package.scala: -------------------------------------------------------------------------------- 1 | package org.tygus.suslik 2 | 3 | /** 4 | * @author Ilya Sergey 5 | */ 6 | 7 | package object language { 8 | 9 | type Ident = String 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/main/scala/org/tygus/suslik/certification/traversal/ProofTreePrinter.scala: -------------------------------------------------------------------------------- 1 | package org.tygus.suslik.certification.traversal 2 | 3 | trait ProofTreePrinter[S <: Step] { 4 | def pp (tree: ProofTree[S]) : String 5 | } 6 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/simple/write1.syn: -------------------------------------------------------------------------------- 1 | should be able to synthesize a simple constant-assigning procedure 2 | ### 3 | {true; x :-> 1} void foo(loc x) {true ; x :-> 43} 4 | ### 5 | void foo (loc x) { 6 | *x = 43; 7 | } -------------------------------------------------------------------------------- /src/main/scala/org/tygus/suslik/language/PrettyPrinting.scala: -------------------------------------------------------------------------------- 1 | package org.tygus.suslik.language 2 | 3 | /** 4 | * @author Ilya Sergey 5 | */ 6 | 7 | trait PrettyPrinting { 8 | def pp : String = toString 9 | } 10 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/copy/lseg.def: -------------------------------------------------------------------------------- 1 | predicate lseg(loc x, loc y, set s) { 2 | | x == y => { s =i {} ; emp } 3 | | not (x == y) => { s =i {v} ++ s1 ; [x, 2] ** x :-> v ** (x + 1) :-> nxt ** lseg(nxt, y, s1) } 4 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/sets/lseg.def: -------------------------------------------------------------------------------- 1 | predicate lseg(loc x, loc y, set s) { 2 | | x == y => { s =i {} ; emp } 3 | | not (x == y) => { s =i {v} ++ s1 ; [x, 2] ** x :-> v ** (x + 1) :-> nxt ** lseg(nxt, y, s1) } 4 | } -------------------------------------------------------------------------------- /src/main/scala/org/tygus/suslik/certification/Predicate.scala: -------------------------------------------------------------------------------- 1 | package org.tygus.suslik.certification 2 | 3 | import org.tygus.suslik.language.PrettyPrinting 4 | 5 | trait Predicate extends PrettyPrinting { 6 | val name: String 7 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/paper-benchmarks/sll/common.def: -------------------------------------------------------------------------------- 1 | predicate sll(loc x, set s) { 2 | | x == 0 => { s =i {} ; emp } 3 | | not (x == 0) => { s =i {v} ++ s1 ; [x, 2] ** x :-> v ** (x + 1) :-> nxt ** sll(nxt, s1) } 4 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/regression/pure_syn1.syn: -------------------------------------------------------------------------------- 1 | expression with existential in a post points-to 2 | 3 | ### 4 | 5 | { x :-> 0 } 6 | void test(loc x) 7 | { a >= 0 ; x :-> 1 + a } 8 | 9 | ### 10 | 11 | ### 12 | 13 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification/ints/max.syn: -------------------------------------------------------------------------------- 1 | #. -b true 2 | maximum of two integers 3 | 4 | ### 5 | 6 | { r :-> 0 } 7 | 8 | void max (loc r, int x, int y) 9 | 10 | { x <= m /\ y <= m; r :-> m } 11 | 12 | ### 13 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification/list/listcopy.syn: -------------------------------------------------------------------------------- 1 | Copy a linked list 2 | 3 | ### 4 | 5 | { r :-> x ** lseg(x, s) } 6 | 7 | void listcopy(loc r) 8 | 9 | { true ; r :-> y ** lseg(x, s) ** lseg(y, s) } 10 | 11 | ##### -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification/sll/common.def: -------------------------------------------------------------------------------- 1 | predicate sll(loc x, set s) { 2 | | x == null => { s =i {} ; emp } 3 | | not (x == null) => { s =i {v} ++ s1 ; [x, 2] ** x :-> v ** (x + 1) :-> nxt ** sll(nxt, s1) } 4 | } 5 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/simple/free.syn: -------------------------------------------------------------------------------- 1 | should be able to deallocate memory 2 | ### 3 | {true; x :-> y ** [y, 1] ** y :-> 42} void delete(loc x) {true ; x :-> y } 4 | ### 5 | void delete (loc x) { 6 | let y = *x; 7 | free(y); 8 | } -------------------------------------------------------------------------------- /src/test/resources/fixme-synthesis/failing-examples/inc_or_dec.syn: -------------------------------------------------------------------------------- 1 | inc_or_dec 2 | ##### 3 | {r :-> was} 4 | void inc_or_dec(loc r, bool should_inc) 5 | { (should_inc /\ (ret == was + 1 )) \/ (not should_inc /\ (ret == was - 1)); r :-> ret} 6 | ##### -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification/account/mk-acc.syn: -------------------------------------------------------------------------------- 1 | #. -b true 2 | An account constructor 3 | 4 | ### 5 | 6 | { r :-> bal } 7 | 8 | void mk_acc (loc r, int id) 9 | 10 | { r :-> x ** account(x, id, bal) } 11 | 12 | ### 13 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/entail/tauto.syn: -------------------------------------------------------------------------------- 1 | should be able to get rid of tautologies in the post 2 | ### 3 | { y == x ; x :-> a } void bar(loc x, loc y) { (x == x) /\ (x == y) ; x :-> 4 } 4 | ### 5 | void bar (loc x, loc y) { 6 | *y = 4; 7 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/overloaded-ops/leq.syn: -------------------------------------------------------------------------------- 1 | leq 2 | ##### 3 | 4 | {a <= b; r :-> was} 5 | void star(int a, int b, loc r) 6 | { {res} <= {4,a}; r :-> res} 7 | ##### 8 | 9 | void star (int a, int b, loc r) { 10 | *r = a; 11 | } -------------------------------------------------------------------------------- /src/test/resources/fixme-synthesis/holes/malloc_free3.sus: -------------------------------------------------------------------------------- 1 | /* malloc var already used */ 2 | 3 | void nop(loc x, loc y) 4 | {} 5 | {} 6 | { 7 | let yy = malloc(15); 8 | let yy = malloc(20); 9 | free(yy); 10 | } 11 | 12 | ### 13 | ERROR -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification-benchmarks/ints/max.syn: -------------------------------------------------------------------------------- 1 | #. -b true 2 | maximum of two integers 3 | 4 | ### 5 | 6 | { r :-> 0 } 7 | 8 | void max (loc r, int x, int y) 9 | 10 | { x <= m /\ y <= m; r :-> m } 11 | 12 | ### 13 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/cyclic-benchmarks/rose-tree/rtree-free-simple.syn: -------------------------------------------------------------------------------- 1 | # -o 2 -p true 2 | 3 | should be able to deallocate a rose tree 4 | 5 | ### 6 | 7 | { rtree(x) } 8 | void rtfree(loc x) 9 | { emp } 10 | 11 | ### 12 | 13 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/overloaded-ops/not-equal.syn: -------------------------------------------------------------------------------- 1 | not equal 2 | ##### 3 | {a < b;r :-> was} 4 | void star(int a, int b, loc r) 5 | { {res,4} != {4,a}; r :-> res} 6 | ##### 7 | 8 | void star (int a, int b, loc r) { 9 | *r = b; 10 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/simple/frame-write.syn: -------------------------------------------------------------------------------- 1 | should be able to use [frame] and [write] 2 | ### 3 | {true; x :-> a ** y :-> 2} void bar(loc x, loc y) {true ; x :-> a ** y :-> 12} 4 | ### 5 | void bar (loc x, loc y) { 6 | *y = 12; 7 | } 8 | 9 | -------------------------------------------------------------------------------- /src/test/resources/fixme-synthesis/holes/swap_ghost.sus: -------------------------------------------------------------------------------- 1 | /* swap with a ghost bug*/ 2 | 3 | void swap(loc x, loc y) 4 | { x :-> a ** y :-> b } 5 | { x :-> b ** y :-> a } 6 | { 7 | *x = b; 8 | *y = a; 9 | } 10 | 11 | ### 12 | ERROR 13 | 14 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification-benchmarks/sll/common.def: -------------------------------------------------------------------------------- 1 | predicate sll(loc x, set s) { 2 | | x == null => { s =i {} ; emp } 3 | | not (x == null) => { s =i {v} ++ s1 ; [x, 2] ** x :-> v ** (x + 1) :-> nxt ** sll(nxt, s1) } 4 | } 5 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/copy-len/lseg.def: -------------------------------------------------------------------------------- 1 | predicate lseg(loc x, loc y, int len) { 2 | | x == y => { len == 0 ; emp } 3 | | not (x == y) => { len == 1 + len1 /\ 0 <= len1 ; [x, 2] ** x :-> v ** (x + 1) :-> nxt ** lseg(nxt, y, len1) } 4 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification-benchmarks-advanced/sll/common.def: -------------------------------------------------------------------------------- 1 | predicate sll(loc x, set s) { 2 | | x == null => { s =i {} ; emp } 3 | | not (x == null) => { s =i {v} ++ s1 ; [x, 2] ** x :-> v ** (x + 1) :-> nxt ** sll(nxt, s1) } 4 | } 5 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/entail/inconsistency3.syn: -------------------------------------------------------------------------------- 1 | should be able to handle inconsistent preconditions 2 | ### 3 | { false; x :-> y ** y :-> z} 4 | void foo(loc x, loc y) 5 | { true; y :-> 5 ** x :-> y} 6 | ### 7 | void foo (loc x, loc y) { 8 | error; 9 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/paper-examples/02-pick.syn: -------------------------------------------------------------------------------- 1 | Example (2) from the paper (pick) 2 | 3 | ### 4 | { x :-> 239 ** y :-> 30 } 5 | void pick(loc x, loc y) 6 | { x :-> e ** y :-> e } 7 | ### 8 | 9 | void pick (loc x, loc y) { 10 | *y = 239; 11 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/regression/pure_syn2.syn: -------------------------------------------------------------------------------- 1 | # --extended true 2 | 3 | expression with existential in a post points-to 4 | 5 | ### 6 | 7 | { x :-> y } 8 | void test(loc x) 9 | { z > y ; x :-> z } 10 | 11 | ### 12 | 13 | ### 14 | 15 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/regression/pure_syn3.syn: -------------------------------------------------------------------------------- 1 | # --extended true 2 | 3 | expression with existential in a post points-to 4 | 5 | ### 6 | 7 | { x :-> a + 1 } 8 | void test(loc x) 9 | { x :-> a + 2 } 10 | 11 | ### 12 | 13 | ### 14 | 15 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/cyclic-benchmarks/dll/definitions.def: -------------------------------------------------------------------------------- 1 | predicate dll(loc x, loc z, set s) { 2 | | x == 0 => { s =i {} ; emp } 3 | | not (x == 0) => 4 | { s =i {v} ++ s1 ; [x, 3] ** x :-> v ** (x + 1) :-> w ** (x + 2) :-> z ** dll(w, x, s1) } 5 | } 6 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/entail/star-partial.syn: -------------------------------------------------------------------------------- 1 | should be able to handle * partiality 2 | ### 3 | { a == x /\ y == a ; x :-> y ** y :-> z} 4 | void foo (loc x, loc y) 5 | { x == 2 ; y :-> a ** x :-> y} 6 | ### 7 | void foo (loc x, loc y) { 8 | error; 9 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/entail/subst-right.syn: -------------------------------------------------------------------------------- 1 | should be able to synthesize existentials in the post 2 | ### 3 | { z == 5; x :-> y ** y :-> z} 4 | void foo (loc x, loc y) 5 | { 5 == a /\ x == x ; y :-> a ** x :-> y} 6 | ### 7 | void foo (loc x, loc y) { 8 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification/list/listmorph.syn: -------------------------------------------------------------------------------- 1 | Morphs a list from one representation to another 2 | 3 | ### 4 | 5 | {true ; r :-> null ** lseg2(x, null, s)} 6 | void listmorph(loc x, loc r) 7 | {true ; r :-> y ** lseg(y, s) } 8 | 9 | ##### 10 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/entail/inconsistency2.syn: -------------------------------------------------------------------------------- 1 | should be able to handle inconsistent preconditions 2 | ### 3 | { y < z /\ z < y; x :-> y ** y :-> z} 4 | void foo(loc x, loc y) 5 | { true; y :-> 5 ** x :-> y} 6 | ### 7 | void foo (loc x, loc y) { 8 | error; 9 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/entail/subst-left.syn: -------------------------------------------------------------------------------- 1 | should be able to substitute equalities 2 | ### 3 | { 5 == z /\ y == a ; x :-> y ** y :-> z} 4 | void foo (loc x, loc y) 5 | { x == x /\ a == y /\ true ; y :-> 5 ** x :-> y} 6 | ### 7 | void foo (loc x, loc y) { 8 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/overloaded-ops/ambiguity.syn: -------------------------------------------------------------------------------- 1 | ambiguity 2 | ##### 3 | predicate ambiguous(loc x, set s) { 4 | | x == 0 => { www==www ; emp } 5 | } 6 | 7 | {true ; emp} void foo (int v) {a==a ; ambiguous(q,w)} 8 | ##### 9 | void foo (int v) { 10 | } -------------------------------------------------------------------------------- /src/main/scala/org/tygus/suslik/certification/targets/htt/language/PrettyPrinting.scala: -------------------------------------------------------------------------------- 1 | package org.tygus.suslik.certification.targets.htt.language 2 | 3 | trait PrettyPrinting { 4 | def pp: String = toString 5 | def getIndent(depth: Int): String = " " * depth 6 | } 7 | -------------------------------------------------------------------------------- /src/test/resources/fixme-synthesis/holes/if_ghost.sus: -------------------------------------------------------------------------------- 1 | /* if ghost */ 2 | 3 | 4 | void if_ghost (loc x) 5 | { true; x :-> was } 6 | { true; x :-> 1 } 7 | { 8 | if (password == 0) { 9 | *x = 1; 10 | } else { 11 | *x = 1; 12 | } 13 | } 14 | ### 15 | ERROR -------------------------------------------------------------------------------- /src/test/resources/synthesis/entail/strip-eq-l.syn: -------------------------------------------------------------------------------- 1 | should be able to discharge trivial equalities in the precondition 2 | ### 3 | { z == 5 /\ x == x ; x :-> y ** y :-> z} 4 | void foo(loc x, loc y) 5 | { true ; y :-> 5 ** x :-> y} 6 | ### 7 | void foo (loc x, loc y) { 8 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/llist/list-semantic-frame.syn: -------------------------------------------------------------------------------- 1 | test case for semantic subst-L 2 | 3 | ##### 4 | 5 | { n + 1 == m + 1 /\ m - 1 == k - 1 ; lsegn(x, 0, n) } 6 | void noop(loc r) 7 | {true ; lsegn(x, 0, k) } 8 | 9 | ##### 10 | 11 | void noop (loc r) { 12 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/overloaded-ops/bool-equality1.syn: -------------------------------------------------------------------------------- 1 | notnot 2 | wow, it works. (Doesn't work if I remove bool b parameter) 3 | ##### 4 | {emp} 5 | void notnot(loc r, bool b) 6 | { c == (not not c);emp} 7 | ##### 8 | 9 | void notnot (loc r, bool b) { 10 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/overloaded-ops/star-multiply.syn: -------------------------------------------------------------------------------- 1 | star overloading 2 | ##### 3 | {r :-> was} 4 | void star(int a, int b, loc r) 5 | { res == x * y && x == a && y == b; r :-> res} 6 | ##### 7 | 8 | void star (int a, int b, loc r) { 9 | *r = a * b; 10 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/sets/unify1.syn: -------------------------------------------------------------------------------- 1 | Should solve the unification with empty sets 2 | 3 | ##### 4 | 5 | { S =i {v2} ++ S1 /\ S1 =i {} ; emp} 6 | void foo (int v) 7 | { S =i {v2} ++ S11 /\ S11 =i {} ; emp} 8 | 9 | ##### 10 | 11 | void foo (int v) { 12 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/simple/read-frame-write.syn: -------------------------------------------------------------------------------- 1 | should be able to synthesize a program with read 2 | ### 3 | {true; x :-> a ** y :-> 2} void bar(loc x, loc y) {true ; x :-> a ** y :-> a} 4 | ### 5 | void bar (loc x, loc y) { 6 | let a = *x; 7 | *y = a; 8 | } 9 | -------------------------------------------------------------------------------- /src/test/resources/fixme-synthesis/holes/malloc_free1.sus: -------------------------------------------------------------------------------- 1 | /* malloc free 1 */ 2 | 3 | void nop(loc x, loc y) 4 | {} 5 | {} 6 | { 7 | let yy = malloc(15); 8 | ?? 9 | } 10 | 11 | ### 12 | 13 | void nop (loc x, loc y) { 14 | let yy = malloc(15); 15 | free(yy); 16 | } -------------------------------------------------------------------------------- /src/test/resources/fixme-synthesis/holes/swap5.sus: -------------------------------------------------------------------------------- 1 | /* swap with a bug */ 2 | 3 | void swap(loc x, loc y) 4 | { x :-> a ** y :-> b } 5 | { x :-> b ** y :-> a } 6 | { 7 | let yy = *y; 8 | let xx = *x; 9 | *x = xx; 10 | *y = yy; 11 | } 12 | 13 | ### 14 | 15 | ERROR -------------------------------------------------------------------------------- /src/test/resources/synthesis/account/free-struct.syn: -------------------------------------------------------------------------------- 1 | should be able to deallocate structures 2 | ### 3 | {true; x :-> y ** account(y, 5, 10)} 4 | void deleteAccount(loc x) 5 | {true ; x :-> y } 6 | ### 7 | void deleteAccount (loc x) { 8 | let y = *x; 9 | free(y); 10 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification-benchmarks/dll/common.def: -------------------------------------------------------------------------------- 1 | predicate dll(loc x, loc z, set s) { 2 | | x == null => { s =i {} ; emp } 3 | | not (x == null) => 4 | { s =i {v} ++ s1 ; [x, 3] ** x :-> v ** (x + 1) :-> w ** (x + 2) :-> z ** dll(w, x, s1) } 5 | } 6 | 7 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/entail/inconsistency.syn: -------------------------------------------------------------------------------- 1 | should be able to handle inconsistent preconditions 2 | ### 3 | { y == z /\ not (y == z); x :-> y ** y :-> z} 4 | void foo(loc x, loc y) 5 | { true; y :-> 5 ** x :-> y} 6 | ### 7 | void foo (loc x, loc y) { 8 | error; 9 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/sets/exists_nil.syn: -------------------------------------------------------------------------------- 1 | Step 1: x-list is Nil, nothing to do here 2 | 3 | ##### 4 | 5 | {(x == 0) /\ S =i {} ; r :-> x} 6 | void list_copy(loc r) 7 | {true ; r :-> y ** lseg(y, 0, S) } 8 | 9 | ##### 10 | 11 | void list_copy (loc r) { 12 | } 13 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/sets/set_unify1.syn: -------------------------------------------------------------------------------- 1 | Should be able to unify simple facts about sets via *-hypothesis 2 | 3 | ##### 4 | 5 | { S =i {v} ++ S1 ; emp} 6 | 7 | void foo (loc x) 8 | 9 | {{v1} ++ S11 =i S ; emp} 10 | 11 | ##### 12 | 13 | void foo (loc x) { 14 | } -------------------------------------------------------------------------------- /src/test/resources/fixme-synthesis/holes/swap6.sus: -------------------------------------------------------------------------------- 1 | /* swap with a bug 2*/ 2 | 3 | void swap(loc x, loc y) 4 | { x :-> a ** y :-> b } 5 | { x :-> b ** y :-> a } 6 | { 7 | let yy = *y; 8 | *x = yy; 9 | let xx = *x; 10 | *y = xx; 11 | } 12 | 13 | ### 14 | ERROR 15 | 16 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/entail/nil-not-lval.syn: -------------------------------------------------------------------------------- 1 | should handle nil-values in the pure part 2 | 3 | ### 4 | 5 | { y == z /\ z == 0 ; x :-> y ** y :-> z} 6 | void foo(loc x, loc y) 7 | { x == 55 ; emp } 8 | 9 | ### 10 | 11 | void foo (loc x, loc y) { 12 | error; 13 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/entail/non-triv-pure.syn: -------------------------------------------------------------------------------- 1 | should be able to synthesize an empty program for a non-trivial pure part 2 | ### 3 | { x == x /\ y == x ; x :-> y} void bar(loc x, int y) { (x == x) /\ ((x == y) /\ true) ; x :-> y} 4 | ### 5 | void bar (loc x, int y) { 6 | } 7 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/simple/write2.syn: -------------------------------------------------------------------------------- 1 | should be able to synthesize a two-pointer constant-assigning procedure 2 | ### 3 | {true; x :-> 1 ** y :-> 2} void bar(loc x, loc y) {true ; y :-> 239 ** x :-> 43} 4 | ### 5 | void bar (loc x, loc y) { 6 | *x = 43; 7 | *y = 239; 8 | } -------------------------------------------------------------------------------- /examples/tree-flatten-acc.syn: -------------------------------------------------------------------------------- 1 | should be able to flatten the tree into a list given a list accumulator 2 | 3 | #### 4 | 5 | { true ; tree(x, s) ** z :-> y ** lseg(y, acc)} 6 | void tree_flatten(loc x, loc z) 7 | { s1 =i s ++ acc /\ c <= b + a; z :-> t ** lseg(t, s1)} 8 | 9 | #### -------------------------------------------------------------------------------- /src/test/resources/fixme-synthesis/holes/malloc_free2.sus: -------------------------------------------------------------------------------- 1 | /* malloc free 2 */ 2 | 3 | void nop(loc x, loc y) 4 | {} 5 | {} 6 | { 7 | let yy = malloc(15); 8 | free(yy); 9 | } 10 | 11 | ### 12 | 13 | void nop (loc x, loc y) { 14 | let yy = malloc(15); 15 | free(yy); 16 | } -------------------------------------------------------------------------------- /src/test/resources/fixme-synthesis/holes/read_const.sus: -------------------------------------------------------------------------------- 1 | /* read doesn't redefine values */ 2 | 3 | void swap(loc x, loc y) 4 | { x :-> a ** y :-> b } 5 | { x :-> b ** y :-> a } 6 | { 7 | let yy = *y; 8 | let xx = *x; 9 | let yy = *x; 10 | ?? 11 | } 12 | 13 | ### 14 | ERROR -------------------------------------------------------------------------------- /src/test/resources/synthesis/overloaded-ops/unary-minus.syn: -------------------------------------------------------------------------------- 1 | unary minus is not overloaded, but let it be in this folder 2 | ##### 3 | 4 | {true; r :-> was} 5 | void star(int b, loc r) 6 | { res == -b; r :-> res} 7 | ##### 8 | 9 | void star (int b, loc r) { 10 | *r = 0 - b; 11 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/sets/addelem.syn: -------------------------------------------------------------------------------- 1 | should be able to reason with singleton sets 2 | 3 | ##### 4 | 5 | { true ; x :-> a } 6 | 7 | void add(loc x, int e) 8 | 9 | { {e, a} =i {a, r} ; x :-> r } 10 | 11 | ###### 12 | 13 | void add (loc x, int e) { 14 | *x = e; 15 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/cardio/cardio-frame.syn: -------------------------------------------------------------------------------- 1 | 2 | should be able to synthesize list copy 3 | 4 | ##### 5 | 6 | {a >= 1 ; r :-> x ** sll_card(x, s)} 7 | void sll_copy(loc r) 8 | {0 < b ; r :-> y ** sll_card(y, s) } 9 | 10 | ##### 11 | 12 | void sll_copy (loc r) { 13 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/paper-examples/04-urk.syn: -------------------------------------------------------------------------------- 1 | Example (4) from the paper (urk) 2 | 3 | ### 4 | 5 | { a == x /\ y == a ; x :-> y ** y :-> z} 6 | void urk (loc x, loc y) 7 | { true ; y :-> a ** x :-> y} 8 | 9 | ### 10 | 11 | void urk (loc x, loc y) { 12 | error; 13 | } 14 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/smallfoot/business1.sf: -------------------------------------------------------------------------------- 1 | /* No race */ 2 | c; 3 | 4 | proc(x,y) [x|-> ] { 5 | x->c = y; 6 | } [x|-> c:y] 7 | 8 | main()[emp] { 9 | local x,z; 10 | x = new(); z= new(); x->c=3; z->c=3; 11 | proc(x,4); 12 | proc(z,5); 13 | } [x|->c:4 * z|-> c:5] 14 | -------------------------------------------------------------------------------- /src/main/scala/org/tygus/suslik/SSLException.scala: -------------------------------------------------------------------------------- 1 | package org.tygus.suslik 2 | 3 | /** 4 | * Generic exception 5 | * 6 | * @author Ilya Sergey 7 | */ 8 | 9 | abstract class SSLException(qualifier: String, val cause: String) 10 | extends Exception(s"[$qualifier] $cause") 11 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/simple/alloc.syn: -------------------------------------------------------------------------------- 1 | should be able to allocate memory 2 | 3 | ### 4 | {true; x :-> 0} 5 | void create(loc x) 6 | {true ; x :-> y ** y :-> 42 ** [y, 1]} 7 | 8 | ### 9 | 10 | void create (loc x) { 11 | let y = malloc(1); 12 | *x = y; 13 | *y = 42; 14 | } 15 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/simple/free-block.syn: -------------------------------------------------------------------------------- 1 | should be able to deallocate blocks 2 | ### 3 | {true; x :-> y ** y :-> 42 ** (y + 1) :-> 43 ** (y + 2) :-> 44 ** [y, 3]} 4 | void delete(loc x) 5 | {true ; x :-> y } 6 | ### 7 | void delete (loc x) { 8 | let y = *x; 9 | free(y); 10 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/simple/kareem1.syn: -------------------------------------------------------------------------------- 1 | should be able to work with a simple version of Kareem's example 2 | ### 3 | 4 | {true; x :-> v ** v :-> d} 5 | void kareem2(loc x) 6 | {true ; x :-> v ** v :-> x} 7 | 8 | ### 9 | void kareem2 (loc x) { 10 | let v = *x; 11 | *v = x; 12 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/paper-examples/05-elem.syn: -------------------------------------------------------------------------------- 1 | Example (5) from the paper (elem) 2 | 3 | ##### 4 | 5 | { S =i {v} ++ S1 ; x :-> a} 6 | 7 | void elem (loc x, int v) 8 | 9 | { S1 ++ {v1} =i S; x :-> v1 + 1} 10 | 11 | ##### 12 | 13 | void elem (loc x, int v) { 14 | *x = v + 1; 15 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/smallfoot/tree_deallocate.sf: -------------------------------------------------------------------------------- 1 | l,r; 2 | 3 | tree_deallocate(t) [tree(t)] { 4 | local i, j; 5 | if(t == NULL) {} 6 | else { 7 | i = t->l; 8 | j = t->r; 9 | tree_deallocate(i); 10 | tree_deallocate(j); 11 | dispose t; 12 | } 13 | } [emp] 14 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/sets/list_skip.syn: -------------------------------------------------------------------------------- 1 | should be able to synthesize programs with non-trivial lists 2 | 3 | ##### 4 | 5 | {true ; r :-> x ** lseg(x, 0, S)} 6 | void list_skip(loc x, loc r) 7 | {true ; r :-> x ** lseg(x, 0, S) } 8 | 9 | ### 10 | 11 | void list_skip (loc x, loc r) { 12 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification/ints/swap.syn: -------------------------------------------------------------------------------- 1 | Swapping example 2 | ### 3 | 4 | { x :-> a ** y :-> b } 5 | 6 | void swap(loc x, loc y) 7 | 8 | { x :-> b ** y :-> a } 9 | 10 | ### 11 | 12 | void swap (loc x, loc y) { 13 | let a2 = *x; 14 | let b2 = *y; 15 | *x = b2; 16 | *y = a2; 17 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/copy/c1-copy-nil.syn: -------------------------------------------------------------------------------- 1 | Step 1: x-list is Nil, nothing to do here 2 | 3 | ##### 4 | 5 | { x == 0 /\ S =i {} ; r :-> x ** lseg(x, 0, S) } 6 | void list_copy(loc r) 7 | { true ; r :-> y ** lseg(x, 0, S) ** lseg(y, 0, S) } 8 | 9 | ##### 10 | 11 | void list_copy (loc r) { 12 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/ints/ints.syn: -------------------------------------------------------------------------------- 1 | should be able to handle simple assertions about integers 2 | 3 | ### 4 | 5 | { x < y ; r :-> 0 } 6 | 7 | void maxish(loc r, int x, int y) 8 | 9 | { x <= m /\ y <= m; r :-> m } 10 | 11 | ### 12 | 13 | void maxish (loc r, int x, int y) { 14 | *r = y; 15 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/sets/addelem1.syn: -------------------------------------------------------------------------------- 1 | should be able to reason with singleton sets 2 | 3 | ##### 4 | 5 | { not (e == 0) ; x :-> a } 6 | 7 | void add(loc x, int e) 8 | 9 | { e in {r} /\ not (0 in ({r} ++ {r})) ; x :-> r } 10 | 11 | ###### 12 | 13 | void add (loc x, int e) { 14 | *x = e; 15 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/sets/unify2.syn: -------------------------------------------------------------------------------- 1 | Should solve the unification with empty sets - 2 2 | 3 | ##### 4 | 5 | { S =i {v} ++ S1 /\ S2 =i {} ; x :-> a} 6 | void elemInSet (loc x, int v) 7 | { {v1} ++ S1 =i S ++ S2; x :-> v1} 8 | 9 | ##### 10 | 11 | void elemInSet (loc x, int v) { 12 | *x = v; 13 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/copy-len/c1-copy-nil.syn: -------------------------------------------------------------------------------- 1 | Step 1: x-list is Nil, nothing to do here 2 | 3 | ##### 4 | 5 | {x == 0 /\ len == 0 ; r :-> x ** lseg(x, 0, len)} 6 | void list_copy(loc r) 7 | {true ; r :-> y ** lseg(x, 0, len) ** lseg(y, 0, len) } 8 | 9 | ##### 10 | 11 | void list_copy (loc r) { 12 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/cyclic-benchmarks/sll/intersect.syn: -------------------------------------------------------------------------------- 1 | # -b true -p true 2 | 3 | intersect two unique lists 4 | 5 | ##### 6 | 7 | { r :-> x ** ulist(x, s1) ** ulist(y, s2) } 8 | void intersect (loc r, loc y) 9 | { r :-> z ** ulist(z, s1 * s2) ** ulist(y, s2) } 10 | 11 | ##### 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/paper-examples/01-swap.syn: -------------------------------------------------------------------------------- 1 | Example (1) from the paper (swap) 2 | 3 | ### 4 | 5 | {true; x :-> a ** y :-> b} void swap(loc x, loc y) {true ; x :-> b ** y :-> a} 6 | 7 | ### 8 | 9 | void swap (loc x, loc y) { 10 | let a = *x; 11 | let b = *y; 12 | *x = b; 13 | *y = a; 14 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/simple/swap.syn: -------------------------------------------------------------------------------- 1 | should be able to synthesize a swap program 2 | 3 | ### 4 | 5 | {true; x :-> a ** y :-> b} void swap(loc x, loc y) {true ; x :-> b ** y :-> a} 6 | 7 | ### 8 | 9 | void swap (loc x, loc y) { 10 | let a = *x; 11 | let b = *y; 12 | *x = b; 13 | *y = a; 14 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/cyclic-benchmarks/dll/multi-append.syn: -------------------------------------------------------------------------------- 1 | # -p true -c 2 -f 1 2 | append multiple lists 3 | 4 | ### 5 | 6 | {true; r :-> unused ** dll(x, a, s1) ** dll(y, b, s2) ** dll(z, c, s3) } 7 | void append3(loc x, loc y, loc z, loc r) 8 | {s =i s1 ++ s2 ++ s3 ; r :-> v ** dll(v, d, s) } 9 | 10 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/paper-examples/03-notsure.syn: -------------------------------------------------------------------------------- 1 | Example (3) from the paper (notSure) 2 | 3 | ### 4 | {true ; x :-> a ** y :-> b ** a :-> 0} 5 | void notSure (loc x, loc y) 6 | {true ; x :-> a ** y :-> c ** c :-> 0} 7 | 8 | ### 9 | 10 | void notSure (loc x, loc y) { 11 | let a = *x; 12 | *y = a; 13 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification-benchmarks/ints/swap2.syn: -------------------------------------------------------------------------------- 1 | Swapping example 2 | ### 3 | 4 | { x :-> a ** y :-> b } 5 | 6 | void swap2(loc x, loc y) 7 | 8 | { x :-> b ** y :-> a } 9 | 10 | ### 11 | 12 | void swap2 (loc x, loc y) { 13 | let a2 = *x; 14 | let b2 = *y; 15 | *x = b2; 16 | *y = a2; 17 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/syntax/accepts-new-syntax.sus: -------------------------------------------------------------------------------- 1 | /* syntax V1 */ 2 | 3 | void typing() [bool a] 4 | {a==b; emp} 5 | { b == true \/ true; emp} 6 | {??} 7 | 8 | void vvvvvv(int a, int b, loc r) 9 | [int a, int b] 10 | {a!=b; r :->was} 11 | { res != a; r:-> res} 12 | 13 | ### 14 | 15 | void typing () { 16 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/all-benchmarks/ints/swap.syn: -------------------------------------------------------------------------------- 1 | should be able to synthesize a swap program 2 | 3 | ### 4 | 5 | {true; x :-> a ** y :-> b} void swap(loc x, loc y) {true ; x :-> b ** y :-> a} 6 | 7 | ### 8 | 9 | void swap (loc x, loc y) { 10 | let a = *x; 11 | let b = *y; 12 | *x = b; 13 | *y = a; 14 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/cardio/cardio-close.syn: -------------------------------------------------------------------------------- 1 | 2 | should be able to synthesize list copy 3 | 4 | ##### 5 | 6 | {s =i {v} ++ s1 /\ a == b + 2 ; [x, 2] ** x :-> v ** (x + 1) :-> nxt ** sll_card(nxt, s1)} 7 | void sll_copy(loc x) 8 | {true ; sll_card(x, s) } 9 | 10 | ##### 11 | 12 | void sll_copy (loc x) { 13 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/cyclic-benchmarks/skiplist/skl-simple-flatten.syn: -------------------------------------------------------------------------------- 1 | # -o 2 -p true 2 | 3 | [AuxRec] 4 | 5 | should be able to flatten a skip list to a SLL 6 | 7 | ### 8 | 9 | { r :-> x ** skl_simple(x, p, s) } 10 | void skl_simple_flatten(loc r, loc p) 11 | { r :-> y ** sll(y, s) } 12 | 13 | ### 14 | 15 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/online/list-dispose.sus: -------------------------------------------------------------------------------- 1 | // dispose a singly-linked list 2 | 3 | predicate list(loc x) { 4 | | x == 0 => { true ; emp } 5 | | x != 0 => { true ; [x, 2] ** x :-> v ** (x + 1) :-> y ** list(y) } 6 | } 7 | 8 | void dispose(loc x) 9 | {true ; list(x) } 10 | {true ; emp } 11 | { 12 | ?? 13 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/paper-benchmarks/ints/swap.syn: -------------------------------------------------------------------------------- 1 | should be able to synthesize a swap program 2 | 3 | ### 4 | 5 | {true; x :-> a ** y :-> b} void swap(loc x, loc y) {true ; x :-> b ** y :-> a} 6 | 7 | ### 8 | 9 | void swap (loc x, loc y) { 10 | let a = *x; 11 | let b = *y; 12 | *x = b; 13 | *y = a; 14 | } -------------------------------------------------------------------------------- /src/viz/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 |
10 |
11 | 12 | -------------------------------------------------------------------------------- /examples/srtl-insert.syn: -------------------------------------------------------------------------------- 1 | #. -b true -c 2 2 | sorted list: insert an element 3 | 4 | ##### 5 | 6 | {0 <= n /\ 0 <= k /\ k <= 7 ; r :-> k ** srtl(x, n, lo, hi) } 7 | void srtl_insert (loc x, loc r) 8 | {n1 == n + 1 /\ lo1 == (k <= lo ? k : lo) /\ hi1 == (hi <= k ? k : hi) ; r :-> y ** srtl(y, n1, lo1, hi1) } 9 | 10 | ##### 11 | -------------------------------------------------------------------------------- /src/test/resources/fixme-synthesis/holes/swap1.sus: -------------------------------------------------------------------------------- 1 | /* swap with holes 1 */ 2 | 3 | void swap(loc x, loc y) 4 | { x :-> a ** y :-> b } 5 | { x :-> b ** y :-> a } 6 | { 7 | let yy = *y; 8 | ?? 9 | } 10 | 11 | ### 12 | 13 | void swap (loc x, loc y) { 14 | let yy = *y; 15 | let a = *x; 16 | *x = yy; 17 | *y = a; 18 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/copy/c2-no-copy-same.syn: -------------------------------------------------------------------------------- 1 | Step 2: Recognise the same list in the post 2 | 3 | ##### 4 | 5 | { S1 =i {v} ++ S ; 6 | [x, 2] ** x :-> v ** (x + 1) :-> nxt ** lseg(nxt, 0, S)} 7 | 8 | void list_copy(loc x) 9 | 10 | {true ; lseg(x, 0, S1)} 11 | 12 | ##### 13 | 14 | void list_copy (loc x) { 15 | } 16 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/cyclic-benchmarks/beyond/skl-len-length.syn: -------------------------------------------------------------------------------- 1 | # -o 2 -x true -p true --lexi true 2 | 3 | should be able to compute the length of a skip list 4 | 5 | ### 6 | 7 | { r :-> z ** skl_len(x, p, s, n)
} 8 | void skl_simple_len(loc r, loc p) 9 | { r :-> n ** skl_len(x, p, s, n) } 10 | 11 | ### 12 | 13 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/regression/extra_pure.syn: -------------------------------------------------------------------------------- 1 | Swapping example 2 | adding useless conditions in pure part breaks the synthesis 3 | (with `a == 55` instead of `y == 55` works) 4 | ### 5 | 6 | { y==55 ;x :-> a ** y :-> b } 7 | 8 | void swap(loc x, loc y) 9 | 10 | {y==55 ; x :-> b ** y :-> a } 11 | 12 | ### 13 | 14 | nope -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification/list/listfree.syn: -------------------------------------------------------------------------------- 1 | Listfree example 2 | 3 | ### 4 | 5 | {true; lseg(x, s)} 6 | void listfree(loc x) 7 | {true ; emp } 8 | 9 | ### 10 | 11 | void listfree (loc x) { 12 | if (x == 0) { 13 | } else { 14 | let nxt2 = *(x + 1); 15 | listfree(nxt2); 16 | free(x); 17 | } 18 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/simple/pointer1.syn: -------------------------------------------------------------------------------- 1 | should be able to work with pointer offsets 2 | 3 | ### 4 | 5 | {true; x :-> a ** x + 1 :-> b} void swap(loc x, loc y) {true ; x :-> b ** x + 1 :-> a} 6 | 7 | ### 8 | 9 | void swap (loc x, loc y) { 10 | let a = *x; 11 | let b = *(x + 1); 12 | *x = b; 13 | *(x + 1) = a; 14 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/copy-len/c2-no-copy-same.syn: -------------------------------------------------------------------------------- 1 | Step 2: Recognise the same list in the post 2 | 3 | ##### 4 | 5 | { 0 <= len ; 6 | [x, 2] ** x :-> v ** (x + 1) :-> nxt ** lseg(nxt, 0, len) } 7 | 8 | void list_copy(loc x) 9 | 10 | { true ; lseg(x, 0, 1 + len) } 11 | 12 | ##### 13 | 14 | void list_copy (loc x) { 15 | } 16 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/ints/inst2.syn: -------------------------------------------------------------------------------- 1 | should be able to handle simple assertions about integers 2 | 3 | ### 4 | 5 | { x < y /\ y <= z ; r :-> a } 6 | 7 | void foo(loc r, int y, int x, int z) 8 | 9 | { x <= m /\ m <= y /\ m < z ; r :-> m } 10 | 11 | ### 12 | 13 | void foo (loc r, int y, int x, int z) { 14 | *r = x; 15 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/llist/llist-nil.syn: -------------------------------------------------------------------------------- 1 | should be able to allocate a linked list 2 | ### 3 | 4 | { true; r :-> 0 } 5 | void create_llist(loc z, loc r) 6 | { true ; r :-> x ** x :-> 0 ** [x, 1] ** lseg(z, z) } 7 | 8 | ### 9 | 10 | void create_llist (loc z, loc r) { 11 | let x = malloc(1); 12 | *r = x; 13 | *x = 0; 14 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/all-benchmarks/sll/free.syn: -------------------------------------------------------------------------------- 1 | should be able to deallocate a linked list 2 | ### 3 | 4 | { true; sll(x, s) } 5 | void sll_free(loc x) 6 | { true ; emp } 7 | 8 | ### 9 | 10 | void sll_free (loc x) { 11 | if (x == 0) { 12 | } else { 13 | let n = *(x + 1); 14 | sll_free(n); 15 | free(x); 16 | } 17 | } -------------------------------------------------------------------------------- /src/test/resources/fixme-synthesis/holes/swap2.sus: -------------------------------------------------------------------------------- 1 | /* swap with holes 2 */ 2 | 3 | void swap(loc x, loc y) 4 | { x :-> a ** y :-> b } 5 | { x :-> b ** y :-> a } 6 | { 7 | let yy = *y; 8 | let xx = *x; 9 | ?? 10 | } 11 | 12 | ### 13 | 14 | void swap (loc x, loc y) { 15 | let yy = *y; 16 | let xx = *x; 17 | *x = yy; 18 | *y = xx; 19 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/all-benchmarks/rbt/rotate_c3.syn: -------------------------------------------------------------------------------- 1 | # -o 2 -c 4 2 | 3 | cannot synthesise rotate 4 | 5 | ##### 6 | 7 | {true ; r :-> 0 ** treeN(a, na, 1, bna) ** treeN(b, nb, 0, bna) ** treeN(c, nc, 0, bna)} 8 | void rotate(loc r, loc a, loc b, loc c) 9 | {true ; r :-> x ** treeN(x, na + nb + nc + 2, 0, bna + 1) } 10 | 11 | ##### 12 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification/sll/sll-free.syn: -------------------------------------------------------------------------------- 1 | should be able to deallocate a linked list 2 | ### 3 | 4 | { true; sll(x, s) } 5 | void sll_free(loc x) 6 | { true ; emp } 7 | 8 | ### 9 | 10 | void sll_free (loc x) { 11 | if (x == 0) { 12 | } else { 13 | let n = *(x + 1); 14 | sll_free(n); 15 | free(x); 16 | } 17 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/paper-benchmarks/sll/sll-free.syn: -------------------------------------------------------------------------------- 1 | should be able to deallocate a linked list 2 | ### 3 | 4 | { true; sll(x, s) } 5 | void sll_free(loc x) 6 | { true ; emp } 7 | 8 | ### 9 | 10 | void sll_free (loc x) { 11 | if (x == 0) { 12 | } else { 13 | let n = *(x + 1); 14 | sll_free(n); 15 | free(x); 16 | } 17 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/paper-examples/07-listfree.syn: -------------------------------------------------------------------------------- 1 | Example (7) from the paper (listfree) 2 | 3 | ### 4 | 5 | {true; lseg(x, 0, S)} 6 | void listfree(loc x) 7 | {true ; emp } 8 | 9 | ### 10 | 11 | void listfree (loc x) { 12 | if (x == 0) { 13 | } else { 14 | let n = *(x + 1); 15 | listfree(n); 16 | free(x); 17 | } 18 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/proofs/induction.syn: -------------------------------------------------------------------------------- 1 | lemma: connected list segments 2 | 3 | ##### 4 | 5 | {true ; lseg(x, y) ** lseg(y, 0)} 6 | void lemma (loc x, loc y) 7 | {true ; lseg(x, 0) } 8 | 9 | ##### 10 | 11 | void lemma (loc x, loc y) { 12 | if (x == y) { 13 | } else { 14 | let nxt2 = *(x + 1); 15 | lemma(nxt2, y); 16 | } 17 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/simple/frame-backtrack2.syn: -------------------------------------------------------------------------------- 1 | should be able to unify c with a 2 | (This is an example for the paper) 3 | 4 | ### 5 | {true ; x :-> a ** y :-> b ** a :-> 0} 6 | void notsure (loc x, loc y) 7 | {true ; x :-> a ** y :-> c ** c :-> 0} 8 | 9 | ### 10 | 11 | void notsure (loc x, loc y) { 12 | let a = *x; 13 | *y = a; 14 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/account/alloc-struct.syn: -------------------------------------------------------------------------------- 1 | should be able to allocate structures 2 | ### 3 | {true; x :-> 0} 4 | void createAccount(loc x, int bal, int lim) 5 | {true ; x :-> y ** account(y, bal, lim) } 6 | ### 7 | void createAccount (loc x, int bal, int lim) { 8 | let y = malloc(2); 9 | *x = y; 10 | *y = lim; 11 | *(y + 1) = bal; 12 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/cyclic-benchmarks/beyond/skil_to_srtl.syn: -------------------------------------------------------------------------------- 1 | # -o 2 -x true -p true --lexi true 2 | 3 | [AuxRec] 4 | 5 | Should be able to flatten a skip list into a sorted list 6 | 7 | ### 8 | 9 | { r :-> x ** skl(x, p, s, n, lo, hi) } 10 | void skl_to_srtl(loc r, loc p) 11 | { r :-> y ** srtl(y, n, lo, hi) } 12 | 13 | ### 14 | 15 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/cyclic-benchmarks/contrived/listfree.syn: -------------------------------------------------------------------------------- 1 | Deallocate a linked list 2 | 3 | ### 4 | 5 | {true; list(x)} 6 | void listfree(loc x) 7 | {true ; emp } 8 | 9 | ### 10 | 11 | void listfree (loc x) { 12 | if (x == 0) { 13 | } else { 14 | let n = *x; 15 | listfree(n); 16 | free(x); 17 | } 18 | } 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/main/scala/org/tygus/suslik/synthesis/package.scala: -------------------------------------------------------------------------------- 1 | package org.tygus.suslik 2 | 3 | import org.tygus.suslik.language.Statements.{Solution, Statement} 4 | 5 | /** 6 | * @author Ilya Sergey 7 | */ 8 | 9 | package object synthesis { 10 | 11 | type Kont = Seq[Solution] => Solution 12 | 13 | val defaultConfig : SynConfig = new SynConfig 14 | } 15 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification-benchmarks/sll/sll-free.syn: -------------------------------------------------------------------------------- 1 | should be able to deallocate a linked list 2 | ### 3 | 4 | { true; sll(x, s) } 5 | void sll_free(loc x) 6 | { true ; emp } 7 | 8 | ### 9 | 10 | void sll_free (loc x) { 11 | if (x == 0) { 12 | } else { 13 | let n = *(x + 1); 14 | sll_free(n); 15 | free(x); 16 | } 17 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/llist/llist-free.syn: -------------------------------------------------------------------------------- 1 | should be able to deallocate a linked list 2 | ### 3 | 4 | {true; lseg(x, y)} 5 | void free_llist(loc x, loc y) 6 | {true ; emp } 7 | 8 | ### 9 | 10 | void free_llist (loc x, loc y) { 11 | if (x == y) { 12 | } else { 13 | let n = *(x + 1); 14 | free_llist(n, y); 15 | free(x); 16 | } 17 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/llist/llist-free0.syn: -------------------------------------------------------------------------------- 1 | should be able to deallocate a null-terminating linked list 2 | ### 3 | 4 | {true; lseg(r, 0)} 5 | void free_llist(loc r) 6 | {true ; emp} 7 | 8 | ### 9 | 10 | void free_llist (loc r) { 11 | if (r == 0) { 12 | } else { 13 | let n = *(r + 1); 14 | free_llist(n); 15 | free(r); 16 | } 17 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/simple/frame-backtrack.syn: -------------------------------------------------------------------------------- 1 | should be able to unify c with a (and not with b as it first tries) 2 | 3 | ### 4 | {true ; x :-> a ** y :-> b ** [a, 1] ** a :-> 0} 5 | void create(loc x, loc y) 6 | {true ; x :-> a ** y :-> c ** [c, 1] ** c :-> 0} 7 | 8 | ### 9 | 10 | void create (loc x, loc y) { 11 | let a = *x; 12 | *y = a; 13 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/all-benchmarks/ints/min2.syn: -------------------------------------------------------------------------------- 1 | #. -b true 2 | minimum of two integers 3 | 4 | ### 5 | 6 | { true ; r :-> 0 } 7 | 8 | void min2(loc r, int x, int y) 9 | 10 | { m <= x /\ m <= y; r :-> m } 11 | 12 | ### 13 | 14 | void min2 (loc r, int x, int y) { 15 | if (x <= y) { 16 | *r = x; 17 | } else { 18 | *r = y; 19 | } 20 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification/ints/min2.syn: -------------------------------------------------------------------------------- 1 | #. -b true 2 | minimum of two integers 3 | 4 | ### 5 | 6 | { true ; r :-> null } 7 | 8 | void min2(loc r, int x, int y) 9 | 10 | { m <= x /\ m <= y; r :-> m } 11 | 12 | ### 13 | 14 | void min2 (loc r, int x, int y) { 15 | if (x <= y) { 16 | *r = x; 17 | } else { 18 | *r = y; 19 | } 20 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/cyclic-benchmarks/beyond/skl-simple-copy.syn: -------------------------------------------------------------------------------- 1 | # -p true --lexi true 2 | 3 | [AuxRec] 4 | 5 | should be able to flatten a skip list to a SLL 6 | 7 | ### 8 | 9 | { r :-> x ** skl_simple(x, p, s) } 10 | void skl_simple_flatten(loc r, loc p, loc t) 11 | { r :-> y ** skl_simple(x, p, s) ** skl_simple(y, t, s) } 12 | 13 | ### 14 | 15 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/llist/llist-morph.syn: -------------------------------------------------------------------------------- 1 | should be able to morph a linked list 2 | ### 3 | 4 | {true; lseg(x, y)} 5 | void morph_llist(loc x, loc y) 6 | {true ; lseg1(x, y) } 7 | 8 | ### 9 | 10 | void morph_llist (loc x, loc y) { 11 | if (x == y) { 12 | } else { 13 | let n = *(x + 1); 14 | morph_llist(n, y); 15 | *x = 1; 16 | } 17 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/overloaded-ops/intervals.syn: -------------------------------------------------------------------------------- 1 | testing intervals 2 | 3 | ##### 4 | 5 | {x <= y && i1 == [x..y] && i3 == [] && i2 == i3 + [x] && s1 == {x, y} && s2 == {}; emp} 6 | void interval_test(int x, int y) 7 | {lower i1 == lower i2 && x in i1 && x in s1 && x in (i1 + i2) && x in (s1 + s2) ; emp} 8 | 9 | ##### 10 | 11 | void foo (int v) { 12 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/paper-benchmarks/ints/min2.syn: -------------------------------------------------------------------------------- 1 | #. -b true 2 | minimum of two integers 3 | 4 | ### 5 | 6 | { true ; r :-> 0 } 7 | 8 | void min2(loc r, int x, int y) 9 | 10 | { m <= x /\ m <= y; r :-> m } 11 | 12 | ### 13 | 14 | void min2 (loc r, int x, int y) { 15 | if (x <= y) { 16 | *r = x; 17 | } else { 18 | *r = y; 19 | } 20 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/all-benchmarks/sll/init.syn: -------------------------------------------------------------------------------- 1 | should be able to initialize a linked list 2 | ### 3 | 4 | { sll(x, s) } 5 | void sll_init(loc x, int v) 6 | { s1 <=i {v} ; sll(x, s1) } 7 | 8 | ### 9 | 10 | void sll_init (loc x, int v) { 11 | if (x == 0) { 12 | } else { 13 | let n = *(x + 1); 14 | sll_init(n, v); 15 | *x = v; 16 | } 17 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/online/tree-dispose.syn: -------------------------------------------------------------------------------- 1 | dispose a tree 2 | 3 | ### 4 | 5 | predicate tree(loc x, set s) { 6 | | x == 0 => {s =i {}; emp} 7 | | not (x == 0) => {s =i {v} ++ s1 ++ s2 ; [x, 3] ** x :-> v ** (x + 1) :-> l ** (x + 2) :-> r ** tree(l, s1) ** tree(r, s2)} 8 | } 9 | 10 | {true; tree(x, s)} void dispose(loc x) {true ; emp } 11 | 12 | ### -------------------------------------------------------------------------------- /src/test/resources/synthesis/simple/blocks.syn: -------------------------------------------------------------------------------- 1 | should be able to allocate blocks 2 | 3 | ##### 4 | 5 | {true; x :-> 0} 6 | void create(loc x) 7 | {true ; x :-> y ** [y, 3] ** y :-> 1 ** (y + 1) :-> 2 ** (y + 2) :-> x} 8 | 9 | #### 10 | 11 | void create (loc x) { 12 | let y = malloc(3); 13 | *x = y; 14 | *y = 1; 15 | *(y + 1) = 2; 16 | *(y + 2) = x; 17 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification-benchmarks/ints/min.syn: -------------------------------------------------------------------------------- 1 | #. -b true 2 | minimum of two integers 3 | 4 | ### 5 | 6 | { true ; r :-> null } 7 | 8 | void min(loc r, int x, int y) 9 | 10 | { m <= x /\ m <= y; r :-> m } 11 | 12 | ### 13 | 14 | void min (loc r, int x, int y) { 15 | if (x <= y) { 16 | *r = x; 17 | } else { 18 | *r = y; 19 | } 20 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/paper-benchmarks/sll/sll-init.syn: -------------------------------------------------------------------------------- 1 | should be able to initialize a linked list 2 | ### 3 | 4 | { sll(x, s) } 5 | void sll_init(loc x, int v) 6 | { s1 <=i {v} ; sll(x, s1) } 7 | 8 | ### 9 | 10 | void sll_init (loc x, int v) { 11 | if (x == 0) { 12 | } else { 13 | let n = *(x + 1); 14 | sll_init(n, v); 15 | *x = v; 16 | } 17 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/simple/kareem.syn: -------------------------------------------------------------------------------- 1 | should be able to work with Kareem's example 2 | ### 3 | {true; x :-> v ** y :-> b ** z :-> v ** v :-> d} 4 | void kareem1(loc x, loc y, loc z) 5 | {true ; x :-> y ** y :-> z ** z :-> x ** v :-> x} 6 | ### 7 | void kareem1 (loc x, loc y, loc z) { 8 | let v = *x; 9 | *x = y; 10 | *y = z; 11 | *z = x; 12 | *v = x; 13 | } -------------------------------------------------------------------------------- /examples/tree-flatten.syn: -------------------------------------------------------------------------------- 1 | should be able to flatten the tree into a list given an auxiliary function for list appending 2 | 3 | #### 4 | 5 | { lseg(x1, s1) ** lseg(x2, s2) ** ret :-> x2 } 6 | void lseg_append (loc x1, loc ret) 7 | { s =i s1 ++ s2 ; lseg(y, s) ** ret :-> y } 8 | 9 | { z :-> x ** tree(x, s) } 10 | void flatten(loc z) 11 | { z :-> y ** lseg(y, s) } 12 | 13 | #### -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification/sll/sll-init.syn: -------------------------------------------------------------------------------- 1 | should be able to initialize a linked list 2 | ### 3 | 4 | { true; sll(x, s) } 5 | void sll_init(loc x, int v) 6 | { s1 <=i {v} ; sll(x, s1) } 7 | 8 | ### 9 | 10 | void sll_init (loc x, int v) { 11 | if (x == 0) { 12 | } else { 13 | let n = *(x + 1); 14 | sll_init(n, v); 15 | *x = v; 16 | } 17 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/tree/tree-free.syn: -------------------------------------------------------------------------------- 1 | should be able to deallocate a tree 2 | ### 3 | 4 | {true; tree(x)} 5 | void free_tree(loc x) 6 | {true ; emp } 7 | 8 | ### 9 | 10 | void free_tree (loc x) { 11 | if (x == 0) { 12 | } else { 13 | let l = *(x + 1); 14 | let r = *(x + 2); 15 | free_tree(l); 16 | free_tree(r); 17 | free(x); 18 | } 19 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/cyclic-benchmarks/contrived/treefree.syn: -------------------------------------------------------------------------------- 1 | Deallocate a tree 2 | 3 | ### 4 | 5 | {true; tree(x)} 6 | void treefree(loc x) 7 | {true ; emp } 8 | 9 | ### 10 | 11 | void treefree (loc x) { 12 | if (x == 0) { 13 | } else { 14 | let l = *x; 15 | let r = *(x + 1); 16 | treefree(l); 17 | treefree(r); 18 | free(x); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/online/tree-dispose.sus: -------------------------------------------------------------------------------- 1 | /* dispose a tree */ 2 | 3 | predicate tree(loc x, set s) { 4 | | x == 0 => { s == {} ; emp } 5 | | x != 0 => { s == {v} + s1 + s2 ; [x, 3] ** x :-> v ** (x + 1) :-> l ** (x + 2) :-> r ** tree(l, s1) ** tree(r, s2) } 6 | } 7 | 8 | void dispose(loc x) 9 | {true; tree(x, s) } 10 | {true ; emp } 11 | { 12 | ?? 13 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/account/update-struct.syn: -------------------------------------------------------------------------------- 1 | should be able to update structs 2 | 3 | ### 4 | 5 | {true; x :-> y ** account(y, bal, lim)} 6 | void deposit(loc x, int amount) 7 | {newBal == bal + amount ; x :-> y ** account(y, newBal, lim) } 8 | 9 | ### 10 | 11 | void deposit (loc x, int amount) { 12 | let y = *x; 13 | let b = *(y + 1); 14 | *(y + 1) = b + amount; 15 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/all-benchmarks/avl/free.syn: -------------------------------------------------------------------------------- 1 | should be able to deallocate a tree 2 | ### 3 | 4 | {true; avl(x, n, h)} 5 | void avl_free(loc x) 6 | {true ; emp } 7 | 8 | ### 9 | 10 | void avl_free (loc x) { 11 | if (x == 0) { 12 | } else { 13 | let l = *(x + 1); 14 | let r = *(x + 2); 15 | avl_free(l); 16 | avl_free(r); 17 | free(x); 18 | } 19 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/all-benchmarks/tree/free.syn: -------------------------------------------------------------------------------- 1 | should be able to deallocate a tree 2 | ### 3 | 4 | {true; tree(x, s)} 5 | void tree_free(loc x) 6 | {true ; emp } 7 | 8 | ### 9 | 10 | void tree_free (loc x) { 11 | if (x == 0) { 12 | } else { 13 | let l = *(x + 1); 14 | let r = *(x + 2); 15 | tree_free(l); 16 | tree_free(r); 17 | free(x); 18 | } 19 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/cardio/cardio-behead.syn: -------------------------------------------------------------------------------- 1 | # -c 2 -o 2 -p true 2 | 3 | should be able to synthesize list beheading 4 | 5 | ##### 6 | 7 | { a > 0 ; r :-> x ** sll_card(x, s)} 8 | void behead(loc r) 9 | {b == a - 2 ; r :-> y ** sll_card(y, s1) } 10 | 11 | ##### 12 | 13 | void behead (loc r) { 14 | let x = *r; 15 | let n = *(x + 1); 16 | free(x); 17 | *r = n; 18 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/simple/swap1.syn: -------------------------------------------------------------------------------- 1 | should be able to synthesize a non-trivial swap program 2 | 3 | ### 4 | 5 | {true; x :-> a ** y :-> c ** z :-> b ** t :-> q } 6 | void swap (loc x, loc z, loc y, loc t) 7 | { true; x :-> c ** z :-> b ** t :-> q ** y :-> 41 } 8 | 9 | ### 10 | 11 | void swap (loc x, loc z, loc y, loc t) { 12 | let c = *y; 13 | *x = c; 14 | *y = 41; 15 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/cyclic-benchmarks/beyond/skl_to_bst.syn: -------------------------------------------------------------------------------- 1 | # -o 2 -x true -p true --lexi true 2 | 3 | [AuxRec] 4 | 5 | Should be able to convert a skip list into a BST, synthesising BST-insert 6 | 7 | ### 8 | 9 | { r :-> x ** skl(x, p, s, n, lo, hi) } 10 | void skl_to_srtl(loc r, loc p) 11 | { r :-> y ** bst(y, n, lo, hi) ** skl(x, p, s, n, lo, hi) } 12 | 13 | ### 14 | 15 | -------------------------------------------------------------------------------- /src/main/scala/org/tygus/suslik/logic/package.scala: -------------------------------------------------------------------------------- 1 | package org.tygus.suslik 2 | 3 | import org.tygus.suslik.language._ 4 | import org.tygus.suslik.language.Expressions._ 5 | 6 | package object logic { 7 | 8 | type Formals = List[(Var, SSLType)] 9 | type PredicateEnv = Map[Ident, InductivePredicate] 10 | type FunctionEnv = Map[Ident, FunSpec] 11 | type Gamma = Map[Var, SSLType] 12 | } 13 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/all-benchmarks/rbt/is_red.syn: -------------------------------------------------------------------------------- 1 | should be able to synthesize node colour 2 | 3 | ##### 4 | 5 | {0 <= n ; r :-> a ** treeN(x, n, cl, bn) } 6 | void is_red(loc x, loc r) 7 | {true ; r :-> cl ** treeN(x, n, cl, bn) } 8 | 9 | ##### 10 | 11 | void is_red (loc x, loc r) { 12 | if (x == 0) { 13 | *r = 0; 14 | } else { 15 | let c = *x; 16 | *r = c; 17 | } 18 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/copy/c3-no-copy-unfold.syn: -------------------------------------------------------------------------------- 1 | Step 3: Recognise the same list in the post - II 2 | 3 | ##### 4 | 5 | { S =i {v} ++ S1 ; 6 | [x, 2] ** x :-> v ** (x + 1) :-> nxt ** lseg(nxt, 0, S1)} 7 | 8 | void list_copy(loc x) 9 | 10 | {S =i {w} ++ S3 ; 11 | [x, 2] ** x :-> w ** (x + 1) :-> nxt1 ** lseg(nxt1, 0, S3)} 12 | 13 | ##### 14 | 15 | void list_copy (loc x) { 16 | } 17 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/entail/duplicator.syn: -------------------------------------------------------------------------------- 1 | should be able to synthesize a duplicator 2 | 3 | ### 4 | 5 | { [x,1] ** x :-> a ** r :-> b } 6 | void duplicate(loc x, loc r) 7 | { r :-> z ** z :-> a ** z + 1 :-> a ** [z,2] } 8 | 9 | ### 10 | 11 | void duplicate (loc x, loc r) { 12 | let a = *x; 13 | let z = malloc(2); 14 | free(x); 15 | *r = z; 16 | *z = a; 17 | *(z + 1) = a; 18 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/paper-benchmarks/tree/tree-free.syn: -------------------------------------------------------------------------------- 1 | should be able to deallocate a tree 2 | ### 3 | 4 | {true; tree(x, s)} 5 | void tree_free(loc x) 6 | {true ; emp } 7 | 8 | ### 9 | 10 | void tree_free (loc x) { 11 | if (x == 0) { 12 | } else { 13 | let l = *(x + 1); 14 | let r = *(x + 2); 15 | tree_free(l); 16 | tree_free(r); 17 | free(x); 18 | } 19 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification/sll/sll-singleton.syn: -------------------------------------------------------------------------------- 1 | #. -c 2 2 | singly-linked list: construct a list with one element 3 | 4 | ##### 5 | 6 | { true ; p :-> a } 7 | void sll_singleton (int x, loc p) 8 | { elems =i {x} ; p :-> y ** sll(y, elems) } 9 | 10 | ##### 11 | 12 | void sll_singleton (int x, loc p) { 13 | let y = malloc(2); 14 | *p = y; 15 | *(y + 1) = 0; 16 | *y = x; 17 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification/tree/tree-free.syn: -------------------------------------------------------------------------------- 1 | should be able to free a tree 2 | 3 | #### 4 | 5 | {true ; tree(x, s) } 6 | void tree_free(loc x) 7 | {true ; emp } 8 | 9 | #### 10 | 11 | void tree_free (loc x) { 12 | if (x == 0) { 13 | } else { 14 | let l2 = *(x + 1); 15 | let r2 = *(x + 2); 16 | tree_free(l2); 17 | tree_free(r2); 18 | free(x); 19 | } 20 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/copy-len/c6-alloc-head.syn: -------------------------------------------------------------------------------- 1 | Step 6: 2 | Add a head to a list 3 | 4 | ##### 5 | 6 | { len == 1 + len1 /\ 0 <= len1 ; r :-> t3 ** lseg(t3, 0, len1) } 7 | 8 | void list_copy(loc r, int v, loc t3) 9 | 10 | {true; r :-> Y ** lseg(Y, 0, len)} 11 | 12 | ##### 13 | 14 | void list_copy (loc r, int v, loc t3) { 15 | let Y = malloc(2); 16 | *r = Y; 17 | *(Y + 1) = t3; 18 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/all-benchmarks/sll/singleton.syn: -------------------------------------------------------------------------------- 1 | #. -c 2 2 | singly-linked list: construct a list with one element 3 | 4 | ##### 5 | 6 | { true ; ret :-> a } 7 | void sll_singleton (int x, loc ret) 8 | { elems =i {x} ; ret :-> y ** sll(y, elems) } 9 | 10 | ##### 11 | 12 | void sll_singleton (int x, loc ret) { 13 | let y = malloc(2); 14 | *ret = y; 15 | *(y + 1) = 0; 16 | *y = x; 17 | } -------------------------------------------------------------------------------- /src/main/scala/org/tygus/suslik/util/StringUtil.scala: -------------------------------------------------------------------------------- 1 | package org.tygus.suslik.util 2 | 3 | /** 4 | * @author Ilya Sergey 5 | */ 6 | 7 | object StringUtil { 8 | 9 | def mkSpaces(n: Int) : String = (for (i <- 0 until n) yield " ").mkString("") 10 | 11 | def withOffset(text:String, offset: Int):String = { 12 | mkSpaces(offset) + text.replace("\n", "\n" + mkSpaces(offset)) 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/all-benchmarks/srtl/prepend.syn: -------------------------------------------------------------------------------- 1 | sorted list: prepend an element 2 | 3 | ##### 4 | 5 | { n >= 0 && k == lower (s + [k]) ; r :-> a ** srtl(x, s, n) } 6 | void srtl_prepend (loc x, int k, loc r) 7 | { r :-> y ** srtl(y, s + [k], n + 1) } 8 | 9 | ##### 10 | 11 | void srtl_prepend (loc x, int k, loc r) { 12 | let y = malloc(2); 13 | *r = y; 14 | *(y + 1) = x; 15 | *y = k; 16 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/cardio/cardio-remove-last-base.syn: -------------------------------------------------------------------------------- 1 | # -c 2 -o 2 -p true 2 | 3 | should be able to synthesize removal of the last element of the list 4 | 5 | ##### 6 | 7 | { a == 2 ; r :-> x ** sll_card(x, s)} 8 | void remove_last(loc r) 9 | {b == a - 2 ; r :-> 0 ** sll_card(y, s1) } 10 | 11 | ##### 12 | 13 | void remove_last (loc r) { 14 | let x = *r; 15 | free(x); 16 | *r = 0; 17 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification-benchmarks/sll/sll-singleton.syn: -------------------------------------------------------------------------------- 1 | #. -c 2 2 | singly-linked list: construct a list with one element 3 | 4 | ##### 5 | 6 | { true ; p :-> a } 7 | void sll_singleton (int x, loc p) 8 | { elems =i {x} ; p :-> y ** sll(y, elems) } 9 | 10 | ##### 11 | 12 | void sll_singleton (int x, loc p) { 13 | let y = malloc(2); 14 | *p = y; 15 | *(y + 1) = 0; 16 | *y = x; 17 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification-benchmarks/tree/tree-free.syn: -------------------------------------------------------------------------------- 1 | should be able to free a tree 2 | 3 | #### 4 | 5 | {true ; tree(x, s) } 6 | void tree_free(loc x) 7 | {true ; emp } 8 | 9 | #### 10 | 11 | void tree_free (loc x) { 12 | if (x == 0) { 13 | } else { 14 | let l2 = *(x + 1); 15 | let r2 = *(x + 2); 16 | tree_free(l2); 17 | tree_free(r2); 18 | free(x); 19 | } 20 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification/sll-bounds/common.def: -------------------------------------------------------------------------------- 1 | predicate sll(loc x, int len, int lo, int hi) { 2 | | x == null => { len == 0 /\ lo == 7 /\ hi == 0 ; emp } 3 | | not (x == null) => { len == 1 + len1 /\ 0 <= len1 /\ lo == (v <= lo1 ? v : lo1) /\ hi == (hi1 <= v ? v : hi1) /\ 0 <= v /\ v <= 7; 4 | [x, 2] ** x :-> v ** (x + 1) :-> nxt ** sll(nxt, len1, lo1, hi1) } 5 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification/sll/sll-dupleton.syn: -------------------------------------------------------------------------------- 1 | # -c 3 2 | singly-linked list: construct a list with two elements 3 | 4 | ##### 5 | 6 | { true ; r :-> a } 7 | void sll_dupleton (int x, int y, loc r) 8 | { elems =i {x, y} ; r :-> z ** sll(z, elems) } 9 | 10 | ##### 11 | 12 | void sll_dupleton (int x, loc r) { 13 | let y2 = malloc(2); 14 | *y2 = x; 15 | *(y2 + 1) = 0; 16 | *r = y2; 17 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/copy/c5-alloc_value.syn: -------------------------------------------------------------------------------- 1 | Step 5: 2 | Allocate the right value 3 | 4 | ##### 5 | 6 | { S =i {v} ++ S1 /\ S1 =i {} /\ not (r == 0) ; r :-> 0} 7 | 8 | void foo(loc r, int v) 9 | 10 | { not (Y == 0) /\ S =i {v1} ++ Z1 ; r :-> Y ** [Y, 2] ** Y :-> v1 ** (Y + 1) :-> nxt} 11 | 12 | ##### 13 | 14 | void foo (loc r, int v) { 15 | let Y = malloc(2); 16 | *r = Y; 17 | *Y = v; 18 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/paper-benchmarks/sll-bounds/common.def: -------------------------------------------------------------------------------- 1 | predicate sll(loc x, int len, int lo, int hi) { 2 | | x == 0 => { len == 0 /\ lo == 7 /\ hi == 0 ; emp } 3 | | not (x == 0) => { len == 1 + len1 /\ 0 <= len1 /\ lo == (v <= lo1 ? v : lo1) /\ hi == (hi1 <= v ? v : hi1) /\ 0 <= v /\ v <= 7; 4 | [x, 2] ** x :-> v ** (x + 1) :-> nxt ** sll(nxt, len1, lo1, hi1) } 5 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/paper-benchmarks/sll/sll-singleton.syn: -------------------------------------------------------------------------------- 1 | #. -c 2 2 | singly-linked list: construct a list with one element 3 | 4 | ##### 5 | 6 | { true ; ret :-> a } 7 | void sll_singleton (int x, loc ret) 8 | { elems =i {x} ; ret :-> y ** sll(y, elems) } 9 | 10 | ##### 11 | 12 | void sll_singleton (int x, loc ret) { 13 | let y = malloc(2); 14 | *ret = y; 15 | *(y + 1) = 0; 16 | *y = x; 17 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/simple/kareem2.syn: -------------------------------------------------------------------------------- 1 | should be able to work with crazy indirection 2 | 3 | ### 4 | 5 | {true; x :-> a ** a :-> b ** b :-> c ** c :-> 42} 6 | void kareem3(loc x) 7 | {true ; x :-> 42 ** b :-> a ** a :-> c ** c :-> b} 8 | 9 | ### 10 | 11 | void kareem3 (loc x) { 12 | let a = *x; 13 | let b = *a; 14 | let c = *b; 15 | *x = 42; 16 | *a = c; 17 | *b = a; 18 | *c = b; 19 | } -------------------------------------------------------------------------------- /src/main/scala/org/tygus/suslik/certification/targets/htt/language/package.scala: -------------------------------------------------------------------------------- 1 | package org.tygus.suslik.certification.targets.htt 2 | 3 | import org.tygus.suslik.certification.targets.htt.language.Expressions.CVar 4 | import org.tygus.suslik.certification.targets.htt.language.Types.HTTType 5 | 6 | package object language { 7 | type CGamma = Map[CVar, HTTType] 8 | type CFormals = Seq[(CVar, HTTType)] 9 | } 10 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/dllist/dllist-set-prev.syn: -------------------------------------------------------------------------------- 1 | should be able to set the previous pointer of a doubly-linked list 2 | 3 | ####### 4 | 5 | { true; (prev + 1) :-> x ** dllseg(x, z, s) } 6 | void set_prev(loc x, loc prev) 7 | { true; (prev + 1) :-> x ** dllseg(x, prev, s)} 8 | 9 | ####### 10 | 11 | void set_prev (loc x, loc prev) { 12 | if (x == 0) { 13 | } else { 14 | *(x + 2) = prev; 15 | } 16 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification-benchmarks/sll-bounds/common.def: -------------------------------------------------------------------------------- 1 | predicate sll(loc x, int len, int lo, int hi) { 2 | | x == null => { len == 0 /\ lo == 7 /\ hi == 0 ; emp } 3 | | not (x == null) => { len == 1 + len1 /\ 0 <= len1 /\ lo == (v <= lo1 ? v : lo1) /\ hi == (hi1 <= v ? v : hi1) /\ 0 <= v /\ v <= 7; 4 | [x, 2] ** x :-> v ** (x + 1) :-> nxt ** sll(nxt, len1, lo1, hi1) } 5 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/paper-benchmarks/dll/dll-dupleton.syn: -------------------------------------------------------------------------------- 1 | # -c 3 2 | singly-linked list: construct a list with two elements 3 | 4 | ##### 5 | 6 | { ret :-> a } 7 | void dll_dupleton (int x, int y, loc ret) 8 | { elems =i {x, y} ; ret :-> z ** dll(z, 0, elems) } 9 | 10 | ##### 11 | 12 | void sll_dupleton (int x, loc ret) { 13 | let y2 = malloc(2); 14 | *y2 = x; 15 | *(y2 + 1) = 0; 16 | *ret = y2; 17 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/paper-benchmarks/sll/sll-dupleton.syn: -------------------------------------------------------------------------------- 1 | # -c 3 2 | singly-linked list: construct a list with two elements 3 | 4 | ##### 5 | 6 | { true ; ret :-> a } 7 | void sll_dupleton (int x, int y, loc ret) 8 | { elems =i {x, y} ; ret :-> z ** sll(z, elems) } 9 | 10 | ##### 11 | 12 | void sll_dupleton (int x, loc ret) { 13 | let y2 = malloc(2); 14 | *y2 = x; 15 | *(y2 + 1) = 0; 16 | *ret = y2; 17 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/all-benchmarks/dll/singleton.syn: -------------------------------------------------------------------------------- 1 | # -c 2 2 | singly-linked list: construct a list with one element 3 | 4 | ##### 5 | 6 | { ret :-> a } 7 | void dll_singleton (int x, loc ret) 8 | { elems =i {x} ; ret :-> y ** dll(y, 0, elems) } 9 | 10 | ##### 11 | 12 | void dll_singleton (int x, loc ret) { 13 | let y = malloc(3); 14 | *ret = y; 15 | *(y + 1) = 0; 16 | *(y + 2) = 0; 17 | *y = x; 18 | } 19 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification/dll/dll-singleton.syn: -------------------------------------------------------------------------------- 1 | #. -c 2 2 | doubly-linked list: construct a list with one element 3 | 4 | ##### 5 | 6 | { r :-> a } 7 | void dll_singleton (int x, loc r) 8 | { elems =i {x} ; r :-> y ** dll(y, null, elems) } 9 | 10 | ##### 11 | 12 | void dll_singleton (int x, loc r) { 13 | let y = malloc(3); 14 | *r = y; 15 | *(y + 1) = 0; 16 | *(y + 2) = 0; 17 | *y = x; 18 | } 19 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification/list/common.def: -------------------------------------------------------------------------------- 1 | predicate lseg(loc x, set s) { 2 | | x == null => { s =i {} ; emp } 3 | | not (x == null) => { s =i {v} ++ s1 ; [x, 2] ** x :-> v ** (x + 1) :-> nxt ** lseg(nxt, s1) } 4 | } 5 | 6 | predicate lseg2(loc x, loc y, set s) { 7 | | x == y => { s =i {} ; emp } 8 | | not (x == y) => { s =i {v} ++ s1 ; [x, 2] ** x :-> v ** (x + 1) :-> nxt ** lseg2(nxt, y, s1) } 9 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/abduct/list-free-ptr.syn: -------------------------------------------------------------------------------- 1 | should be able to deallocate a list from the pointer to a head 2 | ### 3 | 4 | {true; r :-> x ** lseg(x, 0, n)} 5 | void list_free(loc r) 6 | {true ; r :-> 0} 7 | 8 | ### 9 | 10 | void list_free (loc r) { 11 | let x = *r; 12 | if (x == 0) { 13 | } else { 14 | let n = *(x + 1); 15 | *x = n; 16 | list_free(x); 17 | free(x); 18 | *r = 0; 19 | } 20 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification-benchmarks-advanced/sll/sll-dupleton.syn: -------------------------------------------------------------------------------- 1 | # -c 3 2 | singly-linked list: construct a list with two elements 3 | 4 | ##### 5 | 6 | { true ; r :-> a } 7 | void sll_dupleton (int x, int y, loc r) 8 | { elems =i {x, y} ; r :-> z ** sll(z, elems) } 9 | 10 | ##### 11 | 12 | void sll_dupleton (int x, loc r) { 13 | let y2 = malloc(2); 14 | *y2 = x; 15 | *(y2 + 1) = 0; 16 | *r = y2; 17 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification-benchmarks/dll/dll-singleton.syn: -------------------------------------------------------------------------------- 1 | #. -c 2 2 | doubly-linked list: construct a list with one element 3 | 4 | ##### 5 | 6 | { r :-> a } 7 | void dll_singleton (int x, loc r) 8 | { elems =i {x} ; r :-> y ** dll(y, null, elems) } 9 | 10 | ##### 11 | 12 | void dll_singleton (int x, loc r) { 13 | let y = malloc(3); 14 | *r = y; 15 | *(y + 1) = 0; 16 | *(y + 2) = 0; 17 | *y = x; 18 | } 19 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification/srtl/srtl-prepend.syn: -------------------------------------------------------------------------------- 1 | sorted list: prepend an element 2 | 3 | ##### 4 | 5 | {0 <= n /\ 0 <= k /\ k <= 7 /\ k <= lo ; r :-> a ** srtl(x, n, lo, hi) } 6 | void srtl_prepend (loc x, int k, loc r) 7 | {n1 == n + 1 ; r :-> y ** srtl(y, n1, k, hi1) } 8 | 9 | ##### 10 | 11 | void srtl_prepend (loc x, int k, loc r) { 12 | let y = malloc(2); 13 | *r = y; 14 | *(y + 1) = x; 15 | *y = k; 16 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/copy-len/c3-no-copy-unfold.syn: -------------------------------------------------------------------------------- 1 | Step 3: Recognise the same list in the post - II 2 | 3 | ##### 4 | 5 | { len == 1 + len1 /\ 0 <= len1 ; 6 | [x, 2] ** x :-> v ** (x + 1) :-> nxt ** lseg(nxt, 0, len1)} 7 | 8 | void list_copy(loc x) 9 | 10 | { len == 1 + len2 /\ 0 <= len2 ; 11 | [x, 2] ** x :-> w ** (x + 1) :-> nxt1 ** lseg(nxt1, 0, len2)} 12 | 13 | ##### 14 | 15 | void list_copy (loc x) { 16 | } 17 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/llist/remove-last.syn: -------------------------------------------------------------------------------- 1 | # -x true 2 | Remove last element 3 | 4 | ### 5 | 6 | {true; ret :-> x ** lsegs(x, y, s) ** [y, 1] ** y :-> 0} 7 | void remove_last(loc ret, loc y) 8 | {true ; ret :-> z ** lsegs(z, 0, s) } 9 | 10 | ### 11 | 12 | void remove_last (loc ret, loc y) { 13 | let x = *ret; 14 | if (x == y) { 15 | free(x); 16 | *ret = 0; 17 | } else { 18 | remove_last(x, y); 19 | } 20 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/online/list-append.sus: -------------------------------------------------------------------------------- 1 | /* append two singly-linked lists */ 2 | 3 | predicate list(loc x, set s) { 4 | | x == 0 => { s == {} ; emp } 5 | | x != 0 => { s == {v} + s1 ; [x, 2] ** x :-> v ** (x + 1) :-> nxt ** list(nxt, s1) } 6 | } 7 | 8 | void append (loc x1, loc ret) 9 | { true ; list(x1, s1) ** list(x2, s2) ** ret :-> x2 } 10 | { s == s1 + s2 ; list(y, s) ** ret :-> y } 11 | { 12 | ?? 13 | } 14 | 15 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/online/list-append.syn: -------------------------------------------------------------------------------- 1 | append two singly-linked lists 2 | 3 | ### 4 | 5 | predicate list(loc x, set s) { 6 | | x == 0 => { s =i {} ; emp } 7 | | not (x == 0) => { s =i {v} ++ s1 ; [x, 2] ** x :-> v ** (x + 1) :-> nxt ** list(nxt, s1) } 8 | } 9 | 10 | { true ; list(x1, s1) ** list(x2, s2) ** ret :-> x2 } 11 | void append (loc x1, loc ret) 12 | { s =i s1 ++ s2 ; list(y, s) ** ret :-> y } 13 | 14 | ### -------------------------------------------------------------------------------- /src/test/resources/synthesis/paper-benchmarks/dll/dll-singleton.syn: -------------------------------------------------------------------------------- 1 | #. -c 2 2 | singly-linked list: construct a list with one element 3 | 4 | ##### 5 | 6 | { ret :-> a } 7 | void dll_singleton (int x, loc ret) 8 | { elems =i {x} ; ret :-> y ** dll(y, 0, elems) } 9 | 10 | ##### 11 | 12 | void dll_singleton (int x, loc ret) { 13 | let y = malloc(3); 14 | *ret = y; 15 | *(y + 1) = 0; 16 | *(y + 2) = 0; 17 | *y = x; 18 | } 19 | -------------------------------------------------------------------------------- /src/main/scala/org/tygus/suslik/certification/targets/htt/translation/ProgramContext.scala: -------------------------------------------------------------------------------- 1 | package org.tygus.suslik.certification.targets.htt.translation 2 | 3 | import org.tygus.suslik.certification.targets.htt.program.Statements.CStatement 4 | import org.tygus.suslik.certification.traversal.Evaluator.ClientContext 5 | import org.tygus.suslik.logic.Environment 6 | 7 | case class ProgramContext(env: Environment) extends ClientContext[CStatement] 8 | -------------------------------------------------------------------------------- /src/main/scala/org/tygus/suslik/certification/targets/htt/translation/TranslatableOps.scala: -------------------------------------------------------------------------------- 1 | package org.tygus.suslik.certification.targets.htt.translation 2 | 3 | import org.tygus.suslik.logic.Environment 4 | 5 | object TranslatableOps { 6 | implicit class Translatable[S](value: S) { 7 | def translate[D](implicit translator: HTTTranslator[S,D], env: Environment): D = { 8 | translator.translate(value) 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/paper-benchmarks/srtl/srtl-prepend.syn: -------------------------------------------------------------------------------- 1 | sorted list: prepend an element 2 | 3 | ##### 4 | 5 | {0 <= n /\ 0 <= k /\ k <= 7 /\ k <= lo ; r :-> a ** srtl(x, n, lo, hi) } 6 | void srtl_prepend (loc x, int k, loc r) 7 | {n1 == n + 1 ; r :-> y ** srtl(y, n1, k, hi1) } 8 | 9 | ##### 10 | 11 | void srtl_prepend (loc x, int k, loc r) { 12 | let y = malloc(2); 13 | *r = y; 14 | *(y + 1) = x; 15 | *y = k; 16 | } -------------------------------------------------------------------------------- /examples/insertion-sort.syn: -------------------------------------------------------------------------------- 1 | sorted list: insert an element 2 | 3 | ##### 4 | 5 | {0 <= n /\ 0 <= k /\ k <= 7 ; r :-> k ** srtl(x, n, lo, hi) } 6 | void srtl_insert (loc x, loc r) 7 | {n1 == n + 1 /\ lo1 == (k <= lo ? k : lo) /\ hi1 == (hi <= k ? k : hi) ; r :-> y ** srtl(y, n1, lo1, hi1) } 8 | 9 | { 0 <= n ; r :-> null ** sll(x, n, lo, hi) } 10 | void insertion_sort_free (loc x, loc r) 11 | { true ; r :-> y ** srtl(y, n, lo, hi) } 12 | 13 | ##### -------------------------------------------------------------------------------- /src/test/resources/synthesis/all-benchmarks/dll/definitions.def: -------------------------------------------------------------------------------- 1 | predicate dll(loc x, loc z, set s) { 2 | | x == 0 => { s =i {} ; emp } 3 | | not (x == 0) => 4 | { s =i {v} ++ s1 ; [x, 3] ** x :-> v ** (x + 1) :-> w ** (x + 2) :-> z ** dll(w, x, s1) } 5 | } 6 | 7 | predicate sll(loc x, set s) { 8 | | x == 0 => { s =i {} ; emp } 9 | | not (x == 0) => { s =i {v} ++ s1 ; [x, 2] ** x :-> v ** (x + 1) :-> nxt ** sll(nxt, s1) } 10 | } 11 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/cyclic-benchmarks/sll/predicates.def: -------------------------------------------------------------------------------- 1 | 2 | predicate sll(loc x, set s) { 3 | | x == 0 => { s == {} ; emp } 4 | | not (x == 0) => { s == {v} ++ s1 ; [x, 2] ** x :-> v ** (x + 1) :-> nxt ** sll(nxt, s1) } 5 | } 6 | 7 | predicate ulist(loc x, set s) { 8 | | x == 0 => { s == {} ; emp } 9 | | not (x == 0) => { s == {v} ++ s1 /\ not (v in s1); [x, 2] ** x :-> v ** (x + 1) :-> nxt ** ulist(nxt, s1) } 10 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/paper-benchmarks/dll/definitions.def: -------------------------------------------------------------------------------- 1 | predicate dll(loc x, loc z, set s) { 2 | | x == 0 => { s =i {} ; emp } 3 | | not (x == 0) => 4 | { s =i {v} ++ s1 ; [x, 3] ** x :-> v ** (x + 1) :-> w ** (x + 2) :-> z ** dll(w, x, s1) } 5 | } 6 | 7 | predicate sll(loc x, set s) { 8 | | x == 0 => { s =i {} ; emp } 9 | | not (x == 0) => { s =i {v} ++ s1 ; [x, 2] ** x :-> v ** (x + 1) :-> nxt ** sll(nxt, s1) } 10 | } 11 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/all-benchmarks/sll/len.syn: -------------------------------------------------------------------------------- 1 | singly-linked list: length 2 | 3 | ##### 4 | 5 | { 0 <= n ; ret :-> a ** sll_bounded(x, n, s) } 6 | void sll_len (loc x, loc ret) 7 | { ret :-> n ** sll_bounded(x, n, s) } 8 | 9 | ##### 10 | 11 | void sll_len (loc x, loc ret) { 12 | if (x == 0) { 13 | *ret = 0; 14 | } else { 15 | let n = *(x + 1); 16 | sll_len(n, ret); 17 | let l = *ret; 18 | *ret = l + 1; 19 | } 20 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification/dll/common.def: -------------------------------------------------------------------------------- 1 | predicate dll(loc x, loc z, set s) { 2 | | x == null => { s =i {} ; emp } 3 | | not (x == null) => 4 | { s =i {v} ++ s1 ; [x, 3] ** x :-> v ** (x + 1) :-> w ** (x + 2) :-> z ** dll(w, x, s1) } 5 | } 6 | 7 | predicate sll(loc x, set s) { 8 | | x == null => { s =i {} ; emp } 9 | | not (x == null) => { s =i {v} ++ s1 ; [x, 2] ** x :-> v ** (x + 1) :-> nxt ** sll(nxt, s1) } 10 | } 11 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/llist/llist-free2.syn: -------------------------------------------------------------------------------- 1 | should be able to deallocate a linked list in the presence of another list 2 | ### 3 | 4 | {true; lseg (a, b) ** lseg(x, y)} 5 | void free_llist2 (loc x, loc y, loc a, loc b) 6 | {true ; lseg(a, b) } 7 | 8 | ### 9 | 10 | void free_llist2 (loc x, loc y, loc a, loc b) { 11 | if (x == y) { 12 | } else { 13 | let n = *(x + 1); 14 | free_llist2(n, y, a, b); 15 | free(x); 16 | } 17 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/tree/tree-morph.syn: -------------------------------------------------------------------------------- 1 | should be able to morhp a tree 2 | 3 | (same cardinality is important) 4 | ### 5 | 6 | {true ; tree(x)} 7 | void morhp_tree(loc x, int i) 8 | {true ; tree_elem(x, i) } 9 | 10 | ### 11 | 12 | void morhp_tree (loc x, int i) { 13 | if (x == 0) { 14 | } else { 15 | let l = *(x + 1); 16 | let r = *(x + 2); 17 | morhp_tree(l, i); 18 | morhp_tree(r, i); 19 | *x = i; 20 | } 21 | } -------------------------------------------------------------------------------- /src/test/resources/fixme-synthesis/holes/swap3.sus: -------------------------------------------------------------------------------- 1 | /* swap with holes 3 */ 2 | 3 | void swap(loc x, loc y) 4 | { x :-> a ** y :-> b } 5 | { x :-> b ** y :-> a } 6 | { 7 | let yy = *y; 8 | let www = malloc(2); 9 | let xx = *x; 10 | *x = yy; 11 | ?? 12 | } 13 | 14 | ### 15 | 16 | void swap (loc x, loc y) { 17 | let yy = *y; 18 | let www = malloc(2); 19 | let xx = *x; 20 | *x = yy; 21 | free(www); 22 | *y = xx; 23 | } 24 | 25 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification-benchmarks-advanced/srtl/srtl-prepend.syn: -------------------------------------------------------------------------------- 1 | sorted list: prepend an element 2 | 3 | ##### 4 | 5 | {0 <= n /\ 0 <= k /\ k <= 7 /\ k <= lo ; r :-> a ** srtl(x, n, lo, hi) } 6 | void srtl_prepend (loc x, int k, loc r) 7 | {n1 == n + 1 ; r :-> y ** srtl(y, n1, k, hi1) } 8 | 9 | ##### 10 | 11 | void srtl_prepend (loc x, int k, loc r) { 12 | let y = malloc(2); 13 | *r = y; 14 | *(y + 1) = x; 15 | *y = k; 16 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/paper-examples/predicates.def: -------------------------------------------------------------------------------- 1 | predicate lseg(loc x, loc y, set s) { 2 | | x == y => { s =i {} ; emp } 3 | | not (x == y) => { s =i {v} ++ s1 ; [x, 2] ** x :-> v ** (x + 1) :-> nxt ** lseg(nxt, y, s1) } 4 | } 5 | 6 | predicate lseg2(loc x, set s) { 7 | | x == 0 => { s =i {} ; emp } 8 | | not (x == 0) => { s =i {v} ++ s1 ; [x, 3] ** x :-> v ** (x + 1) :-> v + 1 ** (x + 2) :-> nxt ** lseg2(nxt, s1) } 9 | } 10 | -------------------------------------------------------------------------------- /src/main/scala/org/tygus/suslik/util/OtherUtil.scala: -------------------------------------------------------------------------------- 1 | package org.tygus.suslik.util 2 | 3 | /** 4 | * @author Ilya Sergey 5 | */ 6 | 7 | object OtherUtil { 8 | // Todo: move to utils. Doesn't scala has same thing built in somewhere? 9 | class Accumulator[T]{ 10 | private var elements:List[T] = Nil 11 | 12 | def put(elem:T):Unit={ 13 | elements = elements ++ List(elem) 14 | } 15 | 16 | def get:List[T] = elements 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/viz/ts/menu.css: -------------------------------------------------------------------------------- 1 | 2 | ul[role=menu] { 3 | font-family: sans-serif; 4 | font-size: 10pt; 5 | line-height: 15pt; 6 | padding: 2px 0; 7 | background: #eeee; 8 | } 9 | 10 | ul[role=menu] > li > a { 11 | padding: 1px 1rem; 12 | } 13 | 14 | ul[role=menu] > li > a:hover { 15 | background: rgb(46, 103, 160); 16 | color: white; 17 | cursor: default; 18 | } 19 | 20 | button:focus, button:active { 21 | outline: none; 22 | } 23 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification/sll/sll-append.syn: -------------------------------------------------------------------------------- 1 | singly-linked list: append 2 | 3 | ##### 4 | 5 | {true ; sll(x1, s1) ** sll(x2, s2) ** r :-> x2} 6 | void sll_append (loc x1, loc r) 7 | {s =i s1 ++ s2 ; sll(y, s) ** r :-> y } 8 | 9 | ##### 10 | 11 | void sll_append (loc x1, loc r) { 12 | if (x1 == 0) { 13 | } else { 14 | let n = *(x1 + 1); 15 | sll_append(n, r); 16 | let y = *r; 17 | *(x1 + 1) = y; 18 | *r = x1; 19 | } 20 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/copy-len/list-free-frame.syn: -------------------------------------------------------------------------------- 1 | should be able to allocate to match the desired precondition of the function, 2 | i.e., by inferring the frame to be allocated (frame abduction!) 3 | ### 4 | 5 | {true; r :-> 0 ** lseg(x, 0, n)} 6 | void list_free(loc x) 7 | {true ; r :-> 0} 8 | 9 | ### 10 | 11 | void list_free (loc x) { 12 | if (x == 0) { 13 | } else { 14 | let n = *(x + 1); 15 | list_free(n); 16 | free(x); 17 | } 18 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/llist/list-len-ptr.syn: -------------------------------------------------------------------------------- 1 | should be able to synthesize list length from the root pointer 2 | 3 | ##### 4 | 5 | {0 <= n ; r :-> x ** lsegn(x, 0, n) } 6 | void list_len(loc r) 7 | {true ; r :-> n ** lsegn(x, 0, n) } 8 | 9 | ##### 10 | 11 | void list_len (loc r) { 12 | let x = *r; 13 | if (x == 0) { 14 | } else { 15 | let n = *(x + 1); 16 | *x = n; 17 | list_len(x); 18 | let l = *x; 19 | *r = 1 + l; 20 | } 21 | } -------------------------------------------------------------------------------- /src/test/resources/fixme-synthesis/holes/swap4.sus: -------------------------------------------------------------------------------- 1 | /* swap without holes */ 2 | 3 | void swap(loc x, loc y) 4 | { x :-> a ** y :-> b } 5 | { x :-> b ** y :-> a } 6 | { 7 | let yy = *y; 8 | let www = malloc(2); 9 | let xx = *x; 10 | *x = yy; 11 | *y = xx; 12 | free(www); 13 | } 14 | 15 | ### 16 | 17 | void swap (loc x, loc y) { 18 | let yy = *y; 19 | let www = malloc(2); 20 | let xx = *x; 21 | *x = yy; 22 | *y = xx; 23 | free(www); 24 | } 25 | 26 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification-benchmarks-advanced/dll/common.def: -------------------------------------------------------------------------------- 1 | predicate dll(loc x, loc z, set s) { 2 | | x == null => { s =i {} ; emp } 3 | | not (x == null) => 4 | { s =i {v} ++ s1 ; [x, 3] ** x :-> v ** (x + 1) :-> w ** (x + 2) :-> z ** dll(w, x, s1) } 5 | } 6 | 7 | predicate sll(loc x, set s) { 8 | | x == null => { s =i {} ; emp } 9 | | not (x == null) => { s =i {v} ++ s1 ; [x, 2] ** x :-> v ** (x + 1) :-> nxt ** sll(nxt, s1) } 10 | } 11 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/simple/swap2.syn: -------------------------------------------------------------------------------- 1 | should be able to synthesize a more complex swap program 2 | 3 | ### 4 | 5 | {true; x :-> a ** y :-> c ** z :-> b ** t :-> q } 6 | void swap (loc x, loc z, loc y, loc t) 7 | { true; x :-> q ** z :-> c ** t :-> a ** y :-> b } 8 | 9 | ### 10 | 11 | void swap (loc x, loc z, loc y, loc t) { 12 | let a = *x; 13 | let c = *y; 14 | let b = *z; 15 | let q = *t; 16 | *x = q; 17 | *y = b; 18 | *z = c; 19 | *t = a; 20 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/all-benchmarks/sll/append.syn: -------------------------------------------------------------------------------- 1 | singly-linked list: append 2 | 3 | ##### 4 | 5 | {true ; sll(x1, s1) ** sll(x2, s2) ** ret :-> x2} 6 | void sll_append (loc x1, loc ret) 7 | {s =i s1 ++ s2 ; sll(y, s) ** ret :-> y } 8 | 9 | ##### 10 | 11 | void sll_append (loc x1, loc ret) { 12 | if (x1 == 0) { 13 | } else { 14 | let n = *(x1 + 1); 15 | sll_append(n, ret); 16 | let y = *ret; 17 | *(x1 + 1) = y; 18 | *ret = x1; 19 | } 20 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification-benchmarks/sll/sll-append.syn: -------------------------------------------------------------------------------- 1 | singly-linked list: append 2 | 3 | ##### 4 | 5 | {true ; sll(x1, s1) ** sll(x2, s2) ** r :-> x2} 6 | void sll_append (loc x1, loc r) 7 | {s =i s1 ++ s2 ; sll(y, s) ** r :-> y } 8 | 9 | ##### 10 | 11 | void sll_append (loc x1, loc r) { 12 | if (x1 == 0) { 13 | } else { 14 | let n = *(x1 + 1); 15 | sll_append(n, r); 16 | let y = *r; 17 | *(x1 + 1) = y; 18 | *r = x1; 19 | } 20 | } -------------------------------------------------------------------------------- /src/main/scala/org/tygus/suslik/certification/traversal/Step.scala: -------------------------------------------------------------------------------- 1 | package org.tygus.suslik.certification.traversal 2 | 3 | import org.tygus.suslik.certification.traversal.Evaluator.DeferredsAction 4 | import org.tygus.suslik.language.PrettyPrinting 5 | 6 | trait Step extends PrettyPrinting 7 | 8 | object Step { 9 | trait SourceStep extends Step { 10 | def deferredsAction: DeferredsAction = DeferredsAction.CurrentLayer 11 | } 12 | trait DestStep extends Step 13 | } 14 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/paper-benchmarks/sll/sll-append.syn: -------------------------------------------------------------------------------- 1 | singly-linked list: append 2 | 3 | ##### 4 | 5 | {true ; sll(x1, s1) ** sll(x2, s2) ** ret :-> x2} 6 | void sll_append (loc x1, loc ret) 7 | {s =i s1 ++ s2 ; sll(y, s) ** ret :-> y } 8 | 9 | ##### 10 | 11 | void sll_append (loc x1, loc ret) { 12 | if (x1 == 0) { 13 | } else { 14 | let n = *(x1 + 1); 15 | sll_append(n, ret); 16 | let y = *ret; 17 | *(x1 + 1) = y; 18 | *ret = x1; 19 | } 20 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification/ints/swap2.syn: -------------------------------------------------------------------------------- 1 | should be able to synthesize a more complex swap program 2 | 3 | ### 4 | 5 | {true; x :-> a ** y :-> c ** z :-> b ** t :-> q } 6 | void swap2 (loc x, loc z, loc y, loc t) 7 | { true; x :-> q ** z :-> c ** t :-> a ** y :-> b } 8 | 9 | ### 10 | 11 | void swap2 (loc x, loc z, loc y, loc t) { 12 | let a = *x; 13 | let c = *y; 14 | let b = *z; 15 | let q = *t; 16 | *x = q; 17 | *y = b; 18 | *z = c; 19 | *t = a; 20 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification/sll-bounds/sll-len.syn: -------------------------------------------------------------------------------- 1 | singly-linked list: length 2 | 3 | ##### 4 | 5 | {0 <= n ; r :-> a ** sll(x, n, lo, hi) } 6 | void sll_len (loc x, loc r) 7 | {true ; r :-> n ** sll(x, n, lo, hi) } 8 | 9 | ##### 10 | 11 | void sll_len (loc x, loc r) {s 12 | if (x == null) { 13 | *r = 0; 14 | } else { 15 | let v = *x; 16 | let n = *(x + 1); 17 | sll_len(n, x); 18 | let l = *x; 19 | *r = 1 + l; 20 | *x = v; 21 | } 22 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification/sll-bounds/sll-min.syn: -------------------------------------------------------------------------------- 1 | singly-linked list: min 2 | 3 | ##### 4 | 5 | {true ; r :-> a ** sll(x, n, lo, hi) } 6 | void sll_min (loc x, loc r) 7 | {true ; r :-> lo ** sll(x, n, lo, hi) } 8 | 9 | ##### 10 | 11 | void sll_min (loc x, loc r) { 12 | if (x == 0) { 13 | *r = 7; 14 | } else { 15 | let v = *x; 16 | let n = *(x + 1); 17 | sll_min(n, x); 18 | let l = *x; 19 | *r = v <= l ? v : l; 20 | *x = v; 21 | } 22 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/copy-len/list-append-len.syn: -------------------------------------------------------------------------------- 1 | should be able to synthesize trivial list append 2 | 3 | ##### 4 | 5 | { 0 <= n ; r :-> x ** lseg(x, 0, n) ** lseg(y, 0, m)} 6 | void list_append(loc r, loc y) 7 | { k == n + m ; r :-> z ** lseg(z, 0, k)} 8 | 9 | ##### 10 | 11 | void list_append (loc r, loc y) { 12 | if (y == 0) { 13 | } else { 14 | let n = *(y + 1); 15 | list_append(r, n); 16 | let z = *r; 17 | *(y + 1) = z; 18 | *r = y; 19 | } 20 | } -------------------------------------------------------------------------------- /.ci/install_z3.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -x 4 | 5 | version=4.7.1 6 | 7 | if [ ! -f "$HOME/z3/z3-${version}-x64-ubuntu-14.04/bin/z3" ]; then 8 | mkdir -p $HOME/z3 9 | if [ "$(ls -A $HOME/z3)" ]; then 10 | rm -r $HOME/z3/* 11 | fi 12 | wget https://github.com/Z3Prover/z3/releases/download/z3-${version}/z3-${version}-x64-ubuntu-14.04.zip -O ~/z3.zip 13 | unzip ~/z3.zip -d ~/z3 14 | fi 15 | 16 | PATH="$HOME/z3/z3-${version}-x64-ubuntu-14.04/bin/:$PATH" 17 | z3 --version 18 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification/sll-bounds/sll-max.syn: -------------------------------------------------------------------------------- 1 | singly-linked list: max 2 | 3 | ##### 4 | 5 | {true ; r :-> a ** sll(x, n, lo, hi) } 6 | void sll_max (loc x, loc r) 7 | {true ; r :-> hi ** sll(x, n, lo, hi) } 8 | 9 | ##### 10 | 11 | void sll_max (loc x, loc r) { 12 | if (x == null) { 13 | *r = 0; 14 | } else { 15 | let v = *x; 16 | let n = *(x + 1); 17 | sll_max(n, x); 18 | let h = *x; 19 | *r = h <= v ? v : h; 20 | *x = v; 21 | } 22 | } -------------------------------------------------------------------------------- /src/test/resources/fixme-synthesis/holes/destroy2.sus: -------------------------------------------------------------------------------- 1 | /* read doesn't destroy vars 2 */ 2 | 3 | void nop(loc x, loc y) 4 | {} 5 | {} 6 | { 7 | let c = malloc(1); 8 | let d = malloc(1); 9 | *d = c; 10 | *c = d; 11 | let cr = *c; 12 | let dr = *d; 13 | free(d); 14 | free(c); 15 | } 16 | 17 | ### 18 | void nop (loc x, loc y) { 19 | let c = malloc(1); 20 | let d = malloc(1); 21 | *d = c; 22 | *c = d; 23 | let cr = *c; 24 | let dr = *d; 25 | free(d); 26 | free(c); 27 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/abduct/tree-free-ptr.syn: -------------------------------------------------------------------------------- 1 | should be able to deallocate a tree from a pointer to the head 2 | ### 3 | 4 | {true; r :-> x ** tree0(x)} 5 | void free_tree(loc r) 6 | {true ; r :-> 0 } 7 | 8 | ### 9 | 10 | void free_tree (loc r) { 11 | let x = *r; 12 | if (x == 0) { 13 | } else { 14 | let l = *(x + 1); 15 | let rx = *(x + 2); 16 | *x = l; 17 | free_tree(x); 18 | *x = rx; 19 | free_tree(x); 20 | free(x); 21 | *r = 0; 22 | } 23 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification-benchmarks/ints/swap4.syn: -------------------------------------------------------------------------------- 1 | should be able to synthesize a more complex swap program 2 | 3 | ### 4 | 5 | {true; x :-> a ** y :-> c ** z :-> b ** t :-> q } 6 | void swap4 (loc x, loc z, loc y, loc t) 7 | { true; x :-> q ** z :-> c ** t :-> a ** y :-> b } 8 | 9 | ### 10 | 11 | void swap4 (loc x, loc z, loc y, loc t) { 12 | let a = *x; 13 | let c = *y; 14 | let b = *z; 15 | let q = *t; 16 | *x = q; 17 | *y = b; 18 | *z = c; 19 | *t = a; 20 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification-benchmarks/sll-bounds/sll-len.syn: -------------------------------------------------------------------------------- 1 | singly-linked list: length 2 | 3 | ##### 4 | 5 | {0 <= n ; r :-> a ** sll(x, n, lo, hi) } 6 | void sll_len (loc x, loc r) 7 | {true ; r :-> n ** sll(x, n, lo, hi) } 8 | 9 | ##### 10 | 11 | void sll_len (loc x, loc r) {s 12 | if (x == null) { 13 | *r = 0; 14 | } else { 15 | let v = *x; 16 | let n = *(x + 1); 17 | sll_len(n, x); 18 | let l = *x; 19 | *r = 1 + l; 20 | *x = v; 21 | } 22 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification-benchmarks/sll-bounds/sll-min.syn: -------------------------------------------------------------------------------- 1 | singly-linked list: min 2 | 3 | ##### 4 | 5 | {true ; r :-> a ** sll(x, n, lo, hi) } 6 | void sll_min (loc x, loc r) 7 | {true ; r :-> lo ** sll(x, n, lo, hi) } 8 | 9 | ##### 10 | 11 | void sll_min (loc x, loc r) { 12 | if (x == 0) { 13 | *r = 7; 14 | } else { 15 | let v = *x; 16 | let n = *(x + 1); 17 | sll_min(n, x); 18 | let l = *x; 19 | *r = v <= l ? v : l; 20 | *x = v; 21 | } 22 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/paper-benchmarks/sll-bounds/sll-len.syn: -------------------------------------------------------------------------------- 1 | singly-linked list: length 2 | 3 | ##### 4 | 5 | {0 <= n ; ret :-> a ** sll(x, n, lo, hi) } 6 | void sll_len (loc x, loc ret) 7 | {true ; ret :-> n ** sll(x, n, lo, hi) } 8 | 9 | ##### 10 | 11 | void sll_len (loc x, loc ret) { 12 | if (x == 0) { 13 | *ret = 0; 14 | } else { 15 | let v = *x; 16 | let n = *(x + 1); 17 | sll_len(n, x); 18 | let l = *x; 19 | *ret = 1 + l; 20 | *x = v; 21 | } 22 | } -------------------------------------------------------------------------------- /src/main/scala/org/tygus/suslik/LanguageUtils.scala: -------------------------------------------------------------------------------- 1 | package org.tygus.suslik 2 | 3 | /** 4 | * @author Ilya Sergey 5 | */ 6 | 7 | object LanguageUtils { 8 | 9 | private val init = 0 10 | 11 | private var now = init 12 | 13 | def resetFreshNameGenerator(): Unit = { 14 | now = init 15 | } 16 | 17 | val cardinalityPrefix = "_alpha_" 18 | 19 | def getTotallyFreshName(prefix: String): String = { 20 | val s = s"$prefix$now" 21 | now = now + 1 22 | s 23 | } 24 | 25 | } -------------------------------------------------------------------------------- /src/main/scala/org/tygus/suslik/certification/targets/htt/translation/ProofEvaluator.scala: -------------------------------------------------------------------------------- 1 | package org.tygus.suslik.certification.targets.htt.translation 2 | 3 | import org.tygus.suslik.certification.source.SuslikProofStep 4 | import org.tygus.suslik.certification.targets.htt.logic.Proof 5 | import org.tygus.suslik.certification.traversal.StackEvaluator 6 | 7 | object ProofEvaluator extends StackEvaluator[SuslikProofStep, Proof.Step, ProofContext] { 8 | val interpreter = ProofInterpreter 9 | } 10 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification-benchmarks/sll-bounds/sll-max.syn: -------------------------------------------------------------------------------- 1 | singly-linked list: max 2 | 3 | ##### 4 | 5 | {true ; r :-> a ** sll(x, n, lo, hi) } 6 | void sll_max (loc x, loc r) 7 | {true ; r :-> hi ** sll(x, n, lo, hi) } 8 | 9 | ##### 10 | 11 | void sll_max (loc x, loc r) { 12 | if (x == null) { 13 | *r = 0; 14 | } else { 15 | let v = *x; 16 | let n = *(x + 1); 17 | sll_max(n, x); 18 | let h = *x; 19 | *r = h <= v ? v : h; 20 | *x = v; 21 | } 22 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/paper-benchmarks/sll-bounds/sll-max.syn: -------------------------------------------------------------------------------- 1 | singly-linked list: max 2 | 3 | ##### 4 | 5 | {true ; ret :-> a ** sll(x, n, lo, hi) } 6 | void sll_max (loc x, loc ret) 7 | {true ; ret :-> hi ** sll(x, n, lo, hi) } 8 | 9 | ##### 10 | 11 | void sll_max (loc x, loc ret) { 12 | if (x == 0) { 13 | *ret = 0; 14 | } else { 15 | let v = *x; 16 | let n = *(x + 1); 17 | sll_max(n, x); 18 | let h = *x; 19 | *ret = h <= v ? v : h; 20 | *x = v; 21 | } 22 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/paper-benchmarks/sll-bounds/sll-min.syn: -------------------------------------------------------------------------------- 1 | singly-linked list: min 2 | 3 | ##### 4 | 5 | {true ; ret :-> a ** sll(x, n, lo, hi) } 6 | void sll_min (loc x, loc ret) 7 | {true ; ret :-> lo ** sll(x, n, lo, hi) } 8 | 9 | ##### 10 | 11 | void sll_min (loc x, loc ret) { 12 | if (x == 0) { 13 | *ret = 7; 14 | } else { 15 | let v = *x; 16 | let n = *(x + 1); 17 | sll_min(n, x); 18 | let l = *x; 19 | *ret = v <= l ? v : l; 20 | *x = v; 21 | } 22 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/copy/c6-alloc_head.syn: -------------------------------------------------------------------------------- 1 | Step 6: 2 | Add a head to a list 3 | 4 | Produces a seemingly right result, but takes sooper-long. 5 | Serves as an example of a problem with closing. 6 | 7 | ##### 8 | 9 | {S =i {v} ++ S1 ; r :-> t3 ** lseg(t3, 0, S1) } 10 | 11 | void list_copy(loc r, int v, loc t3) 12 | 13 | {true; r :-> y ** lseg(y, 0, S)} 14 | 15 | ##### 16 | 17 | void list_copy (loc r, int v, loc t3) { 18 | let y = malloc(2); 19 | *r = y; 20 | *(y + 1) = t3; 21 | *y = v; 22 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/online/list-copy.sus: -------------------------------------------------------------------------------- 1 | // copy a singly-linked list 2 | 3 | predicate list(loc x, set s) { 4 | | x == 0 => { s == {} ; emp } 5 | | x != 0 => { s == {v} + s1 ; [x, 2] ** x :-> v ** (x + 1) :-> nxt ** list(nxt, s1) } 6 | } 7 | 8 | 9 | // Create a copy of a list starting at `x`; 10 | // and store the address of the copy in `r`. 11 | void copy (loc x, loc r) 12 | { true ; list(x, s) ** r :-> _ } 13 | { true ; list(x, s) ** list(y, s) ** r :-> y } 14 | { 15 | ?? 16 | } 17 | 18 | -------------------------------------------------------------------------------- /src/test/resources/fixme-synthesis/holes/read_offsets.sus: -------------------------------------------------------------------------------- 1 | /* read manages to reason about offsets */ 2 | 3 | void nop(loc x, loc y) 4 | {} 5 | {} 6 | { 7 | let a = malloc(3); 8 | let b = malloc(1); 9 | *b = a+1; 10 | let c = *b; /* c == a+1*/ 11 | let d = *(c+1); /* let d = *(a+1+1);*/ 12 | ?? 13 | } 14 | 15 | ### 16 | void nop (loc x, loc y) { 17 | let a = malloc(3); 18 | let b = malloc(1); 19 | *b = a + 1; 20 | let c = *b; 21 | let d = *(c + 1); 22 | free(a); 23 | free(b); 24 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification/dll/dll-dupleton.syn: -------------------------------------------------------------------------------- 1 | # -c 3 2 | doubly-linked list: construct a list with two elements 3 | 4 | ##### 5 | 6 | { r :-> a } 7 | void dll_dupleton (int x, int y, loc r) 8 | { elems =i {x, y} ; r :-> z ** dll(z, null, elems) } 9 | 10 | ##### 11 | 12 | void dll_dupleton (int x, int y, loc r) { 13 | let z = malloc(3); 14 | let w = malloc(3); 15 | *r = z; 16 | *(z + 1) = w; 17 | *(z + 2) = 0; 18 | *(w + 1) = 0; 19 | *(w + 2) = z; 20 | *z = y; 21 | *w = x; 22 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/copy-len/list-free-ghost.syn: -------------------------------------------------------------------------------- 1 | should be able to allocate to match the desired precondition of the function, 2 | i.e., by inferring the frame to be allocated (frame abduction!) 3 | ### 4 | 5 | {true; r :-> z ** lseg(x, 0, n)} 6 | void list_free(loc r, loc x) 7 | {true ; r :-> 0} 8 | 9 | ### 10 | 11 | void list_free (loc r, loc x) { 12 | if (x == 0) { 13 | *r = 0; 14 | } else { 15 | let n = *(x + 1); 16 | list_free(x, n); 17 | free(x); 18 | *r = 0; 19 | } 20 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/copy/c4-copy_strip_frame.syn: -------------------------------------------------------------------------------- 1 | Step 4: strip the frame 2 | 3 | ##### 4 | 5 | { s =i {v} ++ s1 ; 6 | [x, 2] ** x :-> v ** (x + 1) :-> nxt ** lseg(nxt, 0, s1) ** 7 | r :-> t3 ** 8 | lseg(t3, 0, s1) } 9 | 10 | void list_copy(loc r, loc x, loc t3, loc nxt, int v) 11 | 12 | {s =i {w} ++ s3 ; 13 | [x, 2] ** x :-> w ** (x + 1) :-> nxt1 ** lseg(nxt1, 0, s3) ** 14 | r :-> y ** 15 | lseg(y, 0, s1) } 16 | 17 | ##### 18 | 19 | void list_copy (loc r, loc x, loc t3, loc nxt, int v) { 20 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/tree/tree-size.syn: -------------------------------------------------------------------------------- 1 | should be able to synthesize tree size 2 | 3 | ##### 4 | 5 | 6 | {0 <= n ; r :-> 0 ** treeN(x, n) } 7 | void tree_size(loc x, loc r) 8 | {true ; r :-> n ** treeN(x, n) } 9 | 10 | ##### 11 | 12 | void tree_size (loc x, loc r) { 13 | if (x == 0) { 14 | } else { 15 | let l = *(x + 1); 16 | let rx = *(x + 2); 17 | tree_size(l, r); 18 | let n1 = *r; 19 | *r = 0; 20 | tree_size(rx, r); 21 | let n = *r; 22 | *r = 1 + n1 + n; 23 | } 24 | } -------------------------------------------------------------------------------- /src/main/scala/org/tygus/suslik/certification/targets/htt/translation/ProgramEvaluator.scala: -------------------------------------------------------------------------------- 1 | package org.tygus.suslik.certification.targets.htt.translation 2 | 3 | import org.tygus.suslik.certification.source.SuslikProofStep 4 | import org.tygus.suslik.certification.targets.htt.program.Statements.CStatement 5 | import org.tygus.suslik.certification.traversal.StackEvaluator 6 | 7 | object ProgramEvaluator extends StackEvaluator[SuslikProofStep, CStatement, ProgramContext] { 8 | val interpreter = ProgramInterpreter 9 | } 10 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/all-benchmarks/avl/height.syn: -------------------------------------------------------------------------------- 1 | avl height 2 | 3 | ##### 4 | 5 | 6 | {0 <= n /\ 0 <= h; r :-> a ** avl(x, n, h) } 7 | void avl_height(loc x, loc r) 8 | {true ; r :-> h ** avl(x, n, h) } 9 | 10 | ##### 11 | 12 | void avl_height (loc x, loc r) { 13 | if (x == 0) { 14 | *r = 0; 15 | } else { 16 | let l = *(x + 1); 17 | let rx = *(x + 2); 18 | avl_height(l, r); 19 | let h1 = *r; 20 | avl_height(rx, r); 21 | let h = *r; 22 | *r = (h1 <= h ? h : h1) + 1; 23 | } 24 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/all-benchmarks/avl/size.syn: -------------------------------------------------------------------------------- 1 | should be able to synthesize tree size 2 | 3 | ##### 4 | 5 | 6 | {0 <= n ; r :-> a ** avl(x, n, h) } 7 | void avl_size(loc x, loc r) 8 | {true ; r :-> n ** avl(x, n, h) } 9 | 10 | ##### 11 | 12 | void avl_size (loc x, loc r) { 13 | if (x == 0) { 14 | *r = 0; 15 | } else { 16 | let l = *(x + 1); 17 | let rx = *(x + 2); 18 | avl_size(l, r); 19 | let n1 = *r; 20 | avl_size(rx, r); 21 | let n = *r; 22 | *r = 1 + n1 + n; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/all-benchmarks/tree/size.syn: -------------------------------------------------------------------------------- 1 | should be able to synthesize tree size 2 | 3 | ##### 4 | 5 | 6 | {0 <= n ; r :-> 0 ** treeN(x, n) } 7 | void tree_size(loc x, loc r) 8 | {true ; r :-> n ** treeN(x, n) } 9 | 10 | ##### 11 | 12 | void tree_size (loc x, loc r) { 13 | if (x == 0) { 14 | } else { 15 | let l = *(x + 1); 16 | let rx = *(x + 2); 17 | tree_size(l, r); 18 | let n1 = *r; 19 | *r = 0; 20 | tree_size(rx, r); 21 | let n = *r; 22 | *r = 1 + n1 + n; 23 | } 24 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/copy-len/list-copy-len.syn: -------------------------------------------------------------------------------- 1 | should be able to synthesize list copy 2 | 3 | ##### 4 | 5 | {0 <= n ; r :-> a ** lseg(x, 0, n)} 6 | void list_copy(loc r, loc x) 7 | {true ; r :-> y ** lseg(x, 0, n) ** lseg(y, 0, n) } 8 | 9 | ##### 10 | 11 | void list_copy (loc r, loc x) { 12 | if (x == 0) { 13 | *r = 0; 14 | } else { 15 | let n = *(x + 1); 16 | list_copy(x, n); 17 | let yx = *x; 18 | let y = malloc(2); 19 | *(x + 1) = yx; 20 | *r = y; 21 | *(y + 1) = n; 22 | } 23 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/cyclic-benchmarks/skiplist/skl-simple-free.syn: -------------------------------------------------------------------------------- 1 | # -o 2 -p true 2 | 3 | should be able to deallocate a skip list 4 | 5 | ### 6 | 7 | { skl_simple(x, p, s) } 8 | void skl_simple_free(loc x, loc p) 9 | { emp } 10 | 11 | ### 12 | 13 | {skl_simple(x, p, s)} 14 | {emp} 15 | void skl_simple_free (loc x, loc p) { 16 | if (x == p) { 17 | } else { 18 | let d = *(x + 1); 19 | let f = *(x + 2); 20 | skl_simple_free(d, f); 21 | skl_simple_free(f, p); 22 | free(x); 23 | } 24 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification-benchmarks-advanced/dll/dll-dupleton.syn: -------------------------------------------------------------------------------- 1 | # -c 3 2 | doubly-linked list: construct a list with two elements 3 | 4 | ##### 5 | 6 | { r :-> a } 7 | void dll_dupleton (int x, int y, loc r) 8 | { elems =i {x, y} ; r :-> z ** dll(z, null, elems) } 9 | 10 | ##### 11 | 12 | void dll_dupleton (int x, int y, loc r) { 13 | let z = malloc(3); 14 | let w = malloc(3); 15 | *r = z; 16 | *(z + 1) = w; 17 | *(z + 2) = 0; 18 | *(w + 1) = 0; 19 | *(w + 2) = z; 20 | *z = y; 21 | *w = x; 22 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/abduct/list-copy-len-ptr.syn: -------------------------------------------------------------------------------- 1 | should be able to synthesize list copy from a pointer to the head 2 | 3 | ##### 4 | 5 | {0 <= n ; r :-> x ** lseg(x, 0, n)} 6 | void list_copy(loc r) 7 | {true ; r :-> y ** lseg(x, 0, n) ** lseg(y, 0, n) } 8 | 9 | ##### 10 | 11 | void list_copy (loc r) { 12 | let x = *r; 13 | if (x == 0) { 14 | } else { 15 | let n = *(x + 1); 16 | *x = n; 17 | list_copy(x); 18 | let yx = *x; 19 | let y = malloc(2); 20 | *r = y; 21 | *(y + 1) = yx; 22 | } 23 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification/tree/tree-size.syn: -------------------------------------------------------------------------------- 1 | should be able to synthesize tree size 2 | 3 | ##### 4 | 5 | 6 | {0 <= n ; r :-> 0 ** treeN(x, n) } 7 | void tree_size(loc x, loc r) 8 | {true ; r :-> n ** treeN(x, n) } 9 | 10 | ##### 11 | 12 | void tree_size (loc x, loc r) { 13 | if (x == 0) { 14 | } else { 15 | let l = *(x + 1); 16 | let rx = *(x + 2); 17 | tree_size(l, r); 18 | let n1 = *r; 19 | *r = 0; 20 | tree_size(rx, r); 21 | let n = *r; 22 | *r = 1 + n1 + n; 23 | } 24 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/paper-benchmarks/tree/tree-size.syn: -------------------------------------------------------------------------------- 1 | should be able to synthesize tree size 2 | 3 | ##### 4 | 5 | 6 | {0 <= n ; r :-> 0 ** treeN(x, n) } 7 | void tree_size(loc x, loc r) 8 | {true ; r :-> n ** treeN(x, n) } 9 | 10 | ##### 11 | 12 | void tree_size (loc x, loc r) { 13 | if (x == 0) { 14 | } else { 15 | let l = *(x + 1); 16 | let rx = *(x + 2); 17 | tree_size(l, r); 18 | let n1 = *r; 19 | *r = 0; 20 | tree_size(rx, r); 21 | let n = *r; 22 | *r = 1 + n1 + n; 23 | } 24 | } -------------------------------------------------------------------------------- /src/main/scala/org/tygus/suslik/certification/targets/iris/translation/TranslatableOps.scala: -------------------------------------------------------------------------------- 1 | package org.tygus.suslik.certification.targets.iris.translation 2 | 3 | import org.tygus.suslik.certification.targets.iris.heaplang.Types.HType 4 | 5 | object TranslatableOps { 6 | implicit class Translatable[A](value: A) { 7 | def translate[B](implicit translator: IrisTranslator[A,B], ctx: Option[ProgramTranslationContext] = None, target: Option[HType] = None): B = { 8 | translator.translate(value, ctx, target) 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/copy-len/c8-alloc-close.syn: -------------------------------------------------------------------------------- 1 | Step 8: 2 | Add a head to a list and close the predicate 3 | 4 | ##### 5 | 6 | { len == 1 + len1 /\ 0 <= len1 ; 7 | [x, 2] ** x :-> v ** (x + 1) :-> nxt ** lseg(nxt, 0, len1) ** 8 | r :-> t3 ** 9 | lseg(t3, 0, len1) } 10 | 11 | void list_copy(loc r, int v, loc t3) 12 | 13 | {true; r :-> Y ** lseg(Y, 0, len) ** 14 | lseg(x, 0, len) } 15 | 16 | ##### 17 | 18 | void list_copy (loc r, int v, loc t3) { 19 | let Y = malloc(2); 20 | *r = Y; 21 | *(Y + 1) = t3; 22 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/copy/list-append.syn: -------------------------------------------------------------------------------- 1 | should be able to synthesize trivial list append 2 | 3 | ##### 4 | 5 | { r :-> x ** lseg(x, 0, s1) ** lseg(y, 0, s2)} 6 | void list_append(loc r, loc y) 7 | { s =i s1 ++ s2; r :-> z ** lseg(z, 0, s)} 8 | 9 | ##### 10 | 11 | void list_append (loc r, loc y) { 12 | let x = *r; 13 | if (x == 0) { 14 | *r = y; 15 | } else { 16 | let v = *x; 17 | let n = *(x + 1); 18 | *x = y; 19 | list_append(x, n); 20 | let z = *x; 21 | *(x + 1) = z; 22 | *x = v; 23 | } 24 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/cyclic-benchmarks/beyond/skl-free.syn: -------------------------------------------------------------------------------- 1 | # -o 2 -x true -p true --lexi true 2 | 3 | should be able to deallocate a skip list 4 | 5 | ### 6 | 7 | { skl(x, p, s, n, lo, hi) } 8 | void skl_simple_free(loc x, loc p) 9 | { emp } 10 | 11 | ### 12 | 13 | {skl(x, p, s, n, lo, hi)} 14 | {emp} 15 | void skl_simple_free (loc x, loc p) { 16 | if (x == p) { 17 | } else { 18 | let d = *(x + 1); 19 | let f = *(x + 2); 20 | skl_simple_free(d, f); 21 | skl_simple_free(f, p); 22 | free(x); 23 | } 24 | } -------------------------------------------------------------------------------- /src/main/scala/org/tygus/suslik/certification/traversal/ProofTree.scala: -------------------------------------------------------------------------------- 1 | package org.tygus.suslik.certification.traversal 2 | 3 | import org.tygus.suslik.logic.Specifications.GoalLabel 4 | 5 | /** 6 | * Represents an abstract encoding of a proof tree 7 | * 8 | * @param step a proof step (rule application) 9 | * @param children list of child nodes 10 | * @param label the label of the Suslik goal to which the rule was applied 11 | */ 12 | case class ProofTree[S <: Step](step: S, children: List[ProofTree[S]], label: Option[GoalLabel] = None) -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification-benchmarks/tree/tree-size.syn: -------------------------------------------------------------------------------- 1 | should be able to synthesize tree size 2 | 3 | ##### 4 | 5 | 6 | {0 <= n ; r :-> 0 ** treeN(x, n) } 7 | void tree_size(loc x, loc r) 8 | {true ; r :-> n ** treeN(x, n) } 9 | 10 | ##### 11 | 12 | void tree_size (loc x, loc r) { 13 | if (x == 0) { 14 | } else { 15 | let l = *(x + 1); 16 | let rx = *(x + 2); 17 | tree_size(l, r); 18 | let n1 = *r; 19 | *r = 0; 20 | tree_size(rx, r); 21 | let n = *r; 22 | *r = 1 + n1 + n; 23 | } 24 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/all-benchmarks/sll/copy.syn: -------------------------------------------------------------------------------- 1 | should be able to synthesize list copy 2 | 3 | ##### 4 | 5 | {true ; r :-> x ** sll(x, s)} 6 | void sll_copy(loc r) 7 | {true ; r :-> y ** sll(x, s) ** sll(y, s) } 8 | 9 | ##### 10 | 11 | void sll_copy (loc r) { 12 | let x = *r; 13 | if (x == 0) { 14 | } else { 15 | let v = *x; 16 | let n = *(x + 1); 17 | *x = n; 18 | sll_copy(x); 19 | let yx = *x; 20 | let y = malloc(2); 21 | *r = y; 22 | *(y + 1) = yx; 23 | *x = v; 24 | *y = v; 25 | } 26 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification/bst/common.def: -------------------------------------------------------------------------------- 1 | predicate bst(loc x, int sz, int lo, int hi) { 2 | | x == null => { sz == 0 /\ lo == 7 /\ hi == 0 ; emp } 3 | | not (x == null) => { sz == 1 + sz1 + sz2 /\ 0 <= sz1 /\ 0 <= sz2 /\ 4 | lo == (v <= lo1 ? v : lo1) /\ 5 | hi == (hi2 <= v ? v : hi2) /\ 6 | 0 <= v /\ v <= 7 /\ hi1 <= v /\ v <= lo2 ; 7 | [x, 3] ** x :-> v ** (x + 1) :-> l ** (x + 2) :-> r ** bst(l, sz1, lo1, hi1) ** bst(r, sz2, lo2, hi2) } 8 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/paper-examples/13-listmorph.syn: -------------------------------------------------------------------------------- 1 | Example (13) from the paper (listmorph) 2 | 3 | ### 4 | 5 | {true ; r :-> 0 ** lseg(x, 0, S)} 6 | void listmorph(loc x, loc r) 7 | {true ; r :-> y ** lseg2(y, S) } 8 | 9 | ##### 10 | 11 | void listmorph (loc x, loc r) { 12 | if (x == 0) { 13 | } else { 14 | let v = *x; 15 | let n = *(x + 1); 16 | listmorph(n, r); 17 | let yn = *r; 18 | let y = malloc(3); 19 | free(x); 20 | *r = y; 21 | *(y + 2) = yn; 22 | *y = v; 23 | *(y + 1) = v + 1; 24 | } 25 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification/sll/sll-copy.syn: -------------------------------------------------------------------------------- 1 | should be able to synthesize list copy 2 | 3 | ##### 4 | 5 | {true ; r :-> x ** sll(x, s)} 6 | void sll_copy(loc r) 7 | {true ; r :-> y ** sll(x, s) ** sll(y, s) } 8 | 9 | ##### 10 | 11 | void sll_copy (loc r) { 12 | let x = *r; 13 | if (x == 0) { 14 | } else { 15 | let v = *x; 16 | let n = *(x + 1); 17 | *x = n; 18 | sll_copy(x); 19 | let yx = *x; 20 | let y = malloc(2); 21 | *r = y; 22 | *(y + 1) = yx; 23 | *x = v; 24 | *y = v; 25 | } 26 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/paper-benchmarks/bst/common.def: -------------------------------------------------------------------------------- 1 | predicate bst(loc x, int sz, int lo, int hi) { 2 | | x == 0 => { sz == 0 /\ lo == 7 /\ hi == 0 ; emp } 3 | | not (x == 0) => { sz == 1 + sz1 + sz2 /\ 0 <= sz1 /\ 0 <= sz2 /\ 4 | lo == (v <= lo1 ? v : lo1) /\ 5 | hi == (hi2 <= v ? v : hi2) /\ 6 | 0 <= v /\ v <= 7 /\ hi1 <= v /\ v <= lo2 ; 7 | [x, 3] ** x :-> v ** (x + 1) :-> l ** (x + 2) :-> r ** bst(l, sz1, lo1, hi1) ** bst(r, sz2, lo2, hi2) } 8 | } 9 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/tree/tree-size-ptr.syn: -------------------------------------------------------------------------------- 1 | should be able to synthesize tree size from the root pointer 2 | 3 | ##### 4 | 5 | 6 | {0 <= n ; r :-> x ** treeN(x, n) } 7 | void tree_size(loc r) 8 | {true ; r :-> n ** treeN(x, n) } 9 | 10 | ##### 11 | 12 | void tree_size (loc r) { 13 | let x = *r; 14 | if (x == 0) { 15 | } else { 16 | let l = *(x + 1); 17 | let rx = *(x + 2); 18 | *x = l; 19 | tree_size(x); 20 | let n1 = *x; 21 | *r = rx; 22 | tree_size(r); 23 | let n = *r; 24 | *r = 1 + n1 + n; 25 | } 26 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/dllist/llist-to-dllist-in-place.syn: -------------------------------------------------------------------------------- 1 | should be able to convert a doubly-linked list to single-linked list 2 | 3 | ####### 4 | 5 | { true; (prev + 1) :-> x ** dllseg(x, z, s) } 6 | void set_prev(loc x, loc prev) 7 | { true; (prev + 1) :-> x ** dllseg(x, prev, s)} 8 | 9 | { true ; lseg_extra(x, s)} 10 | void sll_to_dll(loc x) 11 | { true ; dllseg(x, z, s)} 12 | 13 | ####### 14 | 15 | void sll_to_dll (loc x) { 16 | if (x == 0) { 17 | } else { 18 | let n = *(x + 1); 19 | sll_to_dll(n); 20 | set_prev(n, x); 21 | } 22 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/paper-benchmarks/sll/sll-copy.syn: -------------------------------------------------------------------------------- 1 | should be able to synthesize list copy 2 | 3 | ##### 4 | 5 | {true ; r :-> x ** sll(x, s)} 6 | void sll_copy(loc r) 7 | {true ; r :-> y ** sll(x, s) ** sll(y, s) } 8 | 9 | ##### 10 | 11 | void sll_copy (loc r) { 12 | let x = *r; 13 | if (x == 0) { 14 | } else { 15 | let v = *x; 16 | let n = *(x + 1); 17 | *x = n; 18 | sll_copy(x); 19 | let yx = *x; 20 | let y = malloc(2); 21 | *r = y; 22 | *(y + 1) = yx; 23 | *x = v; 24 | *y = v; 25 | } 26 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification-benchmarks/sll/sll-copy.syn: -------------------------------------------------------------------------------- 1 | should be able to synthesize list copy 2 | 3 | ##### 4 | 5 | {true ; r :-> x ** sll(x, s)} 6 | void sll_copy(loc r) 7 | {true ; r :-> y ** sll(x, s) ** sll(y, s) } 8 | 9 | ##### 10 | 11 | void sll_copy (loc r) { 12 | let x = *r; 13 | if (x == 0) { 14 | } else { 15 | let v = *x; 16 | let n = *(x + 1); 17 | *x = n; 18 | sll_copy(x); 19 | let yx = *x; 20 | let y = malloc(2); 21 | *r = y; 22 | *(y + 1) = yx; 23 | *x = v; 24 | *y = v; 25 | } 26 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/copy-len/c7-frame-alloc-head.syn: -------------------------------------------------------------------------------- 1 | Step 7: 2 | Add a head to a list 3 | 4 | ##### 5 | 6 | { len == 1 + len1 /\ 0 <= len1 ; 7 | [x, 2] ** x :-> v ** (x + 1) :-> nxt ** lseg(nxt, 0, len1) ** 8 | r :-> t3 ** 9 | lseg(t3, 0, len1) } 10 | 11 | void list_copy(loc r, int v, loc t3) 12 | 13 | {true; r :-> Y ** lseg(Y, 0, len) ** 14 | [x, 2] ** x :-> w ** (x + 1) :-> nxt1 ** lseg(nxt1, 0, len3) } 15 | 16 | ##### 17 | 18 | void list_copy (loc r, int v, loc t3) { 19 | let Y = malloc(2); 20 | *r = Y; 21 | *(Y + 1) = t3; 22 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/copy/c8-alloc-close.syn: -------------------------------------------------------------------------------- 1 | Step 8: 2 | Add a head to a list and close the predicate 3 | 4 | Produces a wrong result so far 5 | 6 | ##### 7 | 8 | {S =i {v} ++ S1 ; 9 | [x, 2] ** x :-> v ** (x + 1) :-> nxt ** lseg(nxt, 0, S1) ** 10 | r :-> t3 ** 11 | lseg(t3, 0, S1) } 12 | 13 | void list_copy(loc r, int v, loc t3) 14 | 15 | {true; r :-> Y ** lseg(Y, 0, S) ** 16 | lseg(x, 0, S) } 17 | 18 | ##### 19 | 20 | void list_copy (loc r, int v, loc t3) { 21 | let Y = malloc(2); 22 | *r = Y; 23 | *(Y + 1) = t3; 24 | *Y = v; 25 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/paper-examples/17-listcopy.syn: -------------------------------------------------------------------------------- 1 | Example (17) from the paper (listcopy) 2 | 3 | ### 4 | 5 | {true ; r :-> x ** lseg(x, 0, S)} 6 | void listcopy(loc r) 7 | {true ; r :-> y ** lseg(x, 0, S) ** lseg(y, 0, S) } 8 | 9 | ##### 10 | 11 | void listcopy (loc r) { 12 | let x = *r; 13 | if (x == 0) { 14 | } else { 15 | let v = *x; 16 | let n = *(x + 1); 17 | *x = n; 18 | listcopy(x); 19 | let yx = *x; 20 | let y = malloc(2); 21 | *r = y; 22 | *(y + 1) = yx; 23 | *x = v; 24 | *y = v; 25 | } 26 | } -------------------------------------------------------------------------------- /src/main/scala/org/tygus/suslik/certification/traversal/TranslatableOps.scala: -------------------------------------------------------------------------------- 1 | package org.tygus.suslik.certification.traversal 2 | 3 | import org.tygus.suslik.certification.traversal.Evaluator._ 4 | import org.tygus.suslik.certification.traversal.Step._ 5 | 6 | object TranslatableOps { 7 | implicit class Translatable[S <: SourceStep](step: S) { 8 | def translate[D <: DestStep, C <: ClientContext[D]](clientContext: C)(implicit translator: Interpreter[S, D, C]): Interpreter.Result[D,C] = { 9 | translator.interpret(step, clientContext) 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/all-benchmarks/multi-list/predicates.def: -------------------------------------------------------------------------------- 1 | predicate sll(loc x, int len, set s) { 2 | | x == 0 => { len == 0 /\ s == {} ; emp } 3 | | not (x == 0) => { len == 1 + len1 /\ s == {v} ++ s1 ; [x, 2] ** x :-> v ** (x + 1) :-> nxt ** sll(nxt, len1, s1) } 4 | } 5 | 6 | predicate multilist(loc x, int size, set s) { 7 | | x == 0 => { size == 0 /\ s == {} ; emp } 8 | | not (x == 0) => { size == len1 + size2 /\ s == s1 ++ s2 ; 9 | [x, 2] ** x :-> h ** (x + 1) :-> t ** sll(h, len1, s1) ** multilist(t, size2, s2) } 10 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/cardio/cardio-sll-copy.syn: -------------------------------------------------------------------------------- 1 | 2 | should be able to synthesize list copy with cardinalities 3 | 4 | ##### 5 | 6 | {r :-> x ** sll_card(x, s)} 7 | void sll_copy(loc r) 8 | {r :-> y ** sll_card(x, s) ** sll_card(y, s) } 9 | 10 | ##### 11 | 12 | void sll_copy (loc r) { 13 | let x = *r; 14 | if (x == 0) { 15 | } else { 16 | let v = *x; 17 | let n = *(x + 1); 18 | *x = n; 19 | sll_copy(x); 20 | let yx = *x; 21 | let y = malloc(2); 22 | *r = y; 23 | *(y + 1) = yx; 24 | *x = v; 25 | *y = v; 26 | } 27 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification-benchmarks-advanced/bst/common.def: -------------------------------------------------------------------------------- 1 | predicate bst(loc x, int sz, int lo, int hi) { 2 | | x == null => { sz == 0 /\ lo == 7 /\ hi == 0 ; emp } 3 | | not (x == null) => { sz == 1 + sz1 + sz2 /\ 0 <= sz1 /\ 0 <= sz2 /\ 4 | lo == (v <= lo1 ? v : lo1) /\ 5 | hi == (hi2 <= v ? v : hi2) /\ 6 | 0 <= v /\ v <= 7 /\ hi1 <= v /\ v <= lo2 ; 7 | [x, 3] ** x :-> v ** (x + 1) :-> l ** (x + 2) :-> r ** bst(l, sz1, lo1, hi1) ** bst(r, sz2, lo2, hi2) } 8 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/smallfoot/tree.sf: -------------------------------------------------------------------------------- 1 | l,r; 2 | 3 | tree_copy(s;t) [tree(t)] { 4 | local i, j, ii, jj; 5 | if(t == NULL) s = t; 6 | else { 7 | i = t->l; 8 | j = t->r; 9 | tree_copy(ii;i); 10 | tree_copy(jj;j); 11 | s = new(); 12 | s->l = ii; 13 | s->r = jj; 14 | } 15 | } [tree(s) * tree(t)] 16 | 17 | tree_deallocate(t) [tree(t)] { 18 | local i, j; 19 | if(t == NULL) {} 20 | else { 21 | i = t->l; 22 | j = t->r; 23 | tree_deallocate(i); 24 | tree_deallocate(j); 25 | dispose(t); 26 | } 27 | } [emp] 28 | -------------------------------------------------------------------------------- /src/main/scala/org/tygus/suslik/certification/traversal/Interpreter.scala: -------------------------------------------------------------------------------- 1 | package org.tygus.suslik.certification.traversal 2 | 3 | import org.tygus.suslik.certification.traversal.Evaluator._ 4 | import org.tygus.suslik.certification.traversal.Step._ 5 | 6 | trait Interpreter[S <: SourceStep, D <: DestStep, C <: ClientContext[D]] { 7 | def interpret(value: S, clientContext: C): Interpreter.Result[D,C] 8 | } 9 | 10 | object Interpreter { 11 | case class Result[D <: DestStep, C <: ClientContext[D]](steps: List[D], childParams: List[(List[D], Option[Deferred[D,C]], C)]) 12 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/copy/list_copy.syn: -------------------------------------------------------------------------------- 1 | should be able to synthesize list copy 2 | 3 | ##### 4 | 5 | {true ; r :-> blank ** lseg(x, 0, s)} 6 | void list_copy(loc r, loc x) 7 | {true ; r :-> y ** lseg(x, 0, s) ** lseg(y, 0, s) } 8 | 9 | ##### 10 | 11 | void list_copy (loc r, loc x) { 12 | if (x == 0) { 13 | *r = 0; 14 | } else { 15 | let v = *x; 16 | let n = *(x + 1); 17 | list_copy(x, n); 18 | let yx = *x; 19 | let y = malloc(2); 20 | *(x + 1) = yx; 21 | *r = y; 22 | *(y + 1) = n; 23 | *x = v; 24 | *y = v; 25 | } 26 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/copy/list_copy_hard.syn: -------------------------------------------------------------------------------- 1 | should be able to synthesize list copy 2 | 3 | ##### 4 | 5 | {true ; r :-> x ** lseg(x, 0, S)} 6 | void listcopy(loc r) 7 | {true ; r :-> y ** lseg(x, 0, S) ** lseg(y, 0, S) } 8 | 9 | ##### 10 | 11 | void listcopy (loc r) { 12 | let x = *r; 13 | if (x == 0) { 14 | } else { 15 | let v = *x; 16 | let n = *(x + 1); 17 | *x = n; 18 | listcopy(x); 19 | let yx = *x; 20 | let y = malloc(2); 21 | *r = y; 22 | *(x + 1) = yx; 23 | *(y + 1) = n; 24 | *x = v; 25 | *y = v; 26 | } 27 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/cyclic-benchmarks/multi-list/predicates.def: -------------------------------------------------------------------------------- 1 | predicate sll(loc x, int len, set s) { 2 | | x == 0 => { len == 0 /\ s == {} ; emp } 3 | | not (x == 0) => { len == 1 + len1 /\ s == {v} ++ s1 ; [x, 2] ** x :-> v ** (x + 1) :-> nxt ** sll(nxt, len1, s1) } 4 | } 5 | 6 | predicate multilist(loc x, int size, set s) { 7 | | x == 0 => { size == 0 /\ s == {} ; emp } 8 | | not (x == 0) => { size == len1 + size2 /\ s == s1 ++ s2 ; 9 | [x, 2] ** x :-> h ** (x + 1) :-> t ** sll(h, len1, s1) ** multilist(t, size2, s2) } 10 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/dllist/dllist-to-llist.syn: -------------------------------------------------------------------------------- 1 | should be able to convert a doubly-linked list to single-linked list 2 | 3 | ####### 4 | 5 | { true ; f :-> x ** dllseg(x, z, s)} 6 | void dll_to_sll(loc f) 7 | { true ; f :-> y ** lseg(y, s)} 8 | 9 | ####### 10 | 11 | void dll_to_sll (loc f) { 12 | let x = *f; 13 | if (x == 0) { 14 | } else { 15 | let v = *x; 16 | let w = *(x + 1); 17 | *x = w; 18 | dll_to_sll(x); 19 | let yx = *x; 20 | let y = malloc(2); 21 | free(x); 22 | *f = y; 23 | *(y + 1) = yx; 24 | *y = v; 25 | } 26 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/llist/intersect_sll_with_2_elem_set.syn: -------------------------------------------------------------------------------- 1 | #. -b true 2 | intersect given sll with set of two elements 3 | 4 | 5 | ##### 6 | 7 | predicate sll(loc x, set s) { 8 | | x == 0 => { s =i {} ; emp } 9 | | not (x == 0) => { s =i {v} ++ s1 ; [x, 2] ** x :-> v ** (x + 1) :-> nxt ** sll(nxt, s1) } 10 | } 11 | 12 | {true ; sll(old_sll, old_elems) ** ret :-> second_set_elem} 13 | void sll_intersect (loc old_sll, loc ret, int e2) 14 | {intersect_elems =i old_elems * {second_set_elem, e2} ; sll(new_sll, intersect_elems) ** ret :-> new_sll } 15 | 16 | ##### 17 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/copy/c7-frame-alloc-head.syn: -------------------------------------------------------------------------------- 1 | Step 7: 2 | Add a head to a list 3 | 4 | Produces a wrong result so far 5 | 6 | ##### 7 | 8 | {S =i {v} ++ S1 ; 9 | [x, 2] ** x :-> v ** (x + 1) :-> nxt ** lseg(nxt, 0, S1) ** 10 | r :-> t3 ** 11 | lseg(t3, 0, S1) } 12 | 13 | void list_copy(loc r, int v, loc t3) 14 | 15 | {true; r :-> Y ** lseg(Y, 0, S) ** 16 | [x, 2] ** x :-> w ** (x + 1) :-> nxt1 ** lseg(nxt1, 0, S3) } 17 | 18 | ##### 19 | 20 | void list_copy (loc r, int v, loc t3) { 21 | let Y = malloc(2); 22 | *r = Y; 23 | *(Y + 1) = t3; 24 | *Y = v; 25 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/flatten/definitions.def: -------------------------------------------------------------------------------- 1 | predicate lseg(loc x, loc y, set s) { 2 | | x == y => { s =i {} ; emp } 3 | | not (x == y) => { s =i {v} ++ s1 ; [x, 2] ** x :-> v ** (x + 1) :-> nxt ** lseg(nxt, y, s1) } 4 | } 5 | 6 | predicate tree(loc x, set s) { 7 | | x == 0 => {s =i {}; emp} 8 | | not (x == 0) => {s =i {v} ++ s1 ++ s2; [x, 3] ** x :-> v ** (x + 1) :-> l ** (x + 2) :-> r ** tree(l, s1) ** tree(r, s2)} 9 | } 10 | 11 | { r :-> x ** lseg(x, 0, s1) ** lseg(y, 0, s2)} 12 | void list_append(loc r, loc y) 13 | { s =i s1 ++ s2; r :-> z ** lseg(z, 0, s)} 14 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/copy-len/c4-copy-strip-frame.syn: -------------------------------------------------------------------------------- 1 | Step 4: strip the frame (not an ideal solution but acceptable) 2 | 3 | ##### 4 | 5 | { len == 1 + len1 /\ 0 <= len1 ; 6 | [x, 2] ** x :-> v ** (x + 1) :-> nxt ** lseg(nxt, 0, len1) ** 7 | r :-> t3 ** 8 | lseg(t3, 0, len1) } 9 | 10 | void list_copy(loc r, loc x, loc t3, loc nxt, int v) 11 | 12 | { len == 1 + len3 /\ 0 <= len3 ; 13 | [x, 2] ** x :-> w ** (x + 1) :-> nxt1 ** lseg(nxt1, 0, len3) ** 14 | r :-> Y ** 15 | lseg(Y, 0, len1) } 16 | 17 | ##### 18 | 19 | void list_copy (loc r, loc x, loc t3, loc nxt, int v) { 20 | } -------------------------------------------------------------------------------- /src/main/scala/org/tygus/suslik/synthesis/tactics/Tactic.scala: -------------------------------------------------------------------------------- 1 | package org.tygus.suslik.synthesis.tactics 2 | 3 | import org.tygus.suslik.synthesis.SearchTree.OrNode 4 | import org.tygus.suslik.synthesis.rules.Rules.{RuleResult, SynthesisRule} 5 | 6 | /** 7 | * a tactic guides search by pruning and prioritizing the children of an or-node 8 | */ 9 | trait Tactic { 10 | 11 | /** 12 | * Which rules should be considered when expanding node 13 | */ 14 | def nextRules(node: OrNode): List[SynthesisRule] 15 | 16 | def filterExpansions(allExpansions: Seq[RuleResult]): Seq[RuleResult] 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/cardio/cardio-fresh.syn: -------------------------------------------------------------------------------- 1 | 2 | should be able to synthesize list copy with omitted cardinalities 3 | 4 | ##### 5 | 6 | {true ; r :-> x ** sll_card(x, s)} 7 | void sll_copy(loc r) 8 | {b <= a /\ a <= b ; r :-> y ** sll_card(x, s) ** sll_card(y, s) } 9 | 10 | ##### 11 | 12 | void sll_copy (loc r) { 13 | let x = *r; 14 | if (x == 0) { 15 | } else { 16 | let v = *x; 17 | let n = *(x + 1); 18 | *x = n; 19 | sll_copy(x); 20 | let yx = *x; 21 | let y = malloc(2); 22 | *r = y; 23 | *(y + 1) = yx; 24 | *x = v; 25 | *y = v; 26 | } 27 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/tree/tree-copy-len-ptr.syn: -------------------------------------------------------------------------------- 1 | should be able to synthesize a tree copy 2 | 3 | ##### 4 | 5 | {0 <= n ; r :-> x ** treeN(x, n)} 6 | void tree_copy(loc r) 7 | {true ; r :-> y ** treeN(x, n) ** treeN(y, n) } 8 | 9 | ##### 10 | 11 | void tree_copy (loc r) { 12 | let x = *r; 13 | if (x == 0) { 14 | } else { 15 | let l = *(x + 1); 16 | let rx = *(x + 2); 17 | *x = l; 18 | tree_copy(x); 19 | let yx = *x; 20 | *r = rx; 21 | tree_copy(r); 22 | let yr = *r; 23 | let y = malloc(3); 24 | *r = y; 25 | *(y + 1) = yx; 26 | *(y + 2) = yr; 27 | } 28 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/tree/tree-copy-len.syn: -------------------------------------------------------------------------------- 1 | should be able to synthesize a tree copy (with preserving length) 2 | 3 | ##### 4 | 5 | {true ; r :-> 0 ** treeN(x, n)} 6 | void tree_copy(loc x, loc r) 7 | {true ; r :-> y ** treeN(x, n) ** treeN(y, n) } 8 | 9 | ##### 10 | 11 | void tree_copy (loc x, loc r) { 12 | if (x == 0) { 13 | } else { 14 | let l = *(x + 1); 15 | let rx = *(x + 2); 16 | tree_copy(l, r); 17 | let yl = *r; 18 | *r = 0; 19 | tree_copy(rx, r); 20 | let yr = *r; 21 | let y = malloc(3); 22 | *r = y; 23 | *(y + 1) = yl; 24 | *(y + 2) = yr; 25 | } 26 | } -------------------------------------------------------------------------------- /src/main/scala/org/tygus/suslik/language/HasExpressions.scala: -------------------------------------------------------------------------------- 1 | package org.tygus.suslik.language 2 | 3 | import org.tygus.suslik.language.Expressions._ 4 | import org.tygus.suslik.logic.Gamma 5 | 6 | /** 7 | * @author Ilya Sergey 8 | */ 9 | 10 | trait HasExpressions[+A] { 11 | 12 | // Variable substitution 13 | def subst(x: Var, by: Expr) : A = { 14 | this.subst(Map(x -> by)) 15 | } 16 | 17 | def subst(sigma: Subst) : A 18 | 19 | def resolveOverloading(gamma: Gamma): A 20 | 21 | def collect[R <: Expr](p: Expr => Boolean): Set[R] 22 | 23 | def vars: Set[Var] = collect(_.isInstanceOf[Var]) 24 | } 25 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/all-benchmarks/srtl/insertion-sort.syn: -------------------------------------------------------------------------------- 1 | sorted list: insert an element 2 | 3 | ##### 4 | 5 | { l >= 0 ; r :-> k ** srtl(x, s, l) } 6 | void srtl_insert (loc x, loc r)[int k] 7 | { r :-> y ** srtl(y, s + [k], l + 1) } 8 | 9 | { n >= 0 ; r :-> 0 ** sll(x, s, n) } 10 | void insertion_sort (loc x, loc r) 11 | { r :-> y ** sll(x, s, n) ** srtl(y, s, n) } 12 | 13 | ##### 14 | 15 | void insertion_sort (loc x, loc r) { 16 | if (x == 0) { 17 | } else { 18 | let v = *x; 19 | let n = *(x + 1); 20 | insertion_sort(n, r); 21 | let y = *r; 22 | *r = v; 23 | srtl_insert(y, r); 24 | } 25 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/all-benchmarks/sll/free2.syn: -------------------------------------------------------------------------------- 1 | 2 | Deallocate two linked lists (needs listfree as an auxiliary, unless we can pass emp as a list) 3 | 4 | ### 5 | 6 | { sll(x, s1) ** sll(y, s2)} 7 | void listfree2(loc x, loc y) 8 | { emp } 9 | 10 | ### 11 | 12 | void listfree2 (loc x, loc y) { 13 | if (x == 0) { 14 | listfree200(x, y); 15 | } else { 16 | let n = *(x + 1); 17 | listfree2(y, n); 18 | free(x); 19 | } 20 | } 21 | 22 | void listfree200 (loc x, loc y) { 23 | if (y == 0) { 24 | } else { 25 | let n = *(y + 1); 26 | listfree200(x, n); 27 | free(y); 28 | } 29 | } 30 | 31 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/cyclic-benchmarks/contrived/listfree2.syn: -------------------------------------------------------------------------------- 1 | Deallocate two linked lists (needs listfree as an auxiliary, unless we can pass emp as a list) 2 | 3 | ### 4 | 5 | {true; list(x) ** list(y)} 6 | void listfree2(loc x, loc y) 7 | {true ; emp } 8 | 9 | ### 10 | 11 | void listfree2 (loc x, loc y) { 12 | if (x == 0) { 13 | listfree200(x, y); 14 | } else { 15 | let n = *x; 16 | listfree2(y, n); 17 | free(x); 18 | } 19 | } 20 | 21 | void listfree200 (loc x, loc y) { 22 | if (y == 0) { 23 | } else { 24 | let n = *y; 25 | listfree200(x, n); 26 | free(y); 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification/dll/dll-append.syn: -------------------------------------------------------------------------------- 1 | # -c 2 -f 1 2 | 3 | doubly-linked list: append 4 | 5 | ##### 6 | 7 | {true ; dll(x1, a, s1) ** dll(x2, b, s2) ** r :-> x2} 8 | void dll_append (loc x1, loc r) 9 | {s =i s1 ++ s2 ; dll(y, c, s) ** r :-> y } 10 | 11 | ##### 12 | 13 | void dll_append (loc x1, loc r) { 14 | if (x1 == null) { 15 | } else { 16 | let w = *(x1 + 1); 17 | dll_append(w, r); 18 | let y = *r; 19 | if (y == null) { 20 | *(x1 + 1) = null; 21 | *r = x1; 22 | } else { 23 | *(y + 2) = x1; 24 | *(x1 + 1) = y; 25 | *r = x1; 26 | } 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/cyclic-benchmarks/contrived/treelistfree.syn: -------------------------------------------------------------------------------- 1 | Deallocate a tree and a list 2 | 3 | ### 4 | 5 | {true; tree(x) ** list(y)} 6 | void treelistfree(loc x, loc y) 7 | {true ; emp } 8 | 9 | ### 10 | 11 | void treelistfree (loc x, loc y) { 12 | if (y == 0) { 13 | treelistfree00(x, y); 14 | } else { 15 | let n = *y; 16 | treelistfree(x, n); 17 | free(y); 18 | } 19 | } 20 | 21 | void treelistfree00 (loc x, loc y) { 22 | if (x == 0) { 23 | } else { 24 | let l = *x; 25 | let r = *(x + 1); 26 | treelistfree00(l, 0); 27 | treelistfree00(r, 0); 28 | free(x); 29 | } 30 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/cyclic-benchmarks/sll/listfree2.syn: -------------------------------------------------------------------------------- 1 | 2 | Deallocate two linked lists (needs listfree as an auxiliary, unless we can pass emp as a list) 3 | 4 | ### 5 | 6 | { sll(x, s1) ** sll(y, s2)} 7 | void listfree2(loc x, loc y) 8 | { emp } 9 | 10 | ### 11 | 12 | void listfree2 (loc x, loc y) { 13 | if (x == 0) { 14 | listfree200(x, y); 15 | } else { 16 | let n = *(x + 1); 17 | listfree2(y, n); 18 | free(x); 19 | } 20 | } 21 | 22 | void listfree200 (loc x, loc y) { 23 | if (y == 0) { 24 | } else { 25 | let n = *(y + 1); 26 | listfree200(x, n); 27 | free(y); 28 | } 29 | } 30 | 31 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/all-benchmarks/dll/append.syn: -------------------------------------------------------------------------------- 1 | # -c 2 -f 1 2 | 3 | doubly-linked list: append 4 | 5 | ##### 6 | 7 | {true ; dll(x1, a, s1) ** dll(x2, b, s2) ** ret :-> x2} 8 | void dll_append (loc x1, loc ret) 9 | {s =i s1 ++ s2 ; dll(y, c, s) ** ret :-> y } 10 | 11 | ##### 12 | 13 | void dll_append (loc x1, loc ret) { 14 | if (x1 == 0) { 15 | } else { 16 | let w = *(x1 + 1); 17 | dll_append(w, ret); 18 | let y = *ret; 19 | if (y == 0) { 20 | *(x1 + 1) = 0; 21 | *ret = x1; 22 | } else { 23 | *(y + 2) = x1; 24 | *(x1 + 1) = y; 25 | *ret = x1; 26 | } 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /src/test/scala/org/tygus/suslik/synthesis/CardioTests.scala: -------------------------------------------------------------------------------- 1 | package org.tygus.suslik.synthesis 2 | 3 | import org.scalatest.{FunSpec, Matchers} 4 | 5 | class CardioTests extends FunSpec with Matchers with SynthesisRunnerUtil { 6 | 7 | override def doRun(testName: String, desc: String, in: String, out: String, params: SynConfig = defaultConfig): Unit = { 8 | super.doRun(testName, desc, in, out, params) 9 | it(desc) { 10 | synthesizeFromSpec(testName, in, out, params) 11 | } 12 | } 13 | 14 | describe("SuSLik with Cardinalities should be able synthesize") { 15 | runAllTestsFromDir("cardio") 16 | } 17 | 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/all-benchmarks/tree/flatten-acc.syn: -------------------------------------------------------------------------------- 1 | should be able to flatten the tree into a list given a list accumulator 2 | 3 | #### 4 | 5 | { true ; tree(x, s) ** z :-> y ** sll(y, acc)} 6 | void tree_flatten(loc x, loc z) 7 | { s1 =i s ++ acc ; z :-> t ** sll(t, s1)} 8 | 9 | #### 10 | 11 | void tree_flatten (loc x, loc z) { 12 | if (x == 0) { 13 | } else { 14 | let v = *x; 15 | let l = *(x + 1); 16 | let r = *(x + 2); 17 | tree_flatten(l, z); 18 | tree_flatten(r, z); 19 | let tr = *z; 20 | let t = malloc(2); 21 | free(x); 22 | *z = t; 23 | *(t + 1) = tr; 24 | *t = v; 25 | } 26 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification-benchmarks/dll/dll-append.syn: -------------------------------------------------------------------------------- 1 | # -c 2 -f 1 2 | 3 | doubly-linked list: append 4 | 5 | ##### 6 | 7 | {true ; dll(x1, a, s1) ** dll(x2, b, s2) ** r :-> x2} 8 | void dll_append (loc x1, loc r) 9 | {s =i s1 ++ s2 ; dll(y, c, s) ** r :-> y } 10 | 11 | ##### 12 | 13 | void dll_append (loc x1, loc r) { 14 | if (x1 == null) { 15 | } else { 16 | let w = *(x1 + 1); 17 | dll_append(w, r); 18 | let y = *r; 19 | if (y == null) { 20 | *(x1 + 1) = null; 21 | *r = x1; 22 | } else { 23 | *(y + 2) = x1; 24 | *(x1 + 1) = y; 25 | *r = x1; 26 | } 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/flatten/tree-flatten-acc.syn: -------------------------------------------------------------------------------- 1 | should be able to flatten the tree into a list given a list accumulator 2 | 3 | #### 4 | 5 | { true ; tree(x, s) ** z :-> y ** lseg(y, 0, acc)} 6 | void tree_flatten(loc x, loc z) 7 | { s1 =i s ++ acc ; z :-> t ** lseg(t, 0, s1)} 8 | 9 | #### 10 | 11 | void tree_flatten (loc x, loc z) { 12 | if (x == 0) { 13 | } else { 14 | let v = *x; 15 | let l = *(x + 1); 16 | let r = *(x + 2); 17 | tree_flatten(l, z); 18 | tree_flatten(r, z); 19 | let tr = *z; 20 | let t = malloc(2); 21 | free(x); 22 | *z = t; 23 | *(t + 1) = tr; 24 | *t = v; 25 | } 26 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/paper-benchmarks/dll/dll-append.syn: -------------------------------------------------------------------------------- 1 | # -c 2 -f 1 2 | 3 | doubly-linked list: append 4 | 5 | ##### 6 | 7 | {true ; dll(x1, a, s1) ** dll(x2, b, s2) ** ret :-> x2} 8 | void dll_append (loc x1, loc ret) 9 | {s =i s1 ++ s2 ; dll(y, c, s) ** ret :-> y } 10 | 11 | ##### 12 | 13 | void dll_append (loc x1, loc ret) { 14 | if (x1 == 0) { 15 | } else { 16 | let w = *(x1 + 1); 17 | dll_append(w, ret); 18 | let y = *ret; 19 | if (y == 0) { 20 | *(x1 + 1) = 0; 21 | *ret = x1; 22 | } else { 23 | *(y + 2) = x1; 24 | *(x1 + 1) = y; 25 | *ret = x1; 26 | } 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/tree/tree-copy.syn: -------------------------------------------------------------------------------- 1 | should be able to synthesize a tree copy (with elements) 2 | 3 | ##### 4 | 5 | {true ; r :-> 0 ** treeS(x, S)} 6 | void tree_copy(loc x, loc r) 7 | {true ; r :-> y ** treeS(x, S) ** treeS(y, S) } 8 | 9 | ##### 10 | 11 | void tree_copy (loc x, loc r) { 12 | if (x == 0) { 13 | } else { 14 | let v = *x; 15 | let l = *(x + 1); 16 | let rx = *(x + 2); 17 | tree_copy(l, r); 18 | let yl = *r; 19 | *r = 0; 20 | tree_copy(rx, r); 21 | let yr = *r; 22 | let y = malloc(3); 23 | *r = y; 24 | *(y + 1) = yl; 25 | *(y + 2) = yr; 26 | *y = v; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/test/resources/fixme-synthesis/failing-examples/free_incorrect.sus: -------------------------------------------------------------------------------- 1 | /* free and write should work with equalities */ 2 | 3 | /* free works incorrectly, because it can't find block parts that has different name than block name */ 4 | void fr(loc f) 5 | { true ; } 6 | { true ; } 7 | { 8 | let a = malloc(3); 9 | *a = a; 10 | let b = *a; /* b == a */ 11 | *b = a; 12 | *(b+1) = b+1; 13 | let c = *(b+1); 14 | *c = c; 15 | free(b); 16 | } 17 | 18 | ### 19 | 20 | void fr(loc f) { 21 | let a = malloc(3); 22 | *a = a; 23 | let b = *a; /* b == a */ 24 | *b = a; 25 | *(b+1) = b+1; 26 | let c = *(b+1); 27 | *c = c; 28 | free(b); 29 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/paper-benchmarks/tree/tree-flatten-acc.syn: -------------------------------------------------------------------------------- 1 | should be able to flatten the tree into a list given a list accumulator 2 | 3 | #### 4 | 5 | { true ; tree(x, s) ** z :-> y ** sll(y, acc)} 6 | void tree_flatten(loc x, loc z) 7 | { s1 =i s ++ acc ; z :-> t ** sll(t, s1)} 8 | 9 | #### 10 | 11 | void tree_flatten (loc x, loc z) { 12 | if (x == 0) { 13 | } else { 14 | let v = *x; 15 | let l = *(x + 1); 16 | let r = *(x + 2); 17 | tree_flatten(l, z); 18 | tree_flatten(r, z); 19 | let tr = *z; 20 | let t = malloc(2); 21 | free(x); 22 | *z = t; 23 | *(t + 1) = tr; 24 | *t = v; 25 | } 26 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/dllist/definitions.def: -------------------------------------------------------------------------------- 1 | predicate lseg(loc x, set s) { 2 | | x == 0 => { s =i {} ; emp } 3 | | not (x == 0) => { s =i {v} ++ s1 ; [x, 2] ** x :-> v ** (x + 1) :-> nxt ** lseg(nxt, s1) } 4 | } 5 | 6 | predicate dllseg(loc x, loc z, set s) { 7 | | x == 0 => { s =i {} ; emp } 8 | | not (x == 0) => 9 | { s =i {v} ++ s1 ; [x, 3] ** x :-> v ** (x + 1) :-> w ** (x + 2) :-> z ** dllseg(w, x, s1) } 10 | } 11 | 12 | predicate lseg_extra(loc x, set s) { 13 | | x == 0 => { s =i {} ; emp } 14 | | not (x == 0) => { s =i {v} ++ s1 ; [x, 3] ** x :-> v ** (x + 1) :-> nxt ** (x + 2) :-> extra ** lseg_extra(nxt, s1) } 15 | } 16 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/cardio/cardio-remove-last-aux1.syn: -------------------------------------------------------------------------------- 1 | # -c 2 -o 2 -p true 2 | 3 | should be able to synthesize removal of the second element of the list 4 | 5 | ##### 6 | 7 | { a == 0 ; r :-> x ** [x, 2] ** x :-> v ** (x + 1) :-> z ** sll_card0(z)} 8 | void aux(loc r) 9 | { b == 0 /\ (y == 0 \/ y == x) ; r :-> y ** sll_card0(y) } 10 | 11 | 12 | { a >= 4 ; r :-> x ** sll_card0(x)} 13 | void remove_second(loc r) 14 | {b == a - 2 /\ (y == 0 \/ y == x); r :-> y ** sll_card0(y) } 15 | 16 | ##### 17 | 18 | void remove_second (loc r) { 19 | let x = *r; 20 | let nx = *(x + 1); 21 | let n = *(nx + 1); 22 | free(nx); 23 | *(x + 1) = n; 24 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification/tree/tree-flatten-acc.syn: -------------------------------------------------------------------------------- 1 | should be able to flatten the tree into a list given a list accumulator 2 | 3 | #### 4 | 5 | { true ; tree(x, s) ** z :-> y ** sll(y, acc)} 6 | void tree_flatten_acc(loc x, loc z) 7 | { s1 =i s ++ acc ; z :-> t ** sll(t, s1)} 8 | 9 | #### 10 | 11 | void tree_flatten_acc (loc x, loc z) { 12 | if (x == null) { 13 | } else { 14 | let v = *x; 15 | let l = *(x + 1); 16 | let r = *(x + 2); 17 | tree_flatten(l, z); 18 | tree_flatten(r, z); 19 | let tr = *z; 20 | let t = malloc(2); 21 | free(x); 22 | *z = t; 23 | *(t + 1) = tr; 24 | *t = v; 25 | } 26 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/abduct/lseg.def: -------------------------------------------------------------------------------- 1 | predicate lseg(loc x, loc y, int len) { 2 | | x == y => { len == 0 ; emp } 3 | | not (x == y) => { len == 1 + len1 /\ 0 <= len1 ; [x, 2] ** x :-> v ** (x + 1) :-> nxt ** lseg(nxt, y, len1) } 4 | } 5 | 6 | predicate tree0(loc x) { 7 | | x == 0 => {emp} 8 | | not (x == 0) => {[x, 3] ** x :-> v ** (x + 1) :-> l ** (x + 2) :-> r ** tree0(l) ** tree0(r)} 9 | } 10 | 11 | predicate treeN(loc x, int n) { 12 | | x == 0 => {n == 0 ; emp} 13 | | not (x == 0) => { n == n1 + n2 /\ 0 <= n1 /\ 0 <= n2 ; 14 | [x, 3] ** x :-> v ** (x + 1) :-> l ** (x + 2) :-> r ** treeN(l, n1) ** treeN(r, n2)} 15 | } 16 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/all-benchmarks/tree/copy.syn: -------------------------------------------------------------------------------- 1 | should be able to synthesize a tree copy (with elements) 2 | 3 | ##### 4 | 5 | {true ; r :-> x ** tree(x, s)} 6 | void tree_copy(loc r) 7 | {true ; r :-> y ** tree(x, s) ** tree(y, s) } 8 | 9 | ##### 10 | 11 | void tree_copy (loc r) { 12 | let x = *r; 13 | if (x == 0) { 14 | } else { 15 | let v = *x; 16 | let l = *(x + 1); 17 | let rx = *(x + 2); 18 | *x = l; 19 | tree_copy(x); 20 | let yx = *x; 21 | *r = rx; 22 | tree_copy(r); 23 | let yr = *r; 24 | let y = malloc(3); 25 | *r = y; 26 | *(y + 1) = yx; 27 | *(y + 2) = yr; 28 | *x = v; 29 | *y = v; 30 | } 31 | } -------------------------------------------------------------------------------- /src/test/resources/fixme-synthesis/holes/call_ghost_arg.sus: -------------------------------------------------------------------------------- 1 | /* ghost arg in function call */ 2 | void srtl_insert (loc x, loc r) 3 | {0 <= n /\ 0 <= k /\ k <= 7 ; r :-> k ** srtl(x, n, lo, hi) } 4 | {n1 == n + 1 /\ lo1 == (k <= lo ? k : lo) /\ hi1 == (hi <= k ? k : hi) ; r :-> y ** srtl(y, n1, lo1, hi1) } 5 | 6 | void insertion_sort_free (loc x, loc r) 7 | { 0 <= n ; r :-> 0 ** sll(x, n, lo, hi) } 8 | { true ; r :-> y ** srtl(y, n, lo, hi) } 9 | { 10 | if (x == 0) { 11 | } else { 12 | let nxt2 = *(x + 1); 13 | insertion_sort_free(nxt2, y); 14 | let y12 = *r; 15 | srtl_insert(y12, x); 16 | let y22 = *x; 17 | *r = y22; 18 | free(x); 19 | } 20 | } 21 | ### 22 | ERROR -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification/tree/tree-copy.syn: -------------------------------------------------------------------------------- 1 | should be able to synthesize a tree copy (with elements) 2 | 3 | ##### 4 | 5 | {true ; r :-> x ** tree(x, s)} 6 | void tree_copy(loc r) 7 | {true ; r :-> y ** tree(x, s) ** tree(y, s) } 8 | 9 | ##### 10 | 11 | void tree_copy (loc r) { 12 | let x = *r; 13 | if (x == 0) { 14 | } else { 15 | let v = *x; 16 | let l = *(x + 1); 17 | let rx = *(x + 2); 18 | *x = l; 19 | tree_copy(x); 20 | let yx = *x; 21 | *r = rx; 22 | tree_copy(r); 23 | let yr = *r; 24 | let y = malloc(3); 25 | *r = y; 26 | *(y + 1) = yx; 27 | *(y + 2) = yr; 28 | *x = v; 29 | *y = v; 30 | } 31 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/cyclic-benchmarks/tree/predicates.def: -------------------------------------------------------------------------------- 1 | 2 | predicate sll(loc x, set s) { 3 | | x == 0 => { s == {} ; emp } 4 | | not (x == 0) => { s == {v} ++ s1 ; [x, 2] ** x :-> v ** (x + 1) :-> nxt ** sll(nxt, s1) } 5 | } 6 | 7 | predicate tree(loc x, set s) { 8 | | x == 0 => {s == {} ; emp} 9 | | not (x == 0) => {s == {v} ++ s1 ++ s2 ; 10 | [x, 3] ** x :-> v ** (x + 1) :-> l ** (x + 2) :-> r ** tree(l, s1) ** tree(r, s2)} 11 | } 12 | 13 | predicate dll(loc x, loc z, set s) { 14 | | x == 0 => { s == {} ; emp } 15 | | not (x == 0) => 16 | { s == {v} ++ s1 ; [x, 3] ** x :-> v ** (x + 1) :-> w ** (x + 2) :-> z ** dll(w, x, s1) } 17 | } 18 | -------------------------------------------------------------------------------- /src/test/scala/org/tygus/suslik/parsing/TestNewSyntax.scala: -------------------------------------------------------------------------------- 1 | package org.tygus.suslik.parsing 2 | 3 | import org.scalatest.{FunSpec, Matchers} 4 | import org.tygus.suslik.synthesis.{SynConfig, SynthesisRunnerUtil, defaultConfig} 5 | 6 | 7 | class TestNewSyntax extends FunSpec with Matchers with SynthesisRunnerUtil { 8 | 9 | override def doRun(testName: String, desc: String, in: String, out: String, params: SynConfig = defaultConfig): Unit = { 10 | super.doRun(testName, desc, in, out, params) 11 | it(desc) { 12 | synthesizeFromSpec(testName, in, out, params) 13 | } 14 | } 15 | 16 | describe("New syntax test") { 17 | runAllTestsFromDir("syntax") 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/test/scala/org/tygus/suslik/synthesis/AccountTests.scala: -------------------------------------------------------------------------------- 1 | package org.tygus.suslik.synthesis 2 | 3 | import org.scalatest.{FunSpec, Matchers} 4 | 5 | /** 6 | * @author Ilya Sergey 7 | */ 8 | 9 | class AccountTests extends FunSpec with Matchers with SynthesisRunnerUtil { 10 | 11 | override def doRun(testName: String, desc: String, in: String, out: String, params: SynConfig = defaultConfig): Unit = { 12 | super.doRun(testName, desc, in, out, params) 13 | it(desc) { 14 | synthesizeFromSpec(testName, in, out, params) 15 | } 16 | } 17 | 18 | describe("SL-based synthesizer with one-constructor predicates") { 19 | runAllTestsFromDir("account") 20 | } 21 | 22 | } -------------------------------------------------------------------------------- /src/test/resources/fixme-synthesis/holes/call_extra_arg.sus: -------------------------------------------------------------------------------- 1 | /* extra arg in function call */ 2 | void srtl_insert (loc x, loc r) 3 | {0 <= n /\ 0 <= k /\ k <= 7 ; r :-> k ** srtl(x, n, lo, hi) } 4 | {n1 == n + 1 /\ lo1 == (k <= lo ? k : lo) /\ hi1 == (hi <= k ? k : hi) ; r :-> y ** srtl(y, n1, lo1, hi1) } 5 | 6 | void insertion_sort_free (loc x, loc r) 7 | { 0 <= n ; r :-> 0 ** sll(x, n, lo, hi) } 8 | { true ; r :-> y ** srtl(y, n, lo, hi) } 9 | { 10 | if (x == 0) { 11 | } else { 12 | let nxt2 = *(x + 1); 13 | insertion_sort_free(nxt2, r, r); 14 | let y12 = *r; 15 | srtl_insert(y12, x); 16 | let y22 = *x; 17 | *r = y22; 18 | free(x); 19 | } 20 | } 21 | ### 22 | ERROR -------------------------------------------------------------------------------- /src/test/resources/synthesis/paper-benchmarks/tree/tree-copy.syn: -------------------------------------------------------------------------------- 1 | should be able to synthesize a tree copy (with elements) 2 | 3 | ##### 4 | 5 | {true ; r :-> x ** tree(x, s)} 6 | void tree_copy(loc r) 7 | {true ; r :-> y ** tree(x, s) ** tree(y, s) } 8 | 9 | ##### 10 | 11 | void tree_copy (loc r) { 12 | let x = *r; 13 | if (x == 0) { 14 | } else { 15 | let v = *x; 16 | let l = *(x + 1); 17 | let rx = *(x + 2); 18 | *x = l; 19 | tree_copy(x); 20 | let yx = *x; 21 | *r = rx; 22 | tree_copy(r); 23 | let yr = *r; 24 | let y = malloc(3); 25 | *r = y; 26 | *(y + 1) = yx; 27 | *(y + 2) = yr; 28 | *x = v; 29 | *y = v; 30 | } 31 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification-benchmarks/tree/tree-copy.syn: -------------------------------------------------------------------------------- 1 | should be able to synthesize a tree copy (with elements) 2 | 3 | ##### 4 | 5 | {true ; r :-> x ** tree(x, s)} 6 | void tree_copy(loc r) 7 | {true ; r :-> y ** tree(x, s) ** tree(y, s) } 8 | 9 | ##### 10 | 11 | void tree_copy (loc r) { 12 | let x = *r; 13 | if (x == 0) { 14 | } else { 15 | let v = *x; 16 | let l = *(x + 1); 17 | let rx = *(x + 2); 18 | *x = l; 19 | tree_copy(x); 20 | let yx = *x; 21 | *r = rx; 22 | tree_copy(r); 23 | let yr = *r; 24 | let y = malloc(3); 25 | *r = y; 26 | *(y + 1) = yx; 27 | *(y + 2) = yr; 28 | *x = v; 29 | *y = v; 30 | } 31 | } -------------------------------------------------------------------------------- /src/test/scala/org/tygus/suslik/synthesis/AbductionTests.scala: -------------------------------------------------------------------------------- 1 | package org.tygus.suslik.synthesis 2 | 3 | import org.scalatest.{FunSpec, Matchers} 4 | 5 | /** 6 | * @author Ilya Sergey 7 | */ 8 | 9 | class AbductionTests extends FunSpec with Matchers with SynthesisRunnerUtil { 10 | 11 | override def doRun(testName: String, desc: String, in: String, out: String, params: SynConfig = defaultConfig): Unit = { 12 | super.doRun(testName, desc, in, out, params) 13 | it(desc) { 14 | synthesizeFromSpec(testName, in, out, params) 15 | } 16 | } 17 | 18 | describe("SL-based synthesizer with abductor for hypothesis preconditions") { 19 | runAllTestsFromDir("abduct") 20 | } 21 | 22 | } -------------------------------------------------------------------------------- /src/test/resources/fixme-synthesis/holes/call_insufficient_args.sus: -------------------------------------------------------------------------------- 1 | /* insufficient args in function call */ 2 | void srtl_insert (loc x, loc r) 3 | {0 <= n /\ 0 <= k /\ k <= 7 ; r :-> k ** srtl(x, n, lo, hi) } 4 | {n1 == n + 1 /\ lo1 == (k <= lo ? k : lo) /\ hi1 == (hi <= k ? k : hi) ; r :-> y ** srtl(y, n1, lo1, hi1) } 5 | 6 | void insertion_sort_free (loc x, loc r) 7 | { 0 <= n ; r :-> 0 ** sll(x, n, lo, hi) } 8 | { true ; r :-> y ** srtl(y, n, lo, hi) } 9 | { 10 | if (x == 0) { 11 | } else { 12 | let nxt2 = *(x + 1); 13 | insertion_sort_free(nxt2); 14 | let y12 = *r; 15 | srtl_insert(y12, x); 16 | let y22 = *x; 17 | *r = y22; 18 | free(x); 19 | } 20 | } 21 | ### 22 | ERROR -------------------------------------------------------------------------------- /src/test/resources/fixme-synthesis/holes/malloc_free4.sus: -------------------------------------------------------------------------------- 1 | /* read doesn't destroy vars */ 2 | 3 | void swap(loc x, loc y) 4 | {} 5 | {} 6 | { 7 | let a = malloc(1); 8 | let b = malloc(1); 9 | let c = malloc(1); 10 | let d = malloc(1); 11 | *a = b; 12 | let ar = *a; 13 | *c = d; 14 | let cr = *c; 15 | let cr2 = *c; 16 | free(a); 17 | free(b); 18 | free(c); 19 | free(cr); 20 | } 21 | 22 | ### 23 | 24 | void swap (loc x, loc y) { 25 | let a = malloc(1); 26 | let b = malloc(1); 27 | let c = malloc(1); 28 | let d = malloc(1); 29 | *a = b; 30 | let ar = *a; 31 | *c = d; 32 | let cr = *c; 33 | let cr2 = *c; 34 | free(a); 35 | free(b); 36 | free(c); 37 | free(cr); 38 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/paper-benchmarks/tree/common.def: -------------------------------------------------------------------------------- 1 | predicate treeN(loc x, int n) { 2 | | x == 0 => { n == 0 ; emp } 3 | | not (x == 0) => { n == 1 + n1 + n2 /\ 0 <= n1 /\ 0 <= n2 ; 4 | [x, 3] ** x :-> v ** (x + 1) :-> l ** (x + 2) :-> r ** treeN(l, n1) ** treeN(r, n2)} 5 | } 6 | 7 | predicate tree(loc x, set s) { 8 | | x == 0 => {s =i {}; emp} 9 | | not (x == 0) => {s =i {v} ++ s1 ++ s2 ; [x, 3] ** x :-> v ** (x + 1) :-> l ** (x + 2) :-> r ** tree(l, s1) ** tree(r, s2)} 10 | } 11 | 12 | predicate sll(loc x, set s) { 13 | | x == 0 => { s =i {} ; emp } 14 | | not (x == 0) => { s =i {v} ++ s1 ; [x, 2] ** x :-> v ** (x + 1) :-> nxt ** sll(nxt, s1) } 15 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/flatten/tree-flatten.syn: -------------------------------------------------------------------------------- 1 | should be able to flatten the tree into a list given an auxiliary function for list appending 2 | 3 | #### 4 | 5 | { true ; z :-> x ** tree(x, s)} 6 | void tree_flatten(loc z) 7 | { true ; z :-> y ** lseg(y, 0, s)} 8 | 9 | #### 10 | 11 | void tree_flatten (loc z) { 12 | let x = *z; 13 | if (x == 0) { 14 | } else { 15 | let v = *x; 16 | let l = *(x + 1); 17 | let r = *(x + 2); 18 | *x = l; 19 | tree_flatten(x); 20 | *z = r; 21 | tree_flatten(z); 22 | let yz = *z; 23 | list_append(x, yz); 24 | let zx = *x; 25 | let y = malloc(2); 26 | free(x); 27 | *z = y; 28 | *(y + 1) = zx; 29 | *y = v; 30 | } 31 | } -------------------------------------------------------------------------------- /src/test/scala/org/tygus/suslik/fixme/FailingTests.scala: -------------------------------------------------------------------------------- 1 | package org.tygus.suslik.synthesis 2 | 3 | import org.scalatest.{FunSpec, Matchers} 4 | 5 | /** 6 | * @author Roman Shchedrin 7 | */ 8 | 9 | abstract class FailingTests extends FunSpec with Matchers with SynthesisRunnerUtil { 10 | 11 | override def doRun(testName: String, desc: String, in: String, out: String, params: SynConfig = defaultConfig): Unit = { 12 | super.doRun(testName, desc, in, out, params) 13 | it(desc) { 14 | synthesizeFromSpec(testName, in, out, params) 15 | } 16 | } 17 | 18 | if(false) { 19 | describe("Failing tests") { 20 | runAllTestsFromDir("failing-examples") 21 | } 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/all-benchmarks/bst/left-rotate.syn: -------------------------------------------------------------------------------- 1 | binary search tree: rotate left 2 | 3 | ##### 4 | 5 | { not (r == 0) && 0 <= sz1 && 0 <= sz2 && v <= lower s2 && (v == upper ([v] + s1)) ; 6 | ret :-> unused ** [x, 3] ** x :-> v ** (x + 1) :-> l ** (x + 2) :-> r ** bst(l, s1, sz1) ** bst(r, s2, sz2) } 7 | void bst_left_rotate (loc x, loc ret) 8 | { sz3 + sz4 == sz1 + sz2 && (v3 == lower ([v3] + s4)) && v3 >= upper s3 ; 9 | ret :-> y ** [y, 3] ** y :-> v3 ** (y + 1) :-> x ** (y + 2) :-> r3 ** bst(x, s3, sz3) ** bst(r3, s4, sz4) } 10 | 11 | ##### 12 | 13 | void bst_left_rotate (loc x, loc ret) { 14 | let r = *(x + 2); 15 | let l = *(r + 1); 16 | *(r + 1) = x; 17 | *(x + 2) = l; 18 | *ret = r; 19 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/all-benchmarks/sll/max.syn: -------------------------------------------------------------------------------- 1 | # -b true -c 2 2 | 3 | singly-linked list: max 4 | 5 | ##### 6 | 7 | { ret :-> a ** sll_bounded(x, n, s) } 8 | void sll_max (loc x, loc ret) 9 | { s == [] || m == upper s ; ret :-> m ** sll_bounded(x, n, s) } 10 | 11 | ##### 12 | 13 | void sll_max (loc x, loc ret) { 14 | if (x == 0) { 15 | } else { 16 | let v = *x; 17 | let n = *(x + 1); 18 | sll_max(n, ret); 19 | let m = *ret; 20 | if (m <= v && v <= m) { 21 | } else { 22 | if (v <= m) { 23 | if (n == 0) { 24 | *(x + 1) = 0; 25 | *ret = v; 26 | } else { 27 | } 28 | } else { 29 | *ret = v; 30 | } 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/all-benchmarks/sll/min.syn: -------------------------------------------------------------------------------- 1 | # -b true -c 2 2 | 3 | singly-linked list: min 4 | 5 | ##### 6 | 7 | { ret :-> a ** sll_bounded(x, n, s) } 8 | void sll_min (loc x, loc ret) 9 | { s == [] || m == lower s ; ret :-> m ** sll_bounded(x, n, s) } 10 | 11 | ##### 12 | 13 | void sll_min (loc x, loc ret) { 14 | if (x == 0) { 15 | } else { 16 | let v = *x; 17 | let n = *(x + 1); 18 | sll_min(n, ret); 19 | let m = *ret; 20 | if (m <= v && v <= m) { 21 | } else { 22 | if (m <= v) { 23 | if (n == 0) { 24 | *(x + 1) = 0; 25 | *ret = v; 26 | } else { 27 | } 28 | } else { 29 | *ret = v; 30 | } 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/tree/tree-copy-ptr.syn: -------------------------------------------------------------------------------- 1 | should be able to synthesize a tree copy (with elements) 2 | 3 | ##### 4 | 5 | {true ; r :-> x ** treeS(x, s)} 6 | void tree_copy(loc r) 7 | {true ; r :-> y ** treeS(x, s) ** treeS(y, s) } 8 | 9 | ##### 10 | 11 | void tree_copy (loc r) { 12 | let x = *r; 13 | if (x == 0) { 14 | } else { 15 | let v = *x; 16 | let l = *(x + 1); 17 | let rx = *(x + 2); 18 | *x = l; 19 | tree_copy(x); 20 | let yx = *x; 21 | *r = rx; 22 | tree_copy(r); 23 | let yr = *r; 24 | let y = malloc(3); 25 | *(x + 2) = yr; 26 | *(x + 1) = yx; 27 | *r = y; 28 | *(y + 1) = l; 29 | *(y + 2) = rx; 30 | *x = v; 31 | *y = v; 32 | } 33 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/all-benchmarks/bst/right-rotate.syn: -------------------------------------------------------------------------------- 1 | binary search tree: rotate right 2 | 3 | ##### 4 | 5 | { not (l == 0) && 0 <= sz1 && 0 <= sz2 && (v == lower ([v] + s2)) && v >= upper s1 ; 6 | ret :-> unused ** [x, 3] ** x :-> v ** (x + 1) :-> l ** (x + 2) :-> r ** bst(l, s1, sz1) ** bst(r, s2, sz2) } 7 | void bst_right_rotate (loc x, loc ret) 8 | { sz3 + sz4 == sz1 + sz2 && v3 <= lower s4 && (v3 == upper ([v3] + s3)) ; 9 | ret :-> y ** [y, 3] ** y :-> v3 ** (y + 1) :-> l3 ** (y + 2) :-> x ** bst(l3, s3, sz3) ** bst(x, s4, sz4) } 10 | 11 | ##### 12 | 13 | void bst_right_rotate (loc x, loc ret) { 14 | let l = *(x + 1); 15 | let r = *(l + 2); 16 | *(l + 2) = x; 17 | *(x + 1) = r; 18 | *ret = l; 19 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/all-benchmarks/sll/predicates.def: -------------------------------------------------------------------------------- 1 | predicate sll(loc x, set s) { 2 | | x == 0 => { s == {} ; emp } 3 | | not (x == 0) => { s == {v} ++ s1 ; [x, 2] ** x :-> v ** (x + 1) :-> nxt ** sll(nxt, s1) } 4 | } 5 | 6 | predicate ulist(loc x, set s) { 7 | | x == 0 => { s == {} ; emp } 8 | | not (x == 0) => { s == {v} ++ s1 /\ not (v in s1); [x, 2] ** x :-> v ** (x + 1) :-> nxt ** ulist(nxt, s1) } 9 | } 10 | 11 | predicate sll_bounded(loc x, int len, interval s) { 12 | | x == 0 => { len == 0 && s == [] ; emp } 13 | | not (x == 0) => { 0 <= len1 && len == len1 + 1 && s == s1 + [v] ; 14 | [x, 2] ** x :-> v ** (x + 1) :-> nxt ** sll_bounded(nxt, len1, s1) } 15 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/all-benchmarks/tree/free2.syn: -------------------------------------------------------------------------------- 1 | Deallocate two trees 2 | 3 | ### 4 | 5 | {tree(x, s1) ** tree(y, s2)} 6 | void treefree2(loc x, loc y) 7 | {emp } 8 | 9 | ### 10 | 11 | void treefree2 (loc x, loc y) { 12 | if (x == 0) { 13 | if (y == 0) { 14 | } else { 15 | let l = *y; 16 | let r = *(y + 1); 17 | treefree2(r, l); 18 | free(y); 19 | } 20 | } else { 21 | let lx = *x; 22 | let rx = *(x + 1); 23 | if (y == 0) { 24 | treefree2(rx, lx); 25 | free(x); 26 | } else { 27 | let l = *y; 28 | let r = *(y + 1); 29 | treefree2(r, l); 30 | treefree2(lx, rx); 31 | free(x); 32 | free(y); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/packed-tree/unpack.syn: -------------------------------------------------------------------------------- 1 | # -o 2 -c 2 2 | 3 | #### 4 | 5 | { r :-> x ** r + 1 :-> b ** packed_tree(x, sz, s) } 6 | void unpack(loc r) 7 | { r :-> x + 2*sz ** r + 1 :-> y ** packed_tree(x, sz, s) ** tree(y, sz, s) } 8 | 9 | #### 10 | 11 | void unpack (loc r) { 12 | let x = *r; 13 | let t = *x; 14 | if (t == 1) { 15 | let y = malloc(2); 16 | *x = 1; 17 | *r = x + (2 * 1); 18 | *(r + 1) = y; 19 | *y = 1; 20 | } else { 21 | *r = x + 2; 22 | unpack(r); 23 | let y1 = *(r + 1); 24 | unpack(r); 25 | let y2 = *(r + 1); 26 | let y = malloc(4); 27 | *x = 0; 28 | *(r + 1) = y; 29 | *y = 0; 30 | *(y + 2) = y1; 31 | *(y + 3) = y2; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/all-benchmarks/avl/copy.syn: -------------------------------------------------------------------------------- 1 | should be able to synthesize a tree copy (with elements) 2 | 3 | ##### 4 | 5 | {true ; r :-> x ** avl(x, n, h)} 6 | void avl_copy(loc r) 7 | {true ; r :-> y ** avl(x, n, h) ** avl(y, n, h) } 8 | 9 | ##### 10 | 11 | {r :-> x ** avl(x, n, h)<_alpha_8>} 12 | {r :-> y ** avl(x, n, h)<_alpha_9> ** avl(y, n, h)<_alpha_10>} 13 | void avl_copy (loc r) { 14 | let x = *r; 15 | if (x == 0) { 16 | } else { 17 | let l = *(x + 1); 18 | let rx = *(x + 2); 19 | *r = l; 20 | avl_copy(r); 21 | let y1 = *r; 22 | *r = rx; 23 | avl_copy(r); 24 | let y2 = *r; 25 | let y = malloc(3); 26 | *r = y; 27 | *(y + 1) = y1; 28 | *(y + 2) = y2; 29 | } 30 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification/tree/common.def: -------------------------------------------------------------------------------- 1 | predicate tree(loc x, set s) { 2 | | x == null => {s =i {}; emp} 3 | | not (x == null) => {s =i {v} ++ s1 ++ s2 ; [x, 3] ** x :-> v ** (x + 1) :-> l ** (x + 2) :-> r ** tree(l, s1) ** tree(r, s2)} 4 | } 5 | 6 | predicate treeN(loc x, int n) { 7 | | x == null => { n == 0 ; emp } 8 | | not (x == null) => { n == 1 + n1 + n2 /\ 0 <= n1 /\ 0 <= n2 ; 9 | [x, 3] ** x :-> v ** (x + 1) :-> l ** (x + 2) :-> r ** treeN(l, n1) ** treeN(r, n2)} 10 | } 11 | 12 | predicate sll(loc x, set s) { 13 | | x == null => { s =i {} ; emp } 14 | | not (x == null) => { s =i {v} ++ s1 ; [x, 2] ** x :-> v ** (x + 1) :-> nxt ** sll(nxt, s1) } 15 | } 16 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/cyclic-benchmarks/tree/treefree2.syn: -------------------------------------------------------------------------------- 1 | Deallocate two trees 2 | 3 | ### 4 | 5 | {tree(x, s1) ** tree(y, s2)} 6 | void treefree2(loc x, loc y) 7 | {emp } 8 | 9 | ### 10 | 11 | void treefree2 (loc x, loc y) { 12 | if (x == 0) { 13 | if (y == 0) { 14 | } else { 15 | let l = *y; 16 | let r = *(y + 1); 17 | treefree2(r, l); 18 | free(y); 19 | } 20 | } else { 21 | let lx = *x; 22 | let rx = *(x + 1); 23 | if (y == 0) { 24 | treefree2(rx, lx); 25 | free(x); 26 | } else { 27 | let l = *y; 28 | let r = *(y + 1); 29 | treefree2(r, l); 30 | treefree2(lx, rx); 31 | free(x); 32 | free(y); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/smallfoot/queue.sf: -------------------------------------------------------------------------------- 1 | /* queues represented as a linked list with front and back pointers 2 | * queue(f,r) iff if f==NULL then emp else lseg(f,r) * r|->NULL) */ 3 | 4 | /* insert new node at rear */ 5 | /* without pointers into the stack, have to pass in f */ 6 | insert(f,r) [if f==NULL then emp else lseg(f,r) * r|->NULL] { 7 | t = new(); 8 | t->tl = NULL; 9 | if(f == NULL) { 10 | r = t; 11 | f = r; 12 | } else { 13 | r->tl = t; 14 | r = t; 15 | } 16 | } [if f==NULL then emp else lseg(f,r) * r|->NULL] 17 | 18 | /* delete node from front */ 19 | delete(f) [lseg(f,_r) * _r|->NULL] { 20 | t = f; 21 | f = f->tl; 22 | dispose t; 23 | } [if f==NULL then emp else lseg(f,_r) * _r|->NULL] 24 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/all-benchmarks/packed/unpack.syn: -------------------------------------------------------------------------------- 1 | # -o 2 -c 2 2 | 3 | #### 4 | 5 | { r :-> x ** r + 1 :-> b ** packed_tree(x, sz, s) } 6 | void unpack(loc r) 7 | { r :-> x + 2*sz ** r + 1 :-> y ** packed_tree(x, sz, s) ** tree(y, sz, s) } 8 | 9 | #### 10 | 11 | void unpack (loc r) { 12 | let x = *r; 13 | let t = *x; 14 | if (t == 1) { 15 | let y = malloc(2); 16 | *x = 1; 17 | *r = x + (2 * 1); 18 | *(r + 1) = y; 19 | *y = 1; 20 | } else { 21 | *r = x + 2; 22 | unpack(r); 23 | let y1 = *(r + 1); 24 | unpack(r); 25 | let y2 = *(r + 1); 26 | let y = malloc(4); 27 | *x = 0; 28 | *(r + 1) = y; 29 | *y = 0; 30 | *(y + 2) = y1; 31 | *(y + 3) = y2; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification-benchmarks/tree/common.def: -------------------------------------------------------------------------------- 1 | predicate tree(loc x, set s) { 2 | | x == null => {s =i {}; emp} 3 | | not (x == null) => {s =i {v} ++ s1 ++ s2 ; [x, 3] ** x :-> v ** (x + 1) :-> l ** (x + 2) :-> r ** tree(l, s1) ** tree(r, s2)} 4 | } 5 | 6 | predicate treeN(loc x, int n) { 7 | | x == null => { n == 0 ; emp } 8 | | not (x == null) => { n == 1 + n1 + n2 /\ 0 <= n1 /\ 0 <= n2 ; 9 | [x, 3] ** x :-> v ** (x + 1) :-> l ** (x + 2) :-> r ** treeN(l, n1) ** treeN(r, n2)} 10 | } 11 | 12 | predicate sll(loc x, set s) { 13 | | x == null => { s =i {} ; emp } 14 | | not (x == null) => { s =i {v} ++ s1 ; [x, 2] ** x :-> v ** (x + 1) :-> nxt ** sll(nxt, s1) } 15 | } 16 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/cyclic-benchmarks/contrived/treefree2.syn: -------------------------------------------------------------------------------- 1 | Deallocate two trees 2 | 3 | ### 4 | 5 | {true; tree(x) ** tree(y)} 6 | void treefree2(loc x, loc y) 7 | {true ; emp } 8 | 9 | ### 10 | 11 | void treefree2 (loc x, loc y) { 12 | if (x == 0) { 13 | if (y == 0) { 14 | } else { 15 | let l = *y; 16 | let r = *(y + 1); 17 | treefree2(r, l); 18 | free(y); 19 | } 20 | } else { 21 | let lx = *x; 22 | let rx = *(x + 1); 23 | if (y == 0) { 24 | treefree2(rx, lx); 25 | free(x); 26 | } else { 27 | let l = *y; 28 | let r = *(y + 1); 29 | treefree2(r, l); 30 | treefree2(lx, rx); 31 | free(x); 32 | free(y); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/scala/org/tygus/suslik/synthesis/tactics/ReplaySynthesis.scala: -------------------------------------------------------------------------------- 1 | package org.tygus.suslik.synthesis.tactics 2 | 3 | import org.tygus.suslik.synthesis.SynConfig 4 | import org.tygus.suslik.synthesis.rules.Rules 5 | 6 | class ReplaySynthesis(config: SynConfig) extends PhasedSynthesis(config) { 7 | var script: List[Int] = config.script 8 | 9 | override def filterExpansions(allExpansions: Seq[Rules.RuleResult]): Seq[Rules.RuleResult] = { 10 | // Interactive mode: ask user to pick an expansion 11 | if (allExpansions.length == 1 || script.isEmpty) allExpansions 12 | else { 13 | val choice = script.head 14 | script = script.tail 15 | val res = allExpansions(choice - 1) 16 | List(res) 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/all-benchmarks/rose-tree/free.syn: -------------------------------------------------------------------------------- 1 | # -o 2 -p true 2 | 3 | should be able to deallocate a rose tree 4 | 5 | ### 6 | 7 | { rose_tree(x, s) } 8 | void rose_tree_free(loc x) 9 | { emp } 10 | 11 | ### 12 | 13 | {rose_tree(x, s)} 14 | {emp} 15 | void rose_tree_free (loc x) { 16 | if (x == 0) { 17 | } else { 18 | rose_tree_free10(x); 19 | } 20 | } 21 | 22 | {not (x == 0) && zx < a ; x :-> bx ** buds(bx, s)[1] ** [x, 1]} 23 | {emp} 24 | void rose_tree_free10 (loc x) { 25 | let b = *x; 26 | if (b == 0) { 27 | free(x); 28 | } else { 29 | let r = *(b + 1); 30 | let n = *(b + 2); 31 | rose_tree_free(r); 32 | *x = n; 33 | rose_tree_free10(x); 34 | free(b); 35 | } 36 | } 37 | 38 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/all-benchmarks/sll/delete-all.syn: -------------------------------------------------------------------------------- 1 | # -b true 2 | singly-linked list: delete all occurrences of x 3 | 4 | ##### 5 | 6 | {true ; sll(x, s) ** ret :-> a} 7 | void sll_delete_all (loc x, loc ret) 8 | {s1 =i s -- {a} ; sll(y, s1) ** ret :-> y } 9 | 10 | ##### 11 | 12 | void sll_delete_all (loc x, loc ret) { 13 | let a2 = *ret; 14 | if (x == 0) { 15 | *ret = 0; 16 | } else { 17 | let v2 = *x; 18 | if (true && v2 <= a2 && a2 <= v2) { 19 | let nxt2 = *(x + 1); 20 | sll_delete_all(nxt2, ret); 21 | free(x); 22 | } else { 23 | let nxt2 = *(x + 1); 24 | sll_delete_all(nxt2, ret); 25 | let y12 = *ret; 26 | *(x + 1) = y12; 27 | *ret = x; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/llist/llist.def: -------------------------------------------------------------------------------- 1 | predicate lseg(loc x, loc y) { 2 | | x == y => {emp} 3 | | not (x == y) => {[x, 2] ** x :-> 0 ** (x + 1) :-> nxt ** lseg(nxt, y)} 4 | } 5 | 6 | predicate lseg1(loc x, loc y) { 7 | | x == y => {emp} 8 | | not (x == y) => {[x, 2] ** x :-> 1 ** (x + 1) :-> nxt ** lseg1(nxt, y)} 9 | } 10 | 11 | predicate lsegn(loc x, loc y, int len) { 12 | | x == y => { len == 0 ; emp } 13 | | not (x == y) => { (len == 1 + len1) /\ (0 <= len1) ; [x, 2] ** x :-> v ** (x + 1) :-> nxt ** lsegn(nxt, y, len1) } 14 | } 15 | 16 | predicate lsegs(loc x, loc y, set s) { 17 | | x == y => { s == {} ; emp } 18 | | x != y => { s == {x} ++ s1 ; [x, 1] ** x :-> nxt ** lsegs(nxt, y, s1) } 19 | } 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/online/tree-flatten.sus: -------------------------------------------------------------------------------- 1 | // flatten a tree into a list 2 | 3 | predicate list(loc x, set s) { 4 | | x == 0 => { s == {} ; emp } 5 | | x != 0 => { s == {v} + s1 ; [x, 2] ** x :-> v ** (x + 1) :-> nxt ** list(nxt, s1) } 6 | } 7 | 8 | predicate tree(loc x, set s) { 9 | | x == 0 => { s == {} ; emp } 10 | | x != 0 => { s == {v} + s1 + s2 ; [x, 3] ** x :-> v ** (x + 1) :-> l ** (x + 2) :-> r ** tree(l, s1) ** tree(r, s2) } 11 | } 12 | 13 | 14 | // Flatten a tree with root `t`; 15 | // `r` stores the address of a list used as an accumulator. 16 | void tree_flatten(loc t, loc r) 17 | { true ; tree(t, s) ** r :-> y ** list(y, acc)} 18 | { s1 == s + acc ; r :-> x ** list(x, s1)} 19 | { 20 | ?? 21 | } 22 | 23 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/paper-benchmarks/sll/sll-delete-all.syn: -------------------------------------------------------------------------------- 1 | # -b true 2 | singly-linked list: delete all occurrences of x 3 | 4 | ##### 5 | 6 | {true ; sll(x, s) ** ret :-> a} 7 | void sll_delete_all (loc x, loc ret) 8 | {s1 =i s -- {a} ; sll(y, s1) ** ret :-> y } 9 | 10 | ##### 11 | 12 | void sll_delete_all (loc x, loc ret) { 13 | let a2 = *ret; 14 | if (x == 0) { 15 | *ret = 0; 16 | } else { 17 | let v2 = *x; 18 | if (true && v2 <= a2 && a2 <= v2) { 19 | let nxt2 = *(x + 1); 20 | sll_delete_all(nxt2, ret); 21 | free(x); 22 | } else { 23 | let nxt2 = *(x + 1); 24 | sll_delete_all(nxt2, ret); 25 | let y12 = *ret; 26 | *(x + 1) = y12; 27 | *ret = x; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/cyclic-benchmarks/rose-tree/rose-tree-free.syn: -------------------------------------------------------------------------------- 1 | # -o 2 -p true 2 | 3 | should be able to deallocate a rose tree 4 | 5 | ### 6 | 7 | { rose_tree(x, s) } 8 | void rose_tree_free(loc x) 9 | { emp } 10 | 11 | ### 12 | 13 | {rose_tree(x, s)} 14 | {emp} 15 | void rose_tree_free (loc x) { 16 | if (x == 0) { 17 | } else { 18 | rose_tree_free10(x); 19 | } 20 | } 21 | 22 | {not (x == 0) && zx < a ; x :-> bx ** buds(bx, s)[1] ** [x, 1]} 23 | {emp} 24 | void rose_tree_free10 (loc x) { 25 | let b = *x; 26 | if (b == 0) { 27 | free(x); 28 | } else { 29 | let r = *(b + 1); 30 | let n = *(b + 2); 31 | rose_tree_free(r); 32 | *x = n; 33 | rose_tree_free10(x); 34 | free(b); 35 | } 36 | } 37 | 38 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification/srtl/insertion-sort-free.syn: -------------------------------------------------------------------------------- 1 | sorted list: insert an element 2 | 3 | ##### 4 | 5 | {0 <= n /\ 0 <= k /\ k <= 7 ; r :-> k ** srtl(x, n, lo, hi) } 6 | void srtl_insert (loc x, loc r) 7 | {n1 == 1 + n /\ lo1 == (k <= lo ? k : lo) /\ hi1 == (hi <= k ? k : hi) ; r :-> y ** srtl(y, n1, lo1, hi1) } 8 | 9 | { 0 <= n ; r :-> null ** sll(x, n, lo, hi) } 10 | void insertion_sort_free (loc x, loc r) 11 | { true ; r :-> y ** srtl(y, n, lo, hi) } 12 | 13 | ##### 14 | 15 | void insertion_sort_free (loc x, loc r) { 16 | if (x == null) { 17 | } else { 18 | let n = *(x + 1); 19 | insertion_sort_free(n, r); 20 | let yn = *r; 21 | srtl_insert(yn, x); 22 | let y = *x; 23 | free(x); 24 | *r = y; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/online/sorted-insert.syn: -------------------------------------------------------------------------------- 1 | #. this -b true -c 2 2 | insert an element into a sorted list 3 | 4 | ### 5 | 6 | predicate srtl(loc x, int len, int lo, int hi) { 7 | | x == 0 => { len == 0 /\ lo == 255 /\ hi == 0 ; emp } 8 | | not (x == 0) => { len == 1 + len1 /\ 0 <= len1 /\ lo == (v <= lo1 ? v : lo1) /\ hi == (hi1 <= v ? v : hi1) /\ 9 | v <= lo1 /\ 0 <= v /\ v <= 255 ; 10 | [x, 2] ** x :-> v ** (x + 1) :-> nxt ** srtl(nxt, len1, lo1, hi1) } 11 | } 12 | 13 | {0 <= n /\ 0 <= k /\ k <= 255 ; r :-> k ** srtl(x, n, lo, hi) } 14 | void srtl_insert (loc x, loc r) 15 | {n1 == n + 1 /\ lo1 == (k <= lo ? k : lo) /\ hi1 == (hi <= k ? k : hi) ; r :-> y ** srtl(y, n1, lo1, hi1) } 16 | 17 | ### -------------------------------------------------------------------------------- /src/test/resources/synthesis/paper-benchmarks/bst/bst-find-smallest.syn: -------------------------------------------------------------------------------- 1 | # -x true -c 2 -p true 2 | 3 | binary search tree: find smallest element 4 | 5 | ##### 6 | 7 | { 0 <= sz /\ 0 <= lo /\ hi <= 7; 8 | ret :-> unused ** 9 | bst(x, sz, lo, hi) } 10 | 11 | void bst_find_smallest (loc x, loc ret) 12 | 13 | { ret :-> lo ** 14 | bst(x, sz, lo, hi) } 15 | 16 | ##### 17 | 18 | {0 <= lo && 0 <= sz && hi <= 7 ; ret :-> unused ** bst(x, sz, lo, hi)} 19 | {ret :-> lo ** bst(x, sz, lo, hi)} 20 | void bst_find_smallest (loc x, loc ret) { 21 | if (x == 0) { 22 | *ret = 7; 23 | } else { 24 | let v = *x; 25 | let lx = *(x + 1); 26 | bst_find_smallest(lx, ret); 27 | let l = *ret; 28 | *ret = v <= l ? v : l; 29 | } 30 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/paper-benchmarks/srtl/insertion-sort-free.syn: -------------------------------------------------------------------------------- 1 | sorted list: insert an element 2 | 3 | ##### 4 | 5 | {0 <= n /\ 0 <= k /\ k <= 7 ; r :-> k ** srtl(x, n, lo, hi) } 6 | void srtl_insert (loc x, loc r) 7 | {n1 == n + 1 /\ lo1 == (k <= lo ? k : lo) /\ hi1 == (hi <= k ? k : hi) ; r :-> y ** srtl(y, n1, lo1, hi1) } 8 | 9 | { 0 <= n ; r :-> 0 ** sll(x, n, lo, hi) } 10 | void insertion_sort_free (loc x, loc r) 11 | { true ; r :-> y ** srtl(y, n, lo, hi) } 12 | 13 | ##### 14 | 15 | void insertion_sort_free (loc x, loc r) { 16 | if (x == 0) { 17 | } else { 18 | let n = *(x + 1); 19 | insertion_sort_free(n, r); 20 | let yn = *r; 21 | srtl_insert(yn, x); 22 | let y = *x; 23 | free(x); 24 | *r = y; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/test/resources/fixme-synthesis/failing-locally-for-ilya/sll-delete-all.syn: -------------------------------------------------------------------------------- 1 | #. -b true 2 | singly-linked list: delete all occurrences of x 3 | 4 | ##### 5 | 6 | {true ; sll(x, s) ** ret :-> a} 7 | void sll_delete_all (loc x, loc ret) 8 | {s1 =i s -- {a} ; sll(y, s1) ** ret :-> y } 9 | 10 | ##### 11 | 12 | void sll_delete_all (loc x, loc ret) { 13 | let a = *ret; 14 | if (x == 0) { 15 | *ret = 0; 16 | } else { 17 | let v = *x; 18 | if (a <= v && v <= a) { 19 | let n = *(x + 1); 20 | sll_delete_all(n, x); 21 | let y = *x; 22 | free(x); 23 | *ret = y; 24 | } else { 25 | let n = *(x + 1); 26 | sll_delete_all(n, ret); 27 | let y = *ret; 28 | *(x + 1) = y; 29 | *ret = x; 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification/bst/bst-find-smallest.syn: -------------------------------------------------------------------------------- 1 | # -x true -c 2 -p true 2 | 3 | binary search tree: find smallest element 4 | 5 | ##### 6 | 7 | { 0 <= sz /\ 0 <= lo /\ hi <= 7; 8 | retv :-> unused ** 9 | bst(x, sz, lo, hi) } 10 | 11 | void bst_find_smallest (loc x, loc retv) 12 | 13 | { retv :-> lo ** 14 | bst(x, sz, lo, hi) } 15 | 16 | ##### 17 | 18 | {0 <= lo && 0 <= sz && hi <= 7 ; retv :-> unused ** bst(x, sz, lo, hi)} 19 | {retv :-> lo ** bst(x, sz, lo, hi)} 20 | void bst_find_smallest (loc x, loc retv) { 21 | if (x == 0) { 22 | *retv = 7; 23 | } else { 24 | let v = *x; 25 | let lx = *(x + 1); 26 | bst_find_smallest(lx, retv); 27 | let l = *retv; 28 | *retv = v <= l ? v : l; 29 | } 30 | } -------------------------------------------------------------------------------- /src/test/resources/fixme-synthesis/failing-examples/predicates.def: -------------------------------------------------------------------------------- 1 | predicate lseg(loc x) { 2 | | x == 0 => { true ; emp } 3 | | not (x == 0) => { true ; [x, 1] ** x :-> nxt ** lseg(nxt) } 4 | } 5 | 6 | predicate tree(loc x) { 7 | | x == 0 => {true ; emp} 8 | | not (x == 0) => {true ; [x, 2] ** x :-> l ** (x + 1) :-> r ** tree(l) ** tree(r)} 9 | } 10 | 11 | predicate treeS(loc x, set s) { 12 | | x == 0 => {s =i {}; emp} 13 | | not (x == 0) => {s =i {v} ++ s1 ++ s2 ; [x, 3] ** x :-> v ** (x + 1) :-> l ** (x + 2) :-> r ** treeS(l, s1) ** treeS(r, s2)} 14 | } 15 | 16 | predicate sll(loc x, set s) { 17 | | x == 0 => { s =i {} ; emp } 18 | | not (x == 0) => { s =i {v} ++ s1 ; [x, 2] ** x :-> v ** (x + 1) :-> nxt ** sll(nxt, s1) } 19 | } 20 | 21 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/all-benchmarks/bst/min.syn: -------------------------------------------------------------------------------- 1 | # -c 2 -p true -x false 2 | 3 | binary search tree: find smallest element 4 | 5 | ##### 6 | 7 | { 0 <= sz ; ret :-> unused ** bst(x, s, sz) } 8 | void bst_min (loc x, loc ret) 9 | { s == [] || m == lower s ; ret :-> m ** bst(x, s, sz) } 10 | 11 | ##### 12 | 13 | {0 <= lo && 0 <= sz && hi <= 7 ; ret :-> unused ** bst(x, sz, lo, hi)} 14 | {ret :-> lo ** bst(x, sz, lo, hi)} 15 | void bst_min (loc x, loc ret) { 16 | if (x == 0) { 17 | } else { 18 | let v = *x; 19 | let l = *(x + 1); 20 | let r = *(x + 2); 21 | bst_min(l, ret); 22 | let m = *ret; 23 | bst_min(r, ret); 24 | if (l == 0) { 25 | *(x + 1) = 0; 26 | *ret = v; 27 | } else { 28 | *ret = m; 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification/srtl/insertion-sort.syn: -------------------------------------------------------------------------------- 1 | sorted list: insert an element 2 | 3 | ##### 4 | 5 | {0 <= n /\ 0 <= k /\ k <= 7 ; r :-> k ** srtl(x, n, lo, hi) } 6 | void srtl_insert (loc x, loc r) 7 | {n1 == 1 + n /\ lo1 == (k <= lo ? k : lo) /\ hi1 == (hi <= k ? k : hi) ; r :-> y ** srtl(y, n1, lo1, hi1) } 8 | 9 | { 0 <= n ; r :-> null ** sll(x, n, lo, hi) } 10 | void insertion_sort (loc x, loc r) 11 | { true ; r :-> y ** sll(x, n, lo, hi) ** srtl(y, n, lo, hi) } 12 | 13 | ##### 14 | 15 | void insertion_sort (loc x, loc r) { 16 | if (x == null) { 17 | } else { 18 | let v = *x; 19 | let n = *(x + 1); 20 | insertion_sort(n, r); 21 | let yn = *r; 22 | srtl_insert(yn, x); 23 | let y = *x; 24 | *r = y; 25 | *x = v; 26 | } 27 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/paper-benchmarks/srtl/insertion-sort.syn: -------------------------------------------------------------------------------- 1 | sorted list: insert an element 2 | 3 | ##### 4 | 5 | {0 <= n /\ 0 <= k /\ k <= 7 ; r :-> k ** srtl(x, n, lo, hi) } 6 | void srtl_insert (loc x, loc r) 7 | {n1 == n + 1 /\ lo1 == (k <= lo ? k : lo) /\ hi1 == (hi <= k ? k : hi) ; r :-> y ** srtl(y, n1, lo1, hi1) } 8 | 9 | { 0 <= n ; r :-> 0 ** sll(x, n, lo, hi) } 10 | void insertion_sort (loc x, loc r) 11 | { true ; r :-> y ** sll(x, n, lo, hi) ** srtl(y, n, lo, hi) } 12 | 13 | ##### 14 | 15 | void insertion_sort (loc x, loc r) { 16 | if (x == 0) { 17 | } else { 18 | let v = *x; 19 | let n = *(x + 1); 20 | insertion_sort(n, r); 21 | let yn = *r; 22 | srtl_insert(yn, x); 23 | let y = *x; 24 | *r = y; 25 | *x = v; 26 | } 27 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification-benchmarks-advanced/bst/bst-find-smallest.syn: -------------------------------------------------------------------------------- 1 | # -x true -c 2 -p true 2 | 3 | binary search tree: find smallest element 4 | 5 | ##### 6 | 7 | { 0 <= sz /\ 0 <= lo /\ hi <= 7; 8 | retv :-> 666 ** 9 | bst(x, sz, lo, hi) } 10 | 11 | void bst_find_smallest (loc x, loc retv) 12 | 13 | { retv :-> lo ** 14 | bst(x, sz, lo, hi) } 15 | 16 | ##### 17 | 18 | {0 <= lo && 0 <= sz && hi <= 7 ; retv :-> unused ** bst(x, sz, lo, hi)} 19 | {retv :-> lo ** bst(x, sz, lo, hi)} 20 | void bst_find_smallest (loc x, loc retv) { 21 | if (x == 0) { 22 | *retv = 7; 23 | } else { 24 | let v = *x; 25 | let lx = *(x + 1); 26 | bst_find_smallest(lx, retv); 27 | let l = *retv; 28 | *retv = v <= l ? v : l; 29 | } 30 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification-benchmarks-advanced/srtl/insertion-sort-free.syn: -------------------------------------------------------------------------------- 1 | sorted list: insert an element 2 | 3 | ##### 4 | 5 | {0 <= n /\ 0 <= k /\ k <= 7 ; r :-> k ** srtl(x, n, lo, hi) } 6 | void srtl_insert (loc x, loc r) 7 | {n1 == 1 + n /\ lo1 == (k <= lo ? k : lo) /\ hi1 == (hi <= k ? k : hi) ; r :-> y ** srtl(y, n1, lo1, hi1) } 8 | 9 | { 0 <= n ; r :-> null ** sll(x, n, lo, hi) } 10 | void insertion_sort_free (loc x, loc r) 11 | { true ; r :-> y ** srtl(y, n, lo, hi) } 12 | 13 | ##### 14 | 15 | void insertion_sort_free (loc x, loc r) { 16 | if (x == null) { 17 | } else { 18 | let n = *(x + 1); 19 | insertion_sort_free(n, r); 20 | let yn = *r; 21 | srtl_insert(yn, x); 22 | let y = *x; 23 | free(x); 24 | *r = y; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/paper-benchmarks/srtl/common.def: -------------------------------------------------------------------------------- 1 | predicate sll(loc x, int len, int lo, int hi) { 2 | | x == 0 => { len == 0 /\ lo == 7 /\ hi == 0 ; emp } 3 | | not (x == 0) => { len == 1 + len1 /\ 0 <= len1 /\ lo == (v <= lo1 ? v : lo1) /\ hi == (hi1 <= v ? v : hi1) /\ 0 <= v /\ v <= 7; 4 | [x, 2] ** x :-> v ** (x + 1) :-> nxt ** sll(nxt, len1, lo1, hi1) } 5 | } 6 | 7 | predicate srtl(loc x, int len, int lo, int hi) { 8 | | x == 0 => { len == 0 /\ lo == 7 /\ hi == 0 ; emp } 9 | | not (x == 0) => { len == 1 + len1 /\ 0 <= len1 /\ lo == (v <= lo1 ? v : lo1) /\ hi == (hi1 <= v ? v : hi1) /\ v <= lo1 /\ 0 <= v /\ v <= 7 ; 10 | [x, 2] ** x :-> v ** (x + 1) :-> nxt ** srtl(nxt, len1, lo1, hi1) } 11 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/cyclic-benchmarks/contrived/predicates.def: -------------------------------------------------------------------------------- 1 | predicate list(loc x) { 2 | | x == 0 => { true ; emp } 3 | | not (x == 0) => { true ; [x, 1] ** x :-> nxt ** list(nxt) } 4 | } 5 | 6 | predicate tree(loc x) { 7 | | x == 0 => {true ; emp} 8 | | not (x == 0) => {true ; [x, 2] ** x :-> l ** (x + 1) :-> r ** tree(l) ** tree(r)} 9 | } 10 | 11 | predicate treeS(loc x, set s) { 12 | | x == 0 => {s == {}; emp} 13 | | not (x == 0) => {s == {v} ++ s1 ++ s2 ; [x, 3] ** x :-> v ** (x + 1) :-> l ** (x + 2) :-> r ** treeS(l, s1) ** treeS(r, s2)} 14 | } 15 | 16 | predicate sll(loc x, set s) { 17 | | x == 0 => { s == {} ; emp } 18 | | not (x == 0) => { s == {v} ++ s1 ; [x, 2] ** x :-> v ** (x + 1) :-> nxt ** sll(nxt, s1) } 19 | } 20 | 21 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification/bst/bst-right-rotate.syn: -------------------------------------------------------------------------------- 1 | binary search tree: rotate right 2 | 3 | ##### 4 | 5 | { not (l == null) /\ 0 <= sz1 /\ 0 <= sz2 /\ 0 <= v /\ v <= 7 /\ hi1 <= v /\ v <= lo2 ; 6 | retv :-> unused ** [x, 3] ** x :-> v ** (x + 1) :-> l ** (x + 2) :-> r ** bst(l, sz1, lo1, hi1) ** bst(r, sz2, lo2, hi2) } 7 | void bst_right_rotate (loc x, loc retv) 8 | { sz3 + sz4 == sz1 + sz2 /\ 0 <= sz3 /\ 0 <= sz4 /\ 0 <= v3 /\ v3 <= 7 /\ hi3 <= v3 /\ v3 <= lo4 ; 9 | retv :-> y ** [y, 3] ** y :-> v3 ** (y + 1) :-> l3 ** (y + 2) :-> x ** bst(l3, sz3, lo3, hi3) ** bst(x, sz4, lo4, hi4) } 10 | 11 | ##### 12 | 13 | void bst_right_rotate (loc x, loc retv) { 14 | let l = *(x + 1); 15 | let r = *(l + 2); 16 | *(l + 2) = x; 17 | *retv = l; 18 | *(x + 1) = r; 19 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification/srtl/common.def: -------------------------------------------------------------------------------- 1 | predicate sll(loc x, int len, int lo, int hi) { 2 | | x == null => { len == 0 /\ lo == 7 /\ hi == 0 ; emp } 3 | | not (x == null) => { len == 1 + len1 /\ 0 <= len1 /\ lo == (v <= lo1 ? v : lo1) /\ hi == (hi1 <= v ? v : hi1) /\ 0 <= v /\ v <= 7; 4 | [x, 2] ** x :-> v ** (x + 1) :-> nxt ** sll(nxt, len1, lo1, hi1) } 5 | } 6 | 7 | predicate srtl(loc x, int len, int lo, int hi) { 8 | | x == null => { len == 0 /\ lo == 7 /\ hi == 0 ; emp } 9 | | not (x == null) => { len == 1 + len1 /\ 0 <= len1 /\ lo == (v <= lo1 ? v : lo1) /\ hi == (hi1 <= v ? v : hi1) /\ v <= lo1 /\ 0 <= v /\ v <= 7 ; 10 | [x, 2] ** x :-> v ** (x + 1) :-> nxt ** srtl(nxt, len1, lo1, hi1) } 11 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification-benchmarks-advanced/srtl/insertion-sort.syn: -------------------------------------------------------------------------------- 1 | sorted list: insert an element 2 | 3 | ##### 4 | 5 | {0 <= n /\ 0 <= k /\ k <= 7 ; r :-> k ** srtl(x, n, lo, hi) } 6 | void srtl_insert (loc x, loc r) 7 | {n1 == 1 + n /\ lo1 == (k <= lo ? k : lo) /\ hi1 == (hi <= k ? k : hi) ; r :-> y ** srtl(y, n1, lo1, hi1) } 8 | 9 | { 0 <= n ; r :-> null ** sll(x, n, lo, hi) } 10 | void insertion_sort (loc x, loc r) 11 | { true ; r :-> y ** sll(x, n, lo, hi) ** srtl(y, n, lo, hi) } 12 | 13 | ##### 14 | 15 | void insertion_sort (loc x, loc r) { 16 | if (x == null) { 17 | } else { 18 | let v = *x; 19 | let n = *(x + 1); 20 | insertion_sort(n, r); 21 | let yn = *r; 22 | srtl_insert(yn, x); 23 | let y = *x; 24 | *r = y; 25 | *x = v; 26 | } 27 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/all-benchmarks/srtl/insert.syn: -------------------------------------------------------------------------------- 1 | # -b true -c 2 2 | sorted list: insert an element 3 | 4 | ##### 5 | 6 | { l >= 0 ; r :-> k ** srtl(x, s, l) } 7 | void srtl_insert (loc x, loc r)[int k] 8 | { r :-> y ** srtl(y, s + [k], l + 1) } 9 | 10 | ##### 11 | 12 | void srtl_insert (loc x, loc r) { 13 | let k = *r; 14 | if (x == 0) { 15 | let y = malloc(2); 16 | *r = y; 17 | *y = lower ([] ++ [k]); 18 | *(y + 1) = 0; 19 | } else { 20 | let v = *x; 21 | let n = *(x + 1); 22 | if (v <= k) { 23 | srtl_insert(n, r); 24 | let y = *r; 25 | *r = x; 26 | *(x + 1) = y; 27 | } else { 28 | *r = v; 29 | srtl_insert(n, r); 30 | let y = *r; 31 | *r = x; 32 | *(x + 1) = y; 33 | *x = k; 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /src/test/scala/org/tygus/suslik/synthesis/BasicSynthesisTests.scala: -------------------------------------------------------------------------------- 1 | package org.tygus.suslik.synthesis 2 | 3 | import org.scalatest.{FunSpec, Matchers} 4 | 5 | /** 6 | * @author Nadia Polikarpova, Ilya Sergey 7 | */ 8 | 9 | class BasicSynthesisTests extends FunSpec with Matchers with SynthesisRunnerUtil { 10 | 11 | override def doRun(testName: String, desc: String, in: String, out: String, params: SynConfig = defaultConfig): Unit = { 12 | super.doRun(testName, desc, in, out, params) 13 | it(desc) { 14 | synthesizeFromSpec(testName, in, out, params) 15 | } 16 | } 17 | 18 | describe("SL-based synthesizer") { 19 | runAllTestsFromDir("simple") 20 | } 21 | 22 | describe("SL-based synthesizer with entailment") { 23 | runAllTestsFromDir("entail") 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/cyclic-benchmarks/contrived/listfree3.syn: -------------------------------------------------------------------------------- 1 | Deallocate three linked lists 2 | 3 | ### 4 | 5 | {true; list(x) ** list(y) ** list(z)} 6 | void listfree3(loc x, loc y, loc z) 7 | {true ; emp } 8 | 9 | ### 10 | 11 | void listfree3 (loc x, loc y, loc z) { 12 | if (x == 0) { 13 | listfree300(x, y, z); 14 | } else { 15 | let n = *x; 16 | listfree3(z, y, n); 17 | free(x); 18 | } 19 | } 20 | 21 | void listfree300 (loc x, loc y, loc z) { 22 | if (y == 0) { 23 | listfree30001(x, y, z); 24 | } else { 25 | let n = *y; 26 | listfree300(x, z, n); 27 | free(y); 28 | } 29 | } 30 | 31 | void listfree30001 (loc x, loc y, loc z) { 32 | if (z == 0) { 33 | } else { 34 | let n = *z; 35 | listfree30001(x, y, n); 36 | free(z); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/paper-benchmarks/bst/bst-left-rotate.syn: -------------------------------------------------------------------------------- 1 | binary search tree: rotate left 2 | 3 | ##### 4 | 5 | { not (r == 0) /\ 0 <= sz1 /\ 0 <= sz2 /\ 0 <= v /\ v <= 7 /\ hi1 <= v /\ v <= lo2 /\ 0 <= a /\ 0 <= b ; 6 | ret :-> unused ** [x, 3] ** x :-> v ** (x + 1) :-> l ** (x + 2) :-> r ** bst(l, sz1, lo1, hi1) ** bst(r, sz2, lo2, hi2) } 7 | void bst_left_rotate (loc x, loc ret) 8 | { sz3 + sz4 == sz1 + sz2 /\ 0 <= sz3 /\ 0 <= sz4 /\ 0 <= v3 /\ v3 <= 7 /\ hi3 <= v3 /\ v3 <= lo4 ; 9 | ret :-> y ** [y, 3] ** y :-> v3 ** (y + 1) :-> x ** (y + 2) :-> r3 ** bst(x, sz3, lo3, hi3) ** bst(r3, sz4, lo4, hi4) } 10 | 11 | ##### 12 | 13 | void bst_left_rotate (loc x, loc ret) { 14 | let r = *(x + 2); 15 | let l = *(r + 1); 16 | *(r + 1) = x; 17 | *ret = r; 18 | *(x + 2) = l; 19 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/paper-benchmarks/bst/bst-right-rotate.syn: -------------------------------------------------------------------------------- 1 | binary search tree: rotate right 2 | 3 | ##### 4 | 5 | { not (l == 0) /\ 0 <= sz1 /\ 0 <= sz2 /\ 0 <= v /\ v <= 7 /\ hi1 <= v /\ v <= lo2 /\ 0 <= a /\ 0 <= b ; 6 | ret :-> unused ** [x, 3] ** x :-> v ** (x + 1) :-> l ** (x + 2) :-> r ** bst(l, sz1, lo1, hi1) ** bst(r, sz2, lo2, hi2) } 7 | void bst_right_rotate (loc x, loc ret) 8 | { sz3 + sz4 == sz1 + sz2 /\ 0 <= sz3 /\ 0 <= sz4 /\ 0 <= v3 /\ v3 <= 7 /\ hi3 <= v3 /\ v3 <= lo4 ; 9 | ret :-> y ** [y, 3] ** y :-> v3 ** (y + 1) :-> l3 ** (y + 2) :-> x ** bst(l3, sz3, lo3, hi3) ** bst(x, sz4, lo4, hi4) } 10 | 11 | ##### 12 | 13 | void bst_right_rotate (loc x, loc ret) { 14 | let l = *(x + 1); 15 | let r = *(l + 2); 16 | *(l + 2) = x; 17 | *ret = l; 18 | *(x + 1) = r; 19 | } -------------------------------------------------------------------------------- /src/main/scala/org/tygus/suslik/synthesis/tactics/InteractiveSynthesis.scala: -------------------------------------------------------------------------------- 1 | package org.tygus.suslik.synthesis.tactics 2 | 3 | import org.tygus.suslik.synthesis.SynConfig 4 | import org.tygus.suslik.synthesis.rules.Rules 5 | import org.tygus.suslik.util.SynStats 6 | 7 | class InteractiveSynthesis(config: SynConfig, stats: SynStats) extends PhasedSynthesis(config) { 8 | 9 | override def filterExpansions(allExpansions: Seq[Rules.RuleResult]): Seq[Rules.RuleResult] = { 10 | // Interactive mode: ask user to pick an expansion 11 | val choice = if (allExpansions.length == 1) 0 else readInt 12 | if (0 < choice && choice <= allExpansions.size) { 13 | val res = allExpansions(choice - 1) 14 | stats.addExpansionChoice(choice) 15 | List(res) 16 | } else allExpansions 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification-benchmarks-advanced/bst/bst-right-rotate.syn: -------------------------------------------------------------------------------- 1 | binary search tree: rotate right 2 | 3 | ##### 4 | 5 | { not (l == null) /\ 0 <= sz1 /\ 0 <= sz2 /\ 0 <= v /\ v <= 7 /\ hi1 <= v /\ v <= lo2 ; 6 | retv :-> unused ** [x, 3] ** x :-> v ** (x + 1) :-> l ** (x + 2) :-> r ** bst(l, sz1, lo1, hi1) ** bst(r, sz2, lo2, hi2) } 7 | void bst_right_rotate (loc x, loc retv) 8 | { sz3 + sz4 == sz1 + sz2 /\ 0 <= sz3 /\ 0 <= sz4 /\ 0 <= v3 /\ v3 <= 7 /\ hi3 <= v3 /\ v3 <= lo4 ; 9 | retv :-> y ** [y, 3] ** y :-> v3 ** (y + 1) :-> l3 ** (y + 2) :-> x ** bst(l3, sz3, lo3, hi3) ** bst(x, sz4, lo4, hi4) } 10 | 11 | ##### 12 | 13 | void bst_right_rotate (loc x, loc retv) { 14 | let l = *(x + 1); 15 | let r = *(l + 2); 16 | *(l + 2) = x; 17 | *retv = l; 18 | *(x + 1) = r; 19 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification-benchmarks-advanced/srtl/common.def: -------------------------------------------------------------------------------- 1 | predicate sll(loc x, int len, int lo, int hi) { 2 | | x == null => { len == 0 /\ lo == 7 /\ hi == 0 ; emp } 3 | | not (x == null) => { len == 1 + len1 /\ 0 <= len1 /\ lo == (v <= lo1 ? v : lo1) /\ hi == (hi1 <= v ? v : hi1) /\ 0 <= v /\ v <= 7; 4 | [x, 2] ** x :-> v ** (x + 1) :-> nxt ** sll(nxt, len1, lo1, hi1) } 5 | } 6 | 7 | predicate srtl(loc x, int len, int lo, int hi) { 8 | | x == null => { len == 0 /\ lo == 7 /\ hi == 0 ; emp } 9 | | not (x == null) => { len == 1 + len1 /\ 0 <= len1 /\ lo == (v <= lo1 ? v : lo1) /\ hi == (hi1 <= v ? v : hi1) /\ v <= lo1 /\ 0 <= v /\ v <= 7 ; 10 | [x, 2] ** x :-> v ** (x + 1) :-> nxt ** srtl(nxt, len1, lo1, hi1) } 11 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification/bst/bst-left-rotate.syn: -------------------------------------------------------------------------------- 1 | binary search tree: rotate left 2 | 3 | ##### 4 | 5 | { not (r == null) /\ 0 <= sz1 /\ 0 <= sz2 /\ 0 <= v /\ v <= 7 /\ hi1 <= v /\ v <= lo2 /\ 0 <= a /\ 0 <= b ; 6 | retv :-> unused ** [x, 3] ** x :-> v ** (x + 1) :-> l ** (x + 2) :-> r ** bst(l, sz1, lo1, hi1) ** bst(r, sz2, lo2, hi2) } 7 | void bst_left_rotate (loc x, loc retv) 8 | { sz3 + sz4 == sz1 + sz2 /\ 0 <= sz3 /\ 0 <= sz4 /\ 0 <= v3 /\ v3 <= 7 /\ hi3 <= v3 /\ v3 <= lo4 ; 9 | retv :-> y ** [y, 3] ** y :-> v3 ** (y + 1) :-> x ** (y + 2) :-> r3 ** bst(x, sz3, lo3, hi3) ** bst(r3, sz4, lo4, hi4) } 10 | 11 | ##### 12 | 13 | void bst_left_rotate (loc x, loc retv) { 14 | let r = *(x + 2); 15 | let l = *(r + 1); 16 | *(r + 1) = x; 17 | *retv = r; 18 | *(x + 2) = l; 19 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/all-benchmarks/bst/insert.syn: -------------------------------------------------------------------------------- 1 | # -b true -c 2 2 | binary search tree: insert an element 3 | 4 | ##### 5 | 6 | { 0 <= n ; ret :-> k ** bst(x, s, n) } 7 | void bst_insert (loc x, loc ret) 8 | { ret :-> y ** bst(y, s + [k], n + 1) } 9 | 10 | ##### 11 | 12 | void bst_insert (loc x, loc ret) { 13 | let k = *ret; 14 | if (x == 0) { 15 | let y = malloc(3); 16 | *ret = y; 17 | *(y + 1) = 0; 18 | *(y + 2) = 0; 19 | *y = k; 20 | } else { 21 | let v = *x; 22 | let l = *(x + 1); 23 | let r = *(x + 2); 24 | if (k <= v) { 25 | bst_insert(l, ret); 26 | let y = *ret; 27 | *ret = x; 28 | *(x + 1) = y; 29 | } else { 30 | bst_insert(r, ret); 31 | let y = *ret; 32 | *ret = x; 33 | *(x + 2) = y; 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /src/test/resources/synthesis/all-benchmarks/rbt/size.syn: -------------------------------------------------------------------------------- 1 | # -o 2 -c 2 2 | should be able to synthesize tree size 3 | 4 | work only with `-o=2 -c=2` 5 | 6 | ##### 7 | 8 | 9 | {0 <= n ; r :-> 0 ** treeN(x, n, cl, bn) } 10 | void tree_size(loc x, loc r) 11 | {true ; r :-> n ** treeN(x, n, cl, bn) } 12 | 13 | ##### 14 | 15 | void tree_size (loc x, loc r) { 16 | if (x == 0) { 17 | } else { 18 | let c = *x; 19 | let l = *(x + 1); 20 | let rx = *(x + 2); 21 | if (c == 1) { 22 | tree_size(l, r); 23 | let n1 = *r; 24 | *r = 0; 25 | tree_size(rx, r); 26 | let n = *r; 27 | *r = 1 + n1 + n; 28 | } else { 29 | tree_size(l, r); 30 | let n1 = *r; 31 | *r = 0; 32 | tree_size(rx, r); 33 | let n = *r; 34 | *r = 1 + n1 + n; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/test/resources/synthesis/certification-benchmarks-advanced/bst/bst-left-rotate.syn: -------------------------------------------------------------------------------- 1 | binary search tree: rotate left 2 | 3 | ##### 4 | 5 | { not (r == null) /\ 0 <= sz1 /\ 0 <= sz2 /\ 0 <= v /\ v <= 7 /\ hi1 <= v /\ v <= lo2 /\ 0 <= a /\ 0 <= b ; 6 | retv :-> unused ** [x, 3] ** x :-> v ** (x + 1) :-> l ** (x + 2) :-> r ** bst(l, sz1, lo1, hi1) ** bst(r, sz2, lo2, hi2) } 7 | void bst_left_rotate (loc x, loc retv) 8 | { sz3 + sz4 == sz1 + sz2 /\ 0 <= sz3 /\ 0 <= sz4 /\ 0 <= v3 /\ v3 <= 7 /\ hi3 <= v3 /\ v3 <= lo4 ; 9 | retv :-> y ** [y, 3] ** y :-> v3 ** (y + 1) :-> x ** (y + 2) :-> r3 ** bst(x, sz3, lo3, hi3) ** bst(r3, sz4, lo4, hi4) } 10 | 11 | ##### 12 | 13 | void bst_left_rotate (loc x, loc retv) { 14 | let r = *(x + 2); 15 | let l = *(r + 1); 16 | *(r + 1) = x; 17 | *retv = r; 18 | *(x + 2) = l; 19 | } -------------------------------------------------------------------------------- /src/main/scala/org/tygus/suslik/synthesis/rules/RuleUtils.scala: -------------------------------------------------------------------------------- 1 | package org.tygus.suslik.synthesis.rules 2 | 3 | import org.tygus.suslik.SSLException 4 | import org.tygus.suslik.synthesis.SynthesisException 5 | import org.tygus.suslik.synthesis.SymbolicExecutionError 6 | 7 | /** 8 | * @author Ilya Sergey 9 | */ 10 | 11 | trait RuleUtils { 12 | 13 | val exceptionQualifier: String 14 | 15 | case class SynthesisRuleException(msg: String) extends SSLException(exceptionQualifier, msg) 16 | 17 | def ruleAssert(assertion: Boolean, msg: String): Unit = if (!assertion) throw SynthesisRuleException(msg) 18 | def synAssert(assertion: Boolean, msg: String): Unit = if (!assertion) throw SynthesisException(msg) 19 | def symExecAssert(assertion: Boolean, msg: String): Unit = if (!assertion) throw SymbolicExecutionError(msg) 20 | } 21 | 22 | --------------------------------------------------------------------------------