Upgrade to Pro — share decks privately, control downloads, hide ads and more …

TPPMark2016 を解きながら学ぶ VeriFast

eldesh
November 19, 2016

TPPMark2016 を解きながら学ぶ VeriFast

(静的コード解析の会 第0回)[https://metasepi.connpass.com/event/42141/] で発表した資料です。

TPP2016で出題された問題である TPPMark を題材として、C 言語検証器である VeriFast による回答を構成しつつ VeriFast 自体の入門的解説をします。

eldesh

November 19, 2016
Tweet

More Decks by eldesh

Other Decks in Programming

Transcript

  1. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর TPPMark2016 Λղ͖ͳ͕ΒֶͿ

    VeriFast @eldesh https://twitter.com/eldesh http://d.hatena.ne.jp/eldesh ੩తίʔυղੳͷձ ୈ 0 ճ 2016/11/19 2016/11/19 VeriFast Introduction 1 / 77
  2. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর ໨࣍ 1

    VeriFast ֓આ 2 VeriFast ೖ໳ 3 جຊ෦඼ͷఆٛ 4 ओఆཧͷূ໌ 5 ࢀর 2016/11/19 VeriFast Introduction 2 / 77
  3. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর What is

    this slide? TPP20161 Ͱग़୊͞Εͨ໰୊Ͱ͋Δ TPPMark Λ୊ࡐͱͯ͠ɺC ݴޠݕূث Ͱ͋Δ VeriFast ʹΑΔճ౴Λߏ੒ͭͭ͠ VeriFast ࣗମͷೖ໳తղઆΛ͠ ·͢ɻ 112th Theorem Proving and Provers. ఆཧূ໌ͱূ໌ثʹؔ͢Δձٞ 2016/11/19 VeriFast Introduction 3 / 77
  4. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর ૝ఆ/ର৅ಡऀ ඞਢ

    C ݴޠ͕෼͔Δ ๬·͍͠ ࣄલ৚݅/ࣄޙ৚݅ͱ͍͏ݴ༿Λฉ͍ͨ͜ͱ͕͋Δ ؔ਺ܕݴޠ (ML) ͷॳาతͳཧղ 2016/11/19 VeriFast Introduction 4 / 77
  5. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর VeriFast ֓ཁ

    1/2 ·ͣ VeriFast ͷಛ௃Λڍ͓͛ͯ͘ɻ ෼཭࿦ཧʹج͍ͮͯ C ·ͨ͸ Java ϓϩάϥϜΛݕূ͢Δݕূث ίϝϯτ಺ʹ஫ऍΛॻ͔ͤɺ੔߹ੑΛݕࠪ ࣄલ৚݅, ࣄޙ৚݅ ϧʔϓෆม৚݅ C ϥΠΫͳ७ਮؔ਺ܕݴޠ Ϟδϡϥʔͳ࢓༷ͱݕࠪ ΑΓԼͷϨΠϠͷ໋୊ͷத਎ʹґଘ͠ͳ͍ ໋୊ͷ੔߹ੑݕࠪʹ͸ SMT ιϧό 2 Λ࢖͏ ઐ༻ IDE ͕͋Δ ݕূʹࣦഊͨ͠৔߹ɺࣦഊͨ͠εςοϓ·ͰͷγϯϘϦοΫ࣮ߦͷϑ ϩʔ͕֬ೝͰ͖Δ tactic ͸ແ͠ 2࢖༻͢Διϧό͸ Redux(಺੡ιϧό) ·ͨ͸ z3 2016/11/19 VeriFast Introduction 5 / 77
  6. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর VeriFast ֓ཁ

    2/2 VeriFast ͰݕূͰ͖Δ಺༰ ܭࢉ݁Ռ͕࢓༷Λຬ͢͜ͱ ϝϞϦ҆શੑ ϦʔΫ͠ͳ͍ ෆਖ਼ͳσϦϑΝϨϯεΛ͠ͳ͍ ਺஋ԋࢉͷΦʔόʔ/Ξϯμʔϑϩʔ͕ແ͍͜ͱ (skip Մೳ) ฒྻϓϩάϥϜͷม਺ΞΫηεͷҰ؏ੑอূ ϩοΫΛऔಘͤͣ (ϩοΫͰอޢͨ͠ม਺΁ͷ) ॻ͖ࠐΈ͸ߦΘΕͳ͍ ϩοΫෆม৚݅Λຬ͍ͨͯ͠ͳ͍ΞϯϩοΫ͸ى͖ͳ͍ ؔ਺ͷఀࢭੑ 2016/11/19 VeriFast Introduction 6 / 77
  7. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর TPPMark2016 TPPMark

    ͷ໰୊จΛݟ͓ͯ͜͏ɻ ໰୊ 2.1(ґଘܕϓϩάϥϛϯάతͳදݱ) Ҿ਺ͱͯ͠ҎԼͷ̏ͭ ϦετͷϦετ lst ੔਺ i ੔਺ j Λड͚औͬͨΒɺ lst ͷ i ൪໨ͷϦετͷ j ൪໨ͷཁૉΛ ࡟আͨ͠΋ͷΛฦ ؔ͢਺ remove-lst Λ࡞੒ͤΑɻͦͷࡍɺҎԼͷ̏ͭͷ৚݅ lst ͷ i ൪໨ͷϦετ͕ଘࡏ͢Δɻ i ൪໨ͷϦετͷ j ൪໨ͷཁૉ͕ଘࡏ͢Δɻ ฦ͞ΕΔϦετͨͪͷ௕͞͸ɺi ൪໨ͷΈ 1 ୹͘ͳ͓ͬͯΓɺଞ͸มΘ Βͳ͍ɻ ͕อূ͞ΕΔΑ͏ʹͤΑɻ ʢ͜͜Ͱɺઌ಄͸͍ͣΕ΋ 0 ൪໨ͱ͢Δɻ ʣ 2016/11/19 VeriFast Introduction 7 / 77
  8. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর TPPMark ͷܗࣜԽΛ࢝ΊΔલʹ.

    . . VeriFast ͷ “࠷΋جຊతͳػೳ” Λղઆ͢Δɻ 2016/11/19 VeriFast Introduction 8 / 77
  9. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর ࣄલ৚݅ͱࣄޙ৚݅ VeriFast

    ͷ஫ऍ͸શͯ//@ʹΑΔҰߦίϝϯτ಺·ͨ͸/*@͔Β@*/·Ͱͷϒ ϩοΫίϝϯτ಺ʹهड़͢Δɻݕূ͍ͨؔ͠਺ʹ requires Ͱࣄલ৚݅Λɺ ensures Ͱࣄޙ৚݅Λهड़͠ɺVeriFast Ͱ࣮૷ͱͷҰ؏ੑΛݕূ͢Δ 3ɻ P=ࣄલ৚݅ Q=ࣄޙ৚݅ int F (int x) //@ requires P; //@ ensures Q; { // ໋୊ P ͕੒Γཱͭ ... // ໋୊ Q ͕੒Γཱͭ } 3ݕূ͍ͨؔ͠਺͔Βݺ͹Ε͍ͯΔؔ਺ʹ΋஫ऍ͕ඞཁ 2016/11/19 VeriFast Introduction 9 / 77
  10. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর ۭͷ৚݅ ·ͣԿ΋͠ͳ͍ؔ਺͔Β࢝ΊΑ͏ɻҎԼͷؔ਺

    empty_cmd ͸Կ΋ҙຯͷ͋ Δ͜ͱΛ͠ͳ͍ͨΊɺͦΕΛ໋୊Ͱද͍ͨ͠ɻͦͷͨΊʹ͸͍ͭͰ΋੒Γ ໋ཱͭ୊Λࢦఆ͢Ε͹Α͍ɻ Կ΋͠ͳ͍ؔ਺ͷݕূ void empty_cmd (void) //@ requires emp; //@ ensures emp; { } emp ͸ৗʹ੒Γ໋ཱͭ୊ 4ɻ 4emp ͷଞʹ true ΋ಉ͡ҙຯ͕ͩɺϒʔϧ஋ͱฆΒΘ͍͠ͷͰ emp Λ࠾༻ͨ͠ɻ 2016/11/19 VeriFast Introduction 10 / 77
  11. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর ໭Γ஋ʹؔ͢Δ໋୊ ໭Γ஋ʹؔ͢Δ໋୊Λॻ͘͜ͱ͕ग़དྷΔɻ໭Γ஋͸

    ensures અͷதͰ result ͱͯ͠ࢀরͰ͖Δ 5ɻ less than ͷ࢓༷ bool compare (int x, int y) //@ requires emp; //@ ensures result == (x < y); { return x < y; // ฦΓ஋͸େখൺֱͷ݁ՌʹҰக͢Δ } 5࣮͸ result ͸ requires ͷதͰ΋ࢀরͰ͖Δ 2016/11/19 VeriFast Introduction 11 / 77
  12. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর ෼཭ੵ ෳ਺ͷ໋୊͕੒Γཱͭ͜ͱΛࣔͨ͢Ίʹ͸ɺ໋୊Λ&*&6

    Ͱ۠੾ͬͯฒ΂Ε ͹Α͍ɻྫ͑͹͋Δ໋୊ P ͱ͋Δ໋୊ Q ͕ͲͪΒ΋੒Γཱͭ৔߹͸ P &*& Q ͱදه͢Δɻ ಉ࣌ʹ੒Γཱͭෳ਺ͷ໋୊ int plus_positive (int x, int y) //@ requires 0 < x &*& 0 < y; //@ ensures result == (x + y); { return x + y; } plus_positive ͸Ҿ਺ x ͱ y ͦΕͧΕ͕ਖ਼਺Ͱ͋Δ͜ͱΛ྆ํཁٻ͢Δ 7ɻ 6෼཭ੵ; separation conjunctionɻseparation logic ͷಋೖ͢ΔΦϖϨʔλɻ 7ݫີʹ͸ࣄલ৚݅ʹ (ྫ͑͹)(x + y) ≤ INT_MAX ͕଍Γͳ͍ɻCheck arithmetic overflow Λແޮʹͯ͠ݕࠪ͢Δ͜ͱɻ 2016/11/19 VeriFast Introduction 12 / 77
  13. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর σϦϑΝϨϯε 1/2

    ϙΠϯλͷࢦ͍ͯ͠Δ஋ʹݴٴ͢Δʹ͸ઐ༻ΦϖϨʔλ | → Λ࢖͏ɻ| → ͷ ӈลʹ͸ແ໊ύλʔϯ (_) ·ͨ͸ม਺Λࢦఆग़དྷΔɻ ϓϦϛςΟϒܕͷϙΠϯλ void div (int x, int d, int * q, int * m) //@ requires d != 0 &*& *q |-> _ &*& *m |-> _; //@ ensures *q |-> x/d &*& *m |-> x%d; { *q = x/d; *m = x%d; } | → ͸ਖ਼͍͠ϝϞϦΛࢦ͍ͯ͠Δͱ͍͏ओுΛؚΜͰ͍Δࣄʹ஫ҙɻ 2016/11/19 VeriFast Introduction 13 / 77
  14. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর σϦϑΝϨϯε 1/2

    ϙΠϯλͷࢦ͍ͯ͠Δ஋ʹݴٴ͢Δʹ͸ઐ༻ΦϖϨʔλ | → Λ࢖͏ɻ| → ͷ ӈลʹ͸ແ໊ύλʔϯ (_) ·ͨ͸ม਺Λࢦఆग़དྷΔɻ struct ܕͷϙΠϯλ struct boxed { int x; }; void update (boxed * b, int v) //@ requires b->x |-> _; //@ ensures b->x |-> v; { b->x = v; } | → ͸ਖ਼͍͠ϝϞϦΛࢦ͍ͯ͠Δͱ͍͏ओுΛؚΜͰ͍Δࣄʹ஫ҙɻ 2016/11/19 VeriFast Introduction 13 / 77
  15. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর σϦϑΝϨϯε 2/2

    | → ͷӈลͰ?Λࢦఆ͢Δͱม਺Λಋೖ͢Δ͜ͱ͕ग़དྷΔ 8ɻ ม਺ͷಋೖ struct S { int v; }; int getV (struct S * s) //@ requires s->v |-> ?value; a //@ ensures s->v |-> value &*& result == value; { return s->v; } a࣮͸ s->v |-> _ͱ͍͏ͷ͸ S_v(s,_) ͷ౶ҥߏจ యܕతͳ getter ͷ࢓༷͕هड़Ͱ͖͍ͯΔɻ 8ͦͷείʔϓͰϢχʔΫͳ໊લͰ͋Δ͜ͱɻshadowing ͸ແ͍ɻ 2016/11/19 VeriFast Introduction 14 / 77
  16. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর ࢓༷ʹؔ͢Δද໌ ࢓༷ʹؔ͢Δද໌Λ

    assert จʹΑͬͯهड़Ͱ͖ΔɻσϦϑΝϨϯε໋୊ͱ ಉ༷ͷύλʔϯΛࢦఆͰ͖Δɻ ࢓༷ʹؔ͢Δද໌ struct boxed { int x; }; void plus_ass (struct boxed * b, int v) //@ requires b->x |-> ?bx &*& 0 < v; //@ ensures b->x |-> (bx + v); { //@ assert b->x |-> _; b->x += v; //@ assert b->x |-> ?new; //@ assert bx < new; } assert ͸هड़ͨ࣌͠఺ͰίϯςΩετ͔Βಋग़Ͱ͖Δ໋୊Ͱ͋Δ͜ͱΛ֬ ೝग़དྷΔ 9ɻ 9ιϧόʹର͢Δώϯτʹ͸ͳΒͳ͍͜ͱʹ஫ҙɻ 2016/11/19 VeriFast Introduction 15 / 77
  17. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর malloc ͱ

    free ࢓༷Ͱͷώʔϓͷѻ͍Λ஌ΔͨΊʹ malloc ͱ free ͷ࢓༷Λࣔ͢ 10ɻ malloc ͷ࢓༷ void *malloc(int size ); //@ requires 0 ≤ size; /*@ ensures result == 0 ? emp : malloc_block(result , size) &*& ... @*/ free ͷ࢓༷ void free(void *array ); //@ requires malloc_block(array , ?size); //@ ensures emp; malloc ͷ໭Γ஋ʹ͍ͭͯ malloc_block ͱ͍͏໋୊͕੒ΓཱͭɻҰํ free ͸ͦΕΛҾ਺ʹཁٻ͢Δɻ 10bin/malloc.h ʹ͋Δɻຊ౰͸΋ͬͱෳࡶɻ 2016/11/19 VeriFast Introduction 16 / 77
  18. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর malloc ͱ

    free ࢓༷Ͱͷώʔϓͷѻ͍Λ஌ΔͨΊʹ malloc ͱ free ͷ࢓༷Λࣔ͢ 10ɻ malloc ͷ࢓༷ void *malloc(int size ); //@ requires 0 ≤ size; /*@ ensures result == 0 ? emp : malloc_block(result , size) &*& ... @*/ free ͷ࢓༷ void free(void *array ); //@ requires malloc_block(array , ?size); //@ ensures emp; ݕূίϯςΩετதͰ੒Γཱ͍ͬͯΔ malloc_block Λ malloc_block chunk ͱݺͿɻ 10bin/malloc.h ʹ͋Δɻຊ౰͸΋ͬͱෳࡶɻ 2016/11/19 VeriFast Introduction 16 / 77
  19. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর ॴ༗ݖΛද໋͢୊ VeriFast

    ͸ϝϞϦͷॴ༗ݖ 11 Λ௥੻͢Δɻ ͷߦͰ͸໋୊ (malloc_block_ints)12 ͕੒Γཱ͍ͬͯΔ͕. . . malloc;free void malloc_free (void) //@ requires emp; //@ ensures emp; { int * px = malloc(sizeof(int )); if (!px) abort (); free(px); } ໋୊ px̸=NULL *px | → _ malloc_block_ints(px,1) 11ϝϞϦͷϥΠϑλΠϜΛࣗ༝ʹ͢ΔݖརͱϝϞϦΛഁغ͢Δٛ຿ͷ͜ͱɻ 12malloc_block_ints(p,s) = malloc_block(p,4*s) 2016/11/19 VeriFast Introduction 17 / 77
  20. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর ॴ༗ݖΛද໋͢୊ free

    ͔Βฦͬͨ࣌఺Ͱ͸ malloc_block_ints ͸੒Γཱͨͳ͘ͳΔʂ malloc;free void malloc_free (void) //@ requires emp; //@ ensures emp; { int * px = malloc(sizeof(int )); if (!px) abort (); free(px); } ໋୊ px̸=NULL *px| →_ malloc_block_ints(px,1) px̸=NULL ͸੒Γཱͬͨ··ͳ͜ͱʹ஫ҙɻ 2016/11/19 VeriFast Introduction 17 / 77
  21. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর ॴ༗ݖͷͳ͍ϙΠϯλ ݕࠪʹࣦഊ͢ΔྫΛݟͯΈΑ͏ɻmalloc_block

    ͕ແ͍৔߹͸ free ग़དྷແ͍ ͷͰɺҎԼͷύλʔϯ͸ݕࠪʹࣦഊ͢Δɻ not owned ptr void try_free_stack (void) //@ requires emp; //@ ensures emp; { struct S sv; struct S * sp = &sv; //@ assert sp ->v |-> _; free(sp); // No matching heap chunks: // malloc_block_S (sv_addr) } assert ʹ஫໨͢Δͱɺmalloc_block ͱσϦϑΝϨϯεؔ܎͕ผͷ໋୊Ͱද ͞Ε͍ͯΔҙ͕ٛ෼͔Δɻ 2016/11/19 VeriFast Introduction 18 / 77
  22. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর Double Free

    ࣍͸ 2 ॏʹϝϞϦΛղ์͠Α͏ͱ͢Δ৔߹Ͱ͋Δɻfree Ͱ͸ malloc_block ໋୊͕ফඅ͞ΕΔͷͰ double free ͸ҎԼͷΑ͏ʹΤϥʔʹͳΔɻ double free void try_free_free (void) //@ requires emp; //@ ensures emp; { struct S * ms = malloc(sizeof(struct S)); if (ms == NULL) abort (); free(ms); free(ms); // No matching heap chunks: S_v(ms , _) } malloc_block ͕ফඅ͞Εͨ৔߹͸ɺͦΕΛσϦϑΝϨϯε͢Δ໋୊΋ಉ࣌ ʹແޮʹͳΔɻ 2016/11/19 VeriFast Introduction 19 / 77
  23. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর VeriFast ೖ໳·ͱΊ

    ͜͜·ͰͰ VeriFast ͷ࠷΋جຊతͳػೳΛղઆͨ͠ɻ ࣄલ৚݅ͱࣄޙ৚݅ requires,ensures 2016/11/19 VeriFast Introduction 20 / 77
  24. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর VeriFast ೖ໳·ͱΊ

    ͜͜·ͰͰ VeriFast ͷ࠷΋جຊతͳػೳΛղઆͨ͠ɻ ࣄલ৚݅ͱࣄޙ৚݅ requires,ensures ฦΓ஋΁ͷݴٴ result 2016/11/19 VeriFast Introduction 20 / 77
  25. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর VeriFast ೖ໳·ͱΊ

    ͜͜·ͰͰ VeriFast ͷ࠷΋جຊతͳػೳΛղઆͨ͠ɻ ࣄલ৚݅ͱࣄޙ৚݅ requires,ensures ฦΓ஋΁ͷݴٴ result ෼཭ੵ & ∗ &(≒ ∧) 2016/11/19 VeriFast Introduction 20 / 77
  26. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর VeriFast ೖ໳·ͱΊ

    ͜͜·ͰͰ VeriFast ͷ࠷΋جຊతͳػೳΛղઆͨ͠ɻ ࣄલ৚݅ͱࣄޙ৚݅ requires,ensures ฦΓ஋΁ͷݴٴ result ෼཭ੵ & ∗ &(≒ ∧) σϦϑΝϨϯεؔ܎ expr | → ?var 2016/11/19 VeriFast Introduction 20 / 77
  27. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর VeriFast ೖ໳·ͱΊ

    ͜͜·ͰͰ VeriFast ͷ࠷΋جຊతͳػೳΛղઆͨ͠ɻ ࣄલ৚݅ͱࣄޙ৚݅ requires,ensures ฦΓ஋΁ͷݴٴ result ෼཭ੵ & ∗ &(≒ ∧) σϦϑΝϨϯεؔ܎ expr | → ?var ࢓༷Ϩϕϧද໌ assert 2016/11/19 VeriFast Introduction 20 / 77
  28. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর VeriFast ೖ໳·ͱΊ

    ͜͜·ͰͰ VeriFast ͷ࠷΋جຊతͳػೳΛղઆͨ͠ɻ ࣄલ৚݅ͱࣄޙ৚݅ requires,ensures ฦΓ஋΁ͷݴٴ result ෼཭ੵ & ∗ &(≒ ∧) σϦϑΝϨϯεؔ܎ expr | → ?var ࢓༷Ϩϕϧද໌ assert ώʔϓΛද໋͢୊ malloc_block 2016/11/19 VeriFast Introduction 20 / 77
  29. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর VeriFast ೖ໳·ͱΊ

    ͜͜·ͰͰ VeriFast ͷ࠷΋جຊతͳػೳΛղઆͨ͠ɻ ࣄલ৚݅ͱࣄޙ৚݅ requires,ensures ฦΓ஋΁ͷݴٴ result ෼཭ੵ & ∗ &(≒ ∧) σϦϑΝϨϯεؔ܎ expr | → ?var ࢓༷Ϩϕϧද໌ assert ώʔϓΛද໋͢୊ malloc_block 2016/11/19 VeriFast Introduction 20 / 77
  30. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর TPPMark2016 TPPMark

    ͷҰ෦Λ࠶ܝɻ ໰୊ 2.1(ґଘܕϓϩάϥϛϯάతͳදݱ) ͷҰ෦ Ҿ਺ͱͯ͠ҎԼͷ̏ͭ ϦετͷϦετ lst ੔਺ i ੔਺ j Λड͚औͬͨΒɺ. . . ϦετͷϦετʹ͍ͭͯͷૢ࡞Λ࣮૷͢Δඞཁ͕͋Δɻ 2016/11/19 VeriFast Introduction 21 / 77
  31. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর ࣮ߦੈքͷϦετ TPPMark

    ͸ϦετͷϦετͷૢ࡞Λཁٻ͍ͯ͠ΔͷͰɺ·ͣ C ݴޠͰϦε τͷ࣮૷Λ༩͑Α͏ɻ int ͷྻΛอ࣋͢ΔܕΛఆٛ͢Δ struct list_t { int val; struct list_t * next; }; આ໌ͷඞཁ͸ແ͍ΑͶ. . . 2016/11/19 VeriFast Introduction 22 / 77
  32. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর predicate VeriFast

    Ͱ͸ C ݴޠͷ஋·ͨ͸࢓༷தͷ஋ͷؒʹ੒Γ໋ཱͭ୊ʹ໊લΛ෇ ͚ͯఆٛͰ͖Δɻ͜ͷͨΊʹ͸ predicate ΩʔϫʔυΛ࢖͏ɻ ҎԼͷ໋୊ list_len ͸ɺlst ͷ௕͕͞ len Ͱ͋Δ͜ͱΛද͢ 11ɻ list_len ؔ܎ predicate list_len (struct list_t * lst , int len) = lst == NULL ? len == 0 : malloc_block_list_t (lst) &*& lst ->val | → _ &*& lst ->next | → ?next &*& list_len(next , len -1); predicate ͸ؔ਺Ͱ͸ͳ͍ͷͰ໭Γ஋͸ແ͘ɺҾ਺ؒʹ੒Γཱͭ৚݅Λॻ͘ ͜ͱͰఆٛ͞ΕΔɻ 11lst ͱ len ͷؒʹ list_len ͕ࣔؔ͢܎͕੒Γཱͭ 2016/11/19 VeriFast Introduction 23 / 77
  33. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর predicate ͷ࢖༻ྫ

    predicate ͷ஋͸ VeriFast ͷ࢖༻͢Δ໋୊ͱͯ͜͠Ε·ͰͷߏจͷதͰ࢖༻ ͢Δ͜ͱ͕Ͱ͖Δɻ predicate ͷ࢖͍ํ void ignore_list (struct list_t * xs) //@ requires list_len(xs , ?len); //@ ensures emp; { //@ assert list_len(xs , ?v); //@ assert v == len; free_list_t(xs); // ϦετΛഁغ } predicate தͰ͸σϦϑΝϨϯε໋୊ 12 ͱಉ༷ͷύλʔϯ͕ࢦఆͰ͖ɺಋ ೖ͞Εͨม਺͸ͦΕҎ߱Ͱ࢖༻Ͱ͖Δɻ 12expr | → ?var 2016/11/19 VeriFast Introduction 24 / 77
  34. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর Ϧετૢ࡞ؔ਺ͷ࢓༷ ໋୊

    list_len Λ࢖ͬͯ (࣮ߦ࣌ͷ) Ϧετ্ͷجຊతͳؔ਺ͷ࢓༷Λهड़͠ ͯΈΑ͏ɻ ctor ͷ࢓༷ struct list_t * cons_v (int v, struct list_t * tl); //@ requires list_len(tl , ?len); //@ ensures list_len(result , 1+len); length ͷ࢓༷ int length_list_t (struct list_t * lst); /*@ requires list_len(lst , ?len) &*& len ≤ INT_MAX; /*@ ensures list_len(lst , len) &*& result == len; @*/ 2016/11/19 VeriFast Introduction 25 / 77
  35. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর ૉͷ cons_v

    ͷ࣮૷ predicate Ͱ஫ऍͨ͠ cons_v Λ࣮૷ͯ͠ΈΑ͏ɻ cons_v ͷ࣮૷ struct list_t * cons_v (int v, struct list_t * tl) //@ requires list_len(tl , ?len); //@ ensures list_len(result , len +1); { struct list_t * xs = malloc(sizeof(struct list_t )); if (xs == NULL) abort (); xs ->val = v; xs ->next = tl; return xs; // } No matching heap chunks:list_len(xs,(len+1)) 2016/11/19 VeriFast Introduction 26 / 77
  36. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর ૉͷ cons_v

    ͷ࣮૷ ૉͷ࣮૷Ͱ͸Ξϊςʔγϣϯ͕଍ΓͣɺVeriFast ͸໭Γ஋ʹ͍ͭͯ list_len ͕੒Γཱͭ͜ͱ͕෼͔Βͳ͍ɻ cons_v ͷ࣮૷ struct list_t * cons_v (int v, struct list_t * tl) //@ requires list_len(tl , ?len); //@ ensures list_len(result , len +1); { struct list_t * xs = malloc(sizeof(struct list_t )); if (xs == NULL) abort (); xs ->val = v; xs ->next = tl; return xs; // } No matching heap chunks:list_len(xs,(len+1)) 2016/11/19 VeriFast Introduction 26 / 77
  37. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর ૉͷ cons_v

    ͷ࣮૷ return ࣌఺Ͱ੒Γ໋ཱͭ୊Λྻڍͯ͠ΈΔɻ cons_v ͷ࣮૷ struct list_t * cons_v (int v, struct list_t * tl) //@ requires list_len(tl , ?len); //@ ensures list_len(result , len +1); { struct list_t * xs = malloc(sizeof(struct list_t )); if (xs == NULL) abort (); xs ->val = v; xs ->next = tl; return xs; // } ໋୊ xs ̸= NULL malloc_block(xs) xs->val | → v xs->next | → tl list_len(tl,len) No matching heap chunks:list_len(xs,(len+1)) 2016/11/19 VeriFast Introduction 27 / 77
  38. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর predicate ͷߏ੒

    close ίϚϯυ close ίϚϯυʹΑͬͯɺͦͷ࣌఺Ͱಛఆͷ predicate ͕੒Γཱͭ͜ͱΛࣔ ͢͜ͱ͕ग़དྷΔ 13ɻ cons_v ͷ࣮૷ struct list_t * cons_v (int v, struct list_t * tl) //@ requires list_len(tl , ?len); //@ ensures list_len(result , len +1); { struct list_t * xs = malloc(sizeof(struct list_t )); if (xs == NULL) abort (); xs ->val = v; xs ->next = tl; return xs; //@ close list_len(xs , len +1); } ໋୊ xs ̸= NULL malloc_block(xs) xs->val | → v xs->next | → tl list_len(tl,len) ໋୊ xs ̸= NULL list_len(xs,len+1) close 13ࣗಈͰ close ͞ΕΔ͜ͱ΋͋Δ 2016/11/19 VeriFast Introduction 28 / 77
  39. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর predicate ͷߏ੒

    close ίϚϯυ ϝϞϦʹ͍ͭͯͷ໋୊͸ফඅ͞ΕΔ͕ɺߏจ͔Βಋग़͞Ε໋ͨ୊ (xs ̸= NULL) ͸ແ͘ͳΒͳ͍͜ͱʹ஫ҙɻ cons_v ͷ࣮૷ struct list_t * cons_v (int v, struct list_t * tl) //@ requires list_len(tl , ?len); //@ ensures list_len(result , len +1); { struct list_t * xs = malloc(sizeof(struct list_t )); if (xs == NULL) abort (); xs ->val = v; xs ->next = tl; return xs; //@ close list_len(xs , len +1); } ໋୊ xs ̸= NULL malloc_block(xs) xs->val | → v xs->next | → tl list_len(tl,len) ໋୊ xs ̸= NULL list_len(xs,len+1) close 2016/11/19 VeriFast Introduction 28 / 77
  40. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর ૉͷ length

    ࣮૷ ࣍ʹ௕͞ΛٻΊΔؔ਺ length_list_t Λ࣮૷ͯ͠ΈΑ͏ɻ raw length int length_list_t (struct list_t * lst) //@ requires list_len(lst , ?len) &*& len <= INT_MAX; //@ ensures list_len(lst , len) &*& result == len; { if (lst == NULL) { return 0; // Cannot prove condition result == len } else { // No matching heap chunks: list_t_next(list , _) int n = length_list_t(lst ->next ); return 1 + n; } } ͜Ε΋ૉͷ࣮૷Ͱ͸Ξϊςʔγϣϯ͕଍Γͳ͍ɻ 2016/11/19 VeriFast Introduction 29 / 77
  41. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর ૉͷ length

    ࣮૷ ࣍ʹ௕͞ΛٻΊΔؔ਺ length_list_t Λ࣮૷ͯ͠ΈΑ͏ɻ raw length VeriFast ʹ͸໭Γ஋ͱ len ͱͷؔ܎͕෼͔Βͳ͍ɻ { if (lst == NULL) { return 0; // Cannot prove condition result == len } else { // No matching heap chunks: list_t_next(list , _) int n = length_list_t(lst ->next ); return 1 + n; } } ͜Ε΋ૉͷ࣮૷Ͱ͸Ξϊςʔγϣϯ͕଍Γͳ͍ɻ 2016/11/19 VeriFast Introduction 29 / 77
  42. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর ૉͷ length

    ࣮૷ ࣍ʹ௕͞ΛٻΊΔؔ਺ length_list_t Λ࣮૷ͯ͠ΈΑ͏ɻ raw length ඌ෦ (lst->next) ʹ͍ͭͯ list_len ͕੒Γཱͭࣄ΋෼͔Βͳ͍ɻ { if (lst == NULL) { return 0; // Cannot prove condition result == len } else { // No matching heap chunks: list_t_next(list , _) int n = length_list_t(lst ->next ); return 1 + n; } } ͜Ε΋ૉͷ࣮૷Ͱ͸Ξϊςʔγϣϯ͕଍Γͳ͍ɻ 2016/11/19 VeriFast Introduction 29 / 77
  43. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর ஫ऍ෇͖ length

    ࣮૷ open/close open/close ໋ྩΛࢦఆ͢ΔͱݕূͰ͖Δɻ annotated length int length_list_t (struct list_t * lst) //@ requires list_len(lst , ?len) &*& len <= INT_MAX; //@ ensures list_len(lst , len) &*& result == len; { //@ open list_len(lst , len); if (lst == NULL) { return 0; //@ close list_len(lst , len); } else { int n = length_list_t(lst ->next ); return 1 + n; //@ close list_len(lst , len); } } 2016/11/19 VeriFast Introduction 30 / 77
  44. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর open ͷৼ෣͍

    open ໋ྩͰ list_len ͷఆ͕ٛ VeriFast ͷจ຺Ͱల։͞ΕΔ 13ɻ Proof. int length_list_t (struct list_t * lst) //@ requires list_len(lst , ?len) &*& len <= INT_MAX; //@ ensures list_len(lst , len) &*& result == len; { //@ open list_len(lst , len); if (lst == NULL) { return 0; //@ close list_len(lst , len); predicate list_len (list_t * lst , int len) = lst == NULL ? len == 0 : lst ->next |-> ?next &*& list_len(next , len -1)... list_lenΛల։ 13list_len ͕੒Γཱͭ͜ͱ͸෼͔Βͳ͘ͳΔ 2016/11/19 VeriFast Introduction 31 / 77
  45. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর ߏจͱ໋୊͔Βͷಋग़ then

    અ͕࣮ߦ͞ΕΔ৔߹Λݕূ Proof. int length_list_t (struct list_t * lst) //@ requires list_len(lst , ?len) &*& len <= INT_MAX; //@ ensures list_len(lst , len) &*& result == len; { //@ open list_len(lst , len); if (lst == NULL) { return 0; //@ close list_len(lst , len); } else { predicate list_len (list_t * lst , int len) = lst == NULL ? len == 0 : lst ->next |-> ?next &*& list_len(next , len -1)... ಋग़ lst==NULL ͔Β result==len ͕ಋग़Ͱ͖Δɻ 2016/11/19 VeriFast Introduction 32 / 77
  46. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর ߏจͱ໋୊͔Βͷಋग़ then

    અ͕࣮ߦ͞ΕΔ৔߹Λݕূ Proof. int length_list_t (struct list_t * lst) //@ requires list_len(lst , ?len) &*& len <= INT_MAX; //@ ensures list_len(lst , len) &*& result == len; { //@ open list_len(lst , len); if (lst == NULL) { return 0; //@ close list_len(lst , len); } else { predicate list_len (list_t * lst , int len) = lst == NULL ? len == 0 : lst ->next |-> ?next &*& list_len(next , len -1)... ৞ΈࠐΉ open Ͱల։͞ΕͨఆٛΛ close Ͱ list_len ʹ৞ΈࠐΉɻ 2016/11/19 VeriFast Introduction 32 / 77
  47. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর ߏจͱ໋୊͔Βͷಋग़ else

    અ͕࣮ߦ͞ΕΔ৔߹Λݕূ Proof. int length_list_t (struct list_t * lst) //@ requires list_len(lst , ?len) &*& len <= INT_MAX; //@ ensures list_len(lst , len) &*& result == len; { //@ open list_len(lst , len); } else { int n = length_list_t(lst ->next ); return 1 + n; //@ close list_len(lst , len); predicate list_len (list_t * lst , int len) = lst == NULL ? len == 0 : lst ->next |-> ?next &*& list_len(next , len -1) ... lst != NULL lst̸=NULL ͔Β n==length(next) ͕ಋग़Ͱ͖Δɻ 2016/11/19 VeriFast Introduction 33 / 77
  48. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর ߏจͱ໋୊͔Βͷಋग़ else

    અ͕࣮ߦ͞ΕΔ৔߹Λݕূ Proof. int length_list_t (struct list_t * lst) //@ requires list_len(lst , ?len) &*& len <= INT_MAX; //@ ensures list_len(lst , len) &*& result == len; { //@ open list_len(lst , len); } else { int n = length_list_t(lst ->next ); return 1 + n; //@ close list_len(lst , len); predicate list_len (list_t * lst , int len) = lst == NULL ? len == 0 : lst ->next |-> ?next &*& list_len(next , len -1) ... ࠶ؼݺͼग़͢͠Δ length_list_t ͷࣄલ৚݅Λຬ͍ͨͯ͠Δɻ 2016/11/19 VeriFast Introduction 33 / 77
  49. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর ߏจͱ໋୊͔Βͷಋग़ else

    અ͕࣮ߦ͞ΕΔ৔߹Λݕূ Proof. int length_list_t (struct list_t * lst) //@ requires list_len(lst , ?len) &*& len <= INT_MAX; //@ ensures list_len(lst , len) &*& result == len; { //@ open list_len(lst , len); } else { int n = length_list_t(lst ->next ); return 1 + n; //@ close list_len(lst , len); predicate list_len (list_t * lst , int len) = lst == NULL ? len == 0 : lst ->next |-> ?next &*& list_len(next , len -1) ... result == n == len-1 length_list_t ͷࣄޙ৚͔݅Β n==len-1 ͱͳΔɻ 2016/11/19 VeriFast Introduction 33 / 77
  50. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর ߏจͱ໋୊͔Βͷಋग़ else

    અ͕࣮ߦ͞ΕΔ৔߹Λݕূ Proof. int length_list_t (struct list_t * lst) //@ requires list_len(lst , ?len) &*& len <= INT_MAX; //@ ensures list_len(lst , len) &*& result == len; { //@ open list_len(lst , len); } else { int n = length_list_t(lst ->next ); return 1 + n; //@ close list_len(lst , len); predicate list_len (list_t * lst , int len) = lst == NULL ? len == 0 : lst ->next |-> ?next &*& list_len(next , len -1) ... 1+n == 1+len-1 1 খ͍͞௕͞ʹ 1 ଍ͨ͠ͷͰ result ͸ len ͱ౳͘͠ͳΔ͜ͱ͕෼͔Δɻ 2016/11/19 VeriFast Introduction 33 / 77
  51. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর ஫ऍ෇͖ length

    ࣮૷ (࠶) annotated length int length_list_t (struct list_t * lst) //@ requires list_len(lst , ?len) &*& len <= INT_MAX; //@ ensures list_len(lst , len) &*& result == len; { //@ open list_len(lst , len); if (lst == NULL) { return 0; //@ close list_len(lst , len); } else { int n = length_list_t(lst ->next ); return 1 + n; //@ close list_len(lst , len); } } 2016/11/19 VeriFast Introduction 34 / 77
  52. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর TPPMark2016 ͱ͜ΖͰ

    TPPMark ͸ϦετͷϦετʹ͍ͭͯͷૢ࡞Λཁٻ͍ͯ͠ΔͷͰ . . . ໰୊ 2.1(ґଘܕϓϩάϥϛϯάతͳදݱ) ͷҰ෦ Ҿ਺ͱͯ͠ҎԼͷ̏ͭ ϦετͷϦετ lst ੔਺ i ੔਺ j Λड͚औͬͨΒɺ. . . ϦετͷϦετʹ͍ͭͯ੒Γ໋ཱͭ୊Λهड़͢Δඞཁ͕͋Δɻ 2016/11/19 VeriFast Introduction 35 / 77
  53. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর int ͷϦετͷϦετ

    ͜Ε·Ͱ int ͷϦετΛఆٛͨ͠ͷͰɺTPPMark ຊདྷͷ໨తͰ͋ΔϦετ ͷϦετΛఆٛ͠Α͏ɻ int ͷϦετͷϦετͷఆٛ struct list_list_t { struct list_t * list; struct list_list_t * next; }; ͜Ε΋આ໌͸ཁΒͳ͍ΑͶɻ 2016/11/19 VeriFast Introduction 36 / 77
  54. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর ϦετͷϦετͷෆม৚݅ list_list_t*ʹ͍ͭͯͷෆม৚݅͸

    list_t*ͷ࣌ͱ΄ͱΜͲมΘΒͳ͍ܗͰ ॻ͚Δɻ list_list_t*ͷ௕͞ʹ͍ͭͯͷ໋୊ predicate list_list_len (struct list_list_t * lst , int len) = lst == NULL ? len == 0 : malloc_block_list_list_t (lst) &*& lst ->list | → ?list &*& lst ->next | → ?next &*& list_len(list , _) &*& list_list_len(next , len -1); 2016/11/19 VeriFast Introduction 37 / 77
  55. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর TPPMark ͷܗࣜԽʹ޲͚ͯ

    TPPMark ͷ໰୊จΛ࠶ܝɻ ໰୊ 2.1(ґଘܕϓϩάϥϛϯάతͳදݱ) Ҿ਺ͱͯ͠ҎԼͷ̏ͭ ϦετͷϦετ lst ੔਺ i ੔਺ j Λड͚औͬͨΒɺ lst ͷ i ൪໨ͷϦετͷ j ൪໨ͷཁૉΛ ࡟আͨ͠΋ͷΛฦ ؔ͢਺ remove-lst Λ࡞੒ͤΑɻͦͷࡍɺҎԼͷ̏ͭͷ৚݅ lst ͷ i ൪໨ͷϦετ͕ଘࡏ͢Δɻ i ൪໨ͷϦετͷ j ൪໨ͷཁૉ͕ଘࡏ͢Δɻ ฦ͞ΕΔϦετͨͪͷ௕͞͸ɺi ൪໨ͷΈ 1 ୹͘ͳ͓ͬͯΓɺଞ͸มΘ Βͳ͍ɻ ͕อূ͞ΕΔΑ͏ʹͤΑɻ ʢ͜͜Ͱɺઌ಄͸͍ͣΕ΋ 0 ൪໨ͱ͢Δɻ ʣ 2016/11/19 VeriFast Introduction 38 / 77
  56. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর TPPMark ͷܗࣜԽ

    Ϧετ (ͷϦετ) ʹؔ͢Δ໋୊͕ߏ੒Ͱ͖ΔΑ͏ʹͳͬͨͷͰɺTPPMark ͷ࢓༷ͷܗࣜԽΛ࢝ΊΔɻ remove-lst ͷܗࣜԽͷࢼΈ struct list_list_t * remove_lst(struct list_list_t* lst ,int i,int j); /*@ requires list_list_len(lst , ?len) &*& 0 ≤ i &*& i < len &*& 0 ≤ j; @*/ /*@ ensures list_list_len(lst , len) &*& list_list_len(result , len); @*/ Ϧετͷ಺༰ʹ͍ͭͯݴٴͰ͖ͳ͍ͷͰෆे෼ͳ໋୊ʹͳ͍ͬͯΔɻ 2016/11/19 VeriFast Introduction 39 / 77
  57. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর list_list_len ʹ଍Γͳ͍΋ͷ

    list_list_len ͸Ϧετͷ௕͞ʹ͍ͭͯड़΂͍ͯΔ͕ɺTPPMark ͷཁٻΛ ຬͨͨ͢Ίʹ͸ɺ໋୊தͰϦετͷ಺༰ʹ͍ͭͯड़΂Δඞཁ͕͋Δɻ͜ͷ ͨΊ list_t*΍ list_list_t*ͷ௕͚ͩ͞Ͱͳ͘ɺอ͍࣋ͯ͠Δ஋ (Ϧετ) Λ໋୊தͰදݱ͢Δඞཁ͕͋Δɻ remove-lst ͷܗࣜԽͷࢼΈ struct list_list_t * remove_lst(struct list_list_t* lst ,int i,int j); /*@ requires list_list_len(lst , ?len) &*& 0 ≤ i &*& i < len &*& 0 ≤ j; @*/ /*@ ensures list_list_len(lst , len) &*& list_list_len(result , len); @*/ 2016/11/19 VeriFast Introduction 40 / 77
  58. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর ࢓༷ੈքͷϦετ ·ͣ࢓༷ͷੈքͰ࢖͑ΔϦετܕΛఆٛ͢Δɻ͜Εʹ͸

    inductive Ωʔ ϫʔυΛ࢖͏ 14ɻ Ϧετܕఆٛ inductive list <t> = nil | cons(t, list <t>); <t>͸ܕม਺Λද͠ɺlist ܕ͕ଟ૬Ͱ͋Δ͜ͱΛࣔ͢ɻ 14࣮ࡍʹ͸ඪ४ϥΠϒϥϦ (list.gh) Ͱఏڙ͞ΕΔͷͰࣗ෼Ͱఆٛ͢Δඞཁ͸ͳ͍ 2016/11/19 VeriFast Introduction 41 / 77
  59. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর ࢓༷ੈքͷม਺ ࢓༷தͰ΋ม਺͕࢖͑ΔͷͰɺ͜ΕΛ࢖ͬͯϦετͷڍಈΛ֬ೝ͓ͯ͘͠ɻ

    Ϧετͷಈ࡞Λ֬ೝ void list_sample (void) //@ requires emp; //@ ensures emp; { //@ list <int > xs = cons(3, cons(5, nil )); //@ list <int > ys = cons(1, xs); //@ assert xs == {3 ,5}; //@ assert ys == {1 ,3 ,5}; } Ϧετͷ஋͸ಛผʹ{v_0,v_1,v_2,...}ͱ͍͏ϦςϥϧͰߏ੒Ͱ͖Δɻ 2016/11/19 VeriFast Introduction 42 / 77
  60. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর ࢓༷ੈքͷؔ਺ VeriFast

    Ͱ͸ఆٛͨ͠ܕͷσʔλʹ͍ͭͯͷੑ࣭ʹ͍ͭͯड़΂ΔͨΊ࢓༷ ੈքͰؔ਺͕ఆٛͰ͖Δɻ͜Εʹ͸ fixpoint ΩʔϫʔυΛ࢖͏ɻ Ϧετͷ௕͞ΛٻΊΔ fixpoint int length <t>(list <t> xs) { switch (xs) { case nil: return 0; case cons(x, xs0): return 1 + length(xs0); } } inductive ͱಉ͘͡<t>͸ܕม਺Λࣔ͢ɻͭ·Γ্ͷίʔυ͸೚ҙͷܕͷϦ ετͷ௕͞ΛٻΊΔଟ૬ؔ਺ͱͳ͍ͬͯΔ 15ɻ 15ඪ४Ͱ bin/list.gh ͔Βఏڙ͞ΕΔ 2016/11/19 VeriFast Introduction 43 / 77
  61. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর ͦͷଞͷ fixpoint

    ͜ΕҎ߱Ͱࢀর͢Δؔ਺Λ͍͔͓ͭࣔͯ͘͘͠ 16ɻ ͦͷଞͷϦετ্ͷؔ਺ fixpoint t nth <t>(int n, list <t> xs) { switch (xs) { case nil: return default_value <t>; case cons(x, xs0): return n == 0 ? x : nth(n - 1, xs0); }} a adefault_value<int> = 0 16͍ͣΕ΋ bin/list.gh ʹ͋Δ 2016/11/19 VeriFast Introduction 44 / 77
  62. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর ͦͷଞͷ fixpoint

    ͜ΕҎ߱Ͱࢀর͢Δؔ਺Λ͍͔͓ͭࣔͯ͘͘͠ 16ɻ ͦͷଞͷϦετ্ͷؔ਺ fixpoint list <t> update <t>(int i, t y, list <t> xs) { switch (xs) { case nil: return nil; case cons(x, xs0): return i == 0 ? cons(y, xs0) : cons(x, update(i - 1, y, xs0 )); }} fixpoint list <t> remove_nth <t>(int n, list <t> xs) { switch(xs) { case nil: return nil; case cons(h, t): return n == 0 ? t : cons(h, remove_nth(n - 1, t)); }} 16͍ͣΕ΋ bin/list.gh ʹ͋Δ 2016/11/19 VeriFast Introduction 44 / 77
  63. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর fixpoint ͷ੍ݶ

    fixpoint ʹΑΔؔ਺ͷఆٛʹ͸ɺ೚ҙͷؔ਺͕هड़Ͱ͖ΔΘ͚Ͱ͸ͳ͘ز ੍͔ͭ໿͕൐͏ 17ɻ fixpoint ͷ੍ݶ શؔ਺Ͱ͋Δ͜ͱ ༗ΓಘΔશͯͷೖྗʹ͍ͭͯ݁Ռ͕ఆٛ͞Ε͍ͯΔ͜ͱ a ୯ಠͷ return ·ͨ͸ switch จͰ͋Δ͜ͱ switch ʹ౉ͤΔͷ͸ inductive σʔλͷΈ ࠶ؼ͢Δ৔߹͸ύλʔϯϚονͰऔΓग़ͨ͠σʔλʹ͍ͭͯࣗ਎Λݺ ΜͰ͍Δ͜ͱ b a෦෼ؔ਺ʹ͍ͭͯ͸ޙड़͢Δ predicate Ͱఆٛ͢Δ͜ͱ͕Ͱ͖Δ b͜ΕΛຬ͍ͨͯ͠Ε͹໌Β͔ʹఀࢭ͢Δ Ҏ্ͷΑ͏ͳ੍ݶΛकΔ͜ͱͰɺ஋ʹґͬͯ͸ະఆٛ͋Δ͍͸ݕ͕ࠪࢭ· Βͳ͘ͳΔΑ͏ͳ (͓͔͠ͳ) ࢓༷Λආ͚Δ͜ͱ͕Ͱ͖Δɻ 17ͦΕͧΕ VeriFast ͕ݕࠪ͢Δ 2016/11/19 VeriFast Introduction 45 / 77
  64. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর ଞͷ inductive

    σʔλ option ଞͷ inductive ܕͷྫͱͯ͠ option ܕΛ͓ࣔͯ͘͠ 18ɻ option ܕఆٛ inductive option <t> = none | some(t); option<t>͸ʮ஋Λ࣋ͨͳ͍ʯ஋Λܕ t ʹ௥Ճ͢Δɻ݁ՌΛ࣋ͨͳ͍৔߹ʹ none Λ࢖͏͜ͱͰ (fixpoint ʹΑΔ) શؔ਺Λఆٛ͢ΔͨΊʹॏๅ͢Δɻ 18prelude_core.gh Ͱఆٛ͞ΕΔ 2016/11/19 VeriFast Introduction 46 / 77
  65. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর ࣮ߦੈքͷϦετ͕ࣔ͢Ϟϊ ͜͜·ͰͰ࣮ߦੈք

    (C ݴޠ) ͷϦετ࣮૷ͱ໋୊ੈքͰͷϦετΛఆٛ͠ ͖ͯͨɻ͋ͱ͸͜ΕΒΛؔ࿈෇͚ͯɺstruct list_t*ܕͷ஋͕อ͍࣋ͯ͠ Δ஋͕ϦετͰ͋Δ͜ͱΛ໋୊ͱͯ͠දͤ͹Α͍ɻ 2016/11/19 VeriFast Introduction 47 / 77
  66. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর C ݴޠੈքͱ໋୊ੈքͷ઀ଓ

    list_t*͕Ϧετ list<int>Λอ͍࣋ͯ͠Δ͜ͱΛ໋ࣔ͢୊ list_p Λఆٛ ͢Δɻ list_t*ͱ list<int>ʹ੒Γ໋ཱͭ୊ predicate list_p (struct list_t * lst; list <int > xs) = lst == NULL ? xs == nil : malloc_block_list_t (lst) &*& lst ->val | → ?v &*& lst ->next | → ?next &*& list_p(next , ?xs0) &*& xs == cons(v, xs0); list_len ͱಉ༷ʹ࠶ؼతʹఆ͍ٛͯ͠Δ 19ɻ 19Ҿ਺ؒͷ; ͸ఆ͍ٛͯ͠Δؔ܎͕ؔ਺Ͱ͋Δ͜ͱΛࣔ͢ 2016/11/19 VeriFast Introduction 48 / 77
  67. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর Ϧετͷجຊૢ࡞ͷ࢓༷ ໋୊

    list_p Λ࢖ͬͯϦετ্ͷؔ਺ͷ࢓༷Λमਖ਼͢Δɻ ctor struct list_t * cons_v (int v, struct list_t * tl); //@ requires list_p(tl , ?tl0); //@ ensures list_p(result , cons(v, tl0 )); length int length_list_t (struct list_t * lst); /*@ requires list_p(lst , ?lst0) &*& length(lst0) ≤ INT_MAX; @*/ /*@ ensures list_p(lst , lst0) &*& result == length(lst0 ); @*/ cons_v ͷ࢓༷͸ίϯςϯπΛ௥੻Ͱ͖ΔΑ͏ʹͳΓɺৄࡉʹͳͬͨɻ 2016/11/19 VeriFast Introduction 49 / 77
  68. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর cons_v ͷ࣮૷

    (2) ࢓༷ΛৄࡉԽͨ͠ cons_v Λ࣮૷ͯ͠ΈΑ͏ɻ ctor struct list_t * cons_v (int v, struct list_t * tl) //@ requires list_p(tl , ?ts); //@ ensures list_p(result , cons(v,ts)); { struct list_t * xs = malloc(sizeof(struct list_t )); if (xs == NULL) abort (); xs ->val = v; xs ->next = tl; return xs; //@ close list_p(xs , cons(v,ts)); } list_len ͷ࣌ͱ΄ͱΜͲมΘΒͣɺclose ʹΑͬͯ list_p ͕੒Γཱͭ͜ͱ Λ໌ࣔ͢Δ͚ͩͰ͋Δɻ 2016/11/19 VeriFast Introduction 50 / 77
  69. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর length ͷ࣮૷

    (2) length_list_t ͷ࣮૷΋֬ೝ͓ͯ͘͠ɻ length int length_list_t (struct list_t * lst) //@ requires list_p(lst , ?xs) &*& length(xs) <= INT_MAX; //@ ensures list_p(lst , xs) &*& result == length(xs); { //@ open list_p(lst , xs); if (lst == NULL) { return 0; //@ close list_p(lst , xs); } else { int n = length_list_t(lst ->next ); return 1 + n; //@ close list_p(lst , xs); } } ͜ͷ৔߹΋ list_len ͷ࣌ͱಉ͘͡ɺೖྗϦετͷߏ଄ʹ͍ͭͯ࠶ؼ͢Δͷ Ͱ open ίϚϯυΛ໌ࣔ͢Δ͜ͱͰݕূͰ͖Δɻ 2016/11/19 VeriFast Introduction 51 / 77
  70. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর Ϧετͷجຊૢ࡞ͷ࢓༷ ͦͷଞඞཁʹͳΔϦετૢ࡞Λ࣮૷͢Δ

    (͜͜Ͱ͸γάωνϟͷΈࣔ͢)ɻ ౳஋ൺֱ bool eq_list_t (struct list_t * xs , struct list_t * ys); //@ requires list_p(xs , ?xs0) &*& list_p(ys , ?ys0); /*@ ensures list_p(xs , xs0) &*& list_p(ys , ys0) &*& result == (xs0 == ys0); @*/ σΟʔϓίϐʔ struct list_t * dup_list_t (struct list_t * lst); //@ requires list_p(lst , ?lst0 ); //@ ensures list_p(lst , lst0) &*& list_p(result , lst0 ); ͍ͣΕ΋φΠʔϒʹ࣮૷ͯ͠ open ͱ close Λద੾ʹૠೖ͢Δ͜ͱͰݕূͰ ͖Δɻdup_list_t ͕σΟʔϓίϐʔͩͱ͍͏͜ͱ͕࢓༷ʹݱΕ͍ͯΔ͜ͱ ͕ಡΈऔΕΔͱྑ͍ 20ɻ 20list_p ʹ͸ malloc_block ؚ͕·ΕΔ͜ͱʹ஫ҙ 2016/11/19 VeriFast Introduction 52 / 77
  71. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর remove ͷ࢓༷

    Ϧετͷૢ࡞͕ѻ͑ΔΑ͏ʹͳͬͨͷͰɺ͜͜Ͱ TPPMark ͰඞཁʹͳΔૢ ࡞ͷҰͭͰ͋Δ (remove) Λ࣮૷͠Α͏ɻ·ͣ࢓༷Λࣔ͢ɻ ؔ਺ remove ͷ࢓༷ struct list_t * remove (struct list_t * lst , int i); /*@ requires list_p(lst , ?lst0) &*& 0 ≤ i &*& i < length(lst0 ); @*/ /*@ ensures list_p(lst , lst0) &*& list_p(result , ?lst1) &*& remove_nth(i, lst0) == lst1; @*/ ࢓༷͔Βɺؔ਺ remove ͸ i ൪໨ͷཁૉΛ࡟আͨ͠ϦετΛ৽ͨʹߏங͢Δ ؔ਺ͱͳ͍ͬͯΔ͜ͱ͕Θ͔Δ 21ɻ 21remove_nth ͸ඪ४ϥΠϒϥϦ͔Βఏڙ͞ΕΔ n ൪໨ͷཁૉΛ࡟আ͢Δؔ਺ 2016/11/19 VeriFast Introduction 53 / 77
  72. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর remove ͷ࣮૷ͱݕূ

    ଓ͍ͯɺ࢓༷Λࣔͨؔ͠਺ remove ͷ࣮૷Λݕূ͢Δɻ ؔ਺ remove ͷఆٛ struct list_t * remove (struct list_t * lst , int i) /*@ requires list_p(lst , ?lst0) &*& 0 <= i &*& i < length(lst0 ); @*/ /*@ ensures list_p(lst , lst0) &*& list_p(result , ?lst1) &*& remove_nth(i, lst0) == lst1; @*/ { //@ open list_p(lst , lst0 ); if (i == 0) { return dup_list_t(lst ->next ); } else { struct list_t * rst_ = remove(lst ->next , i - 1); struct list_t * lst_ = cons_v(lst ->val , rst_ ); return lst_; } //@ close list_p(lst , lst0 ); } 2016/11/19 VeriFast Introduction 54 / 77
  73. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর int ͷϦετͷϦετ

    int ͷϦετͷ಺༰Λ௥੻Ͱ͖ΔΑ͏ʹͳͬͨͷͰɺϦετͷϦετͷ໋୊ ΋಺༰͕௥੻Ͱ͖ΔΑ͏ʹ͓ͯ͘͠ɻ int ͷϦετͷϦετͷఆٛ (࠶) struct list_list_t { struct list_t * list; struct list_list_t * next; }; 2016/11/19 VeriFast Introduction 55 / 77
  74. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর ϦετͷϦετͷෆม৚݅ (վ)

    list_list_t*ͱ list<list<int> >ʹ੒Γ໋ཱͭ୊ predicate list_list_p(struct list_list_t * lst; list <list <int > > xxs) = lst == NULL ? xxs == nil : malloc_block_list_list_t (lst) &*& lst ->list | → ?list &*& lst ->next | → ?next &*& list_p(list , ?list0) &*& list_list_p(next , ?xxs0) &*& xxs == cons(list0 , xxs0 ); list_t*ܕͷ࣌ͱಉ༷ʹमਖ਼͢Ε͹Α͍ɻ 2016/11/19 VeriFast Introduction 56 / 77
  75. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর ϦετͷϦετͷجຊૢ࡞ ϦετͷϦετʹ͍ͭͯ΋ඞཁͳجຊૢ࡞Λఆٛ͢Δ

    (͜͜Ͱ͸γάωνϟ ͷΈࣔ͢)ɻ cons struct list_list_t * cons_list (struct list_t * lst , struct list_list_t * llst ); /*@ requires list_p(lst , ?lst0) &*& list_list_p(llst , ?llst0 ); @*/ //@ ensures list_list_p(result , cons(lst0 , llst0 )); ͦͷଞͷؔ਺΋ࣗ໌ͳ࢓༷ͳͷͰলུɻ 2016/11/19 VeriFast Introduction 57 / 77
  76. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর TPPMark2016 TPPMark

    ͷཁٻΛܗࣜԽ͢ΔͨΊ໰୊จΛ࠶ܝɻ ໰୊ 2.1(ґଘܕϓϩάϥϛϯάతͳදݱ) Ҿ਺ͱͯ͠ҎԼͷ̏ͭ ϦετͷϦετ lst ੔਺ i ੔਺ j Λड͚औͬͨΒɺ lst ͷ i ൪໨ͷϦετͷ j ൪໨ͷཁૉΛ ࡟আͨ͠΋ͷΛฦ ؔ͢਺ remove-lst Λ࡞੒ͤΑɻͦͷࡍɺҎԼͷ̏ͭͷ৚݅ lst ͷ i ൪໨ͷϦετ͕ଘࡏ͢Δɻ i ൪໨ͷϦετͷ j ൪໨ͷཁૉ͕ଘࡏ͢Δɻ ฦ͞ΕΔϦετͨͪͷ௕͞͸ɺi ൪໨ͷΈ 1 ୹͘ͳ͓ͬͯΓɺଞ͸มΘ Βͳ͍ɻ ͕อূ͞ΕΔΑ͏ʹͤΑɻ ʢ͜͜Ͱɺઌ಄͸͍ͣΕ΋ 0 ൪໨ͱ͢Δɻ ʣ 2016/11/19 VeriFast Introduction 58 / 77
  77. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর TPPMark ͷܗࣜԽ

    (࠶ͼ) ͜͜·ͰͰ෼͔ͬͨൣғΛ౿·͑ͯ࠶ͼ TPPMark ͷཁٻ͢Δ remove_lst ͷ࢓༷ΛܗࣜԽͯ͠ΈΑ͏ɻ remove-lst ͷܗࣜԽͷࢼΈ (2) struct list_list_t * remove_lst(struct list_list_t* lst ,int i,int j); /*@ requires list_list_p(lst , ?lst0 )}@ &*& 0 ≤ i &*& i < length(lst0) &*& 0 ≤ j &*& j < length(nth(i,lst0 )); @*/ /*@ ensures list_list_p(lst , lst0) &*& list_list_p(result , ?lst1 ); @*/ ΄ͱΜͲશͯͷ෦෼͕ܗࣜԽͰ͖ͨ 22ɻ͋ͱ͸ lst1 ͕ͲͷΑ͏ͳ৚݅Λຬ ͨ͢΂͖͔Λهड़͢Δ͚ͩͰ͋Δɻ 22ͱࢥ͏ 2016/11/19 VeriFast Introduction 59 / 77
  78. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর remove_lst_p ࢒Γͷ࢓༷ͷܗࣜԽʹඞཁͳͷ͸ɺؔ਺ͷ໭Γ஋͕ೖྗϦετʹର͢Δ

    (࢓ ༷௨Γͷ) ૢ࡞ͷ݁ՌͱҰக͢Δ͜ͱΛද໌͢Δ͜ͱͰ͋Δɻ͜ͷͨΊʹҎ ԼͷΑ͏ͳؔ਺ remove_lst_p Λఆٛ͢Δɻ remove_lst_p fixpoint option <list <list <t> > > remove_lst_p <t>(list <list <t> > lst , int i, int j) { return (i < 0 || length(lst) <= i) ? none : (j < 0 || length(nth(i, lst)) <= j) ? none : some( update(i, remove_nth(j, nth(i, lst)), lst )); } 2016/11/19 VeriFast Introduction 60 / 77
  79. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর ओఆཧ Α͏΍͘

    TPPMark ͷཁٻશͯΛද໋͢୊ΛܗࣜԽ͢Δ͜ͱ͕ग़དྷΔɻ remove_lst ͷ࢓༷ struct list_list_t * remove_lst (struct list_list_t * lst , int i, int j) /*@ requires list_list_p(lst , ?lst0) &*& 0 ≤ i &*& i < length(lst0) &*& 0 ≤ j &*& j < length(nth(i,lst0 )); @*/ /*@ ensures list_list_p(lst , lst0) &*& list_list_p(result , ?lst1) &*& remove_lst_p(lst0 , i, j) == some(lst1 ); @*/ 2016/11/19 VeriFast Introduction 61 / 77
  80. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর ͜Ε·Ͱఆ͖ٛͯͨؔ͠਺Λ૊Έ߹Θ࣮ͤͯ૷Ͱ͖Δɻ remove_lst

    ͷ࣮૷ struct list_list_t * remove_lst (struct list_list_t * lst , int i, int j) /*@ requires list_list_p(lst , ?lst0) &*& 0 <= i &*& i < length(lst0) &*& 0 <= j &*& j < length(nth(i,lst0 )); @*/ /*@ ensures list_list_p(lst , lst0) &*& list_list_p(result , ?lst1) &*& remove_lst_p(lst0 , i, j) == some(lst1 ); @*/ { //@ open list_list_p(lst , lst0 ); if (i == 0) { list_t * rst = remove(lst ->list , j); list_list_t * next = dup_list_list_t (lst ->next ); return cons_list(rst , next ); } else { list_list_t * rest = remove_lst(lst ->next , i-1, j); return cons_list(dup_list_t(lst ->list), rest ); } } 2016/11/19 VeriFast Introduction 62 / 77
  81. ໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর ओఆཧ ࠷ޙʹ΋͏Ұ౓ݕࠪͨ͠࢓༷Λࣔͯ͠ऴΘΖ͏ɻ

    remove_lst ͷ࢓༷ struct list_list_t * remove_lst (struct list_list_t * lst , int i, int j) /*@ requires list_list_p(lst , ?lst0) &*& 0 ≤ i &*& i < length(lst0) &*& 0 ≤ j &*& j < length(nth(i,lst0 )); @*/ /*@ ensures list_list_p(lst , lst0) &*& list_list_p(result , ?lst1) &*& remove_lst_p(lst0 , i, j) == some(lst1 ); @*/ 2016/11/19 VeriFast Introduction 63 / 77
  82. ࢀߟࢿྉ VeriFast official web site https://people.cs.kuleuven.be/~bart.jacobs/verifast/ VeriFast Tutorial(೔ຊޠ൛) https://github.com/jverifast-ug/translate/ 12th

    Theorem Proving and Provers (TPP2016) http://pllab.is.ocha.ac.jp/~asai/tpp2016/ J. C. Reynolds. Separation Logic: A Logic for Shared Mutable Data Structures* Proceedings of the Seventeenth Annual IEEE Symposium on Logic in Computer Science, held July 22-25, 2002 in Copenhagen, Denmark. http://www.cs.cmu.edu/~jcr/seplogic.pdf
  83. Appendix remove ͷ࣮૷ ຊจதͰ͸࣮૷Λ͍ࣔͯ͠ͳ͍ͷͰ͜͜Ͱ͓ࣔͯ͘͠ɻ ؔ਺ remove ͷγάωνϟ (࠶ܝ) // i-th

    ཁૉΛ࡟আͨ͠ϦετΛߏங struct list_t * remove (struct list_t * lst , int i); /*@ requires list_p(lst , ?lst0) &*& 0 ≤ i &*& i < length(lst0 ); @*/ /*@ ensures list_p(lst , lst0) &*& list_p(result , ?lst1) &*& remove_nth(i, lst0) == lst1; @*/ 2016/11/19 VeriFast Introduction 65 / 77
  84. Appendix remove ͷ࣮૷ open ͱ close Λద੾ʹࢦఆ͢Δ͚ͩɻ remove ͷ஫ऍ෇͖࣮૷ struct

    list_t * remove (struct list_t * lst , int i) /*@ requires list_p(lst , ?lst0) &*& 0 <= i &*& i < length(lst0 ); @*/ /*@ ensures list_p(lst , lst0) &*& list_p(result , ?lst1) &*& remove_nth(i, lst0) == lst1; @*/ { //@ open list_p(lst , lst0 ); if (i == 0) { return dup_list_t(lst ->next ); } else { struct list_t * rst_ = remove(lst ->next , i - 1); struct list_t * lst_ = cons_v(lst ->val , rst_ ); return lst_; } //@ close list_p(lst , lst0 ); } 2016/11/19 VeriFast Introduction 66 / 77
  85. Appendix ิ୊ ͋Δ໋୊͕੒Γཱ͍ͬͯΔͱ͖ʹɺ͔ͦ͜Β (ࣗ໌Ͱͳ͍) ໋୊Λಋग़ͨ͠ ͍৔߹ɺ͜ΕΛ lemma ΩʔϫʔυͰఆٛ͢Δ͜ͱ͕Ͱ͖Δɻ lemma ఆٛͷҰൠܗ

    lemma t mylemma <t,...> (args ...) requires ..; ensures ..; { open ... close ... } C ݴޠͷؔ਺ͱಉ͡Α͏ʹࣄલ/ࣄޙ৚͕݅ݕࠪ͞ΕΔ 23ɻlemma Λهड़͢ Δͱࣄޙ৚͕݅ VeriFast ͷ؅ཧ͢Δ໋୊ू߹ʹ௥Ճ͞ΕɺҎ߱ͷݕূͰར ༻͞ΕΔɻ 23ୠ͠ lemma ͸ඞͣఀࢭ͢Δඞཁ͕͋ΔͷͰϧʔϓʹ͍ͭͯ͸ invariant ͷଞʹݮগ͢ ΔύϥϝʔλΛ໌ࣔ͢Δඞཁ͕͋Δ 2016/11/19 VeriFast Introduction 67 / 77
  86. Appendix ิ୊:remove_nth_minus1len remove ͕ཁૉΛ 1 ݮΒ͢͜ͱΛิ୊ͱͯ͠ఆٛ͢Δɻ Lemma. remove_nth_minus1len lemma list

    <t> remove_nth_minus1len <t>(int i, list <t> xs); requires 0 ≤ i &*& i < length(xs); ensures length(xs) == 1 + length(result) &*& result == remove_nth(i, xs); 2016/11/19 VeriFast Introduction 68 / 77
  87. Appendix ิ୊ͷূ໌ remove_lst ͷ࣮૷ lemma list <t> remove_nth_minus1len <t>(int i,

    list <t> xs) requires 0 <= i &*& i < length(xs); ensures length(xs) == 1 + length(result) &*& result == remove_nth(i, xs); { switch (xs) { case nil: assert false; case cons(x,xs0): if (i == 0) { return xs0; } else { list <t> rs = remove_nth_minus1len (i-1, xs0); return cons(x,rs); } } } 2016/11/19 VeriFast Introduction 69 / 77
  88. Appendix ৚݅ 3 ͷݕূ ͦ͏͍͑͹... remove_lst ͷࣄޙ৚݅Ͱ͸ɺ໰୊ͷཁٻ͢Δ (໰୊ 2.1) ৚݅

    3 ฦ͞ΕΔϦετͨͪͷ௕͞͸ɺi ൪໨ͷΈ 1 ୹͘ͳ͓ͬͯΓɺଞ͸มΘΒ ͳ͍ɻ ͕ຬͨ͞ΕΔ͜ͱΛ௚઀ड़΂ͯ͸͍ͳ͍ɻ 2016/11/19 VeriFast Introduction 70 / 77
  89. Appendix ৚݅ 3 ͷݕূ ͦ͏͍͑͹... remove_lst ͷࣄޙ৚݅Ͱ͸ɺ໰୊ͷཁٻ͢Δ (໰୊ 2.1) ৚݅

    3 ฦ͞ΕΔϦετͨͪͷ௕͞͸ɺi ൪໨ͷΈ 1 ୹͘ͳ͓ͬͯΓɺଞ͸มΘΒ ͳ͍ɻ ͕ຬͨ͞ΕΔ͜ͱΛ௚઀ड़΂ͯ͸͍ͳ͍ɻ =⇒ ผʹݕূ͢Δ 2016/11/19 VeriFast Introduction 70 / 77
  90. Appendix ৚݅ 3 Λಋग़͢Δิ୊ ৚݅ 3 ͸ remove_lst ͷࣄޙ৚͔݅Βಋग़Ͱ͖ΔͷͰɺ͜ΕΛิ୊Ͱද͢ɻ Lemma

    remove_lst_inv lemma void remove_lst_inv <t>(list <list <t> > lst , int i, int j) requires remove_lst_p(lst , i, j) == some (?rst); ensures // 0..i ·Ͱͷ௕͞͸มΘΒͳ͍ map(length , take(i,lst)) == map(length , take(i,rst)) &*& length(nth(i,lst)) == 1 + length(nth(i,rst)) &*& // i+1..n ·Ͱͷ௕͞͸มΘΒͳ͍ map(length , drop(i+1,lst)) == map(length , drop(i+1,rst )); 2016/11/19 VeriFast Introduction 71 / 77
  91. Appendix ৚݅ 3 Λಋग़͢Δิ୊ remove_lst_inv ͷূ໌ switch (lst) { case

    nil: assert false; // ͜ͷέʔεʹ͸ͳΒͳ͍ case cons(x,lst0 ): if (0 == i) { assert 0 <= j && j < length(nth(0,lst )); remove_nth_minus1len (j, nth(0,lst )); } else if (0 < i) { remove_lst_inv (lst0 , i-1, j); // ࠶ؼ } } remove_lst_p ͸ fixpoint ͳͷͰ open ͢Δඞཁ͸ͳ͍ (Ͱ͖ͳ͍) 2016/11/19 VeriFast Introduction 72 / 77
  92. Appendix ΋͏Ұͭͷ໰୊ 2.2 ໰୊ʢ࿦ཧతͳදݱʣ ҎԼͷ̏ͭͷσʔλ͕͋Δɻ ϦετͷϦετ lst ੔਺ i ੔਺

    j ͜ͷͱ͖ɺlst ͷ i ൪໨ͷϦετͷ j ൪໨ͷ ཁૉΛऔΕΔͳΒ͹ɺҎԼΛຬ ͨ͢Ϧετ͕ʢ།Ұʣଘࡏ͢Δ͜ͱΛࣔͤɻlst ͷதͷ i ൪໨ͷϦετʹ͍ͭͯ͸ɺͦͷ j ൪໨ͷ ཁૉΛऔΓআ͖ɺ ͦΕҎ֎ͷϦετʹ͍ͭͯ͸ɺ΋ͱͷ·· Ͱ͋ΔΑ͏ͳϦετͰɺฦͬͯ͘ΔϦετͨͪͷ௕͞͸ɺ i ൪໨ͷϦετʹ͍ͭͯ͸ɺ΋ͱͷϦετΑΓ 1 ୹͘ͳ͓ͬͯΓɺ ͦΕҎ֎ʹ͍ͭͯ͸ɺ΋ͱͷϦετͱಉ͡ ʹͳ͍ͬͯΔɻ ʢ͜͜Ͱɺઌ಄͸͍ͣΕ΋ 0 ൪໨ͱ͢Δɻ ʣ 2016/11/19 VeriFast Introduction 74 / 77
  93. Appendix predicate/lemma predicate ͱͯ͠ఆٛͨ͠৔߹͸;(semicolon) Λ࢖ͬͯؔ਺Ͱ͋Δ͜ͱΛ ͔ࣔ͢ɺͦΕ͕Ͱ͖ͳ͍৔߹͸ 25lemma Ͱࣔ͢͜ͱ͕ग़དྷΔɻ predicate(;) Λ࢖͏

    predicate unique_p <T,U> (T t; U u) = switch (t) { case t0: u == ... ิ୊Λ࢖͏ lemma void p_is_unique (T t); requires P(t, ?u1) &*& P(t, ?u2); ensures P(t, u1) &*& P(t, u2) &*& u1 == u2; 25͜ͷνΣοΫ͸ҙ֎ͱ௨͢ͷ͕໘౗ͩͬͨΓ͢Δ 2016/11/19 VeriFast Introduction 76 / 77
  94. Appendix VeriFast ͦͷଞͷೳྗ ຊࢿྉதͰࣔͨ͠Ҏ֎ʹ VeriFast Ͱग़དྷΔ͜ͱΛࣔ͢ 26ɻ fractional permission(෼ׂॴ༗ݖ) εϨουؒͰσʔλΛڞ༗͢Δ৔߹ɺॴ༗ݖ͸

    1/n ʹͳΔ Մม௕Ҿ਺ ઐ༻ͷϦετ (vararg) ͱͯ͠ݴٴͰ͖Δ ؔ਺ͷఀࢭੑอূ Bart Jacobs,2015 ࣄલ/ࣄޙ৚݅ͷଞʹఀࢭ͢Δ͜ͱΛࣔ͢஫ऍ (terminates) ͕͋Δ ؔ਺ϙΠϯλͷݕূ ಛఆͷछྨͷؔ਺Ͱ͋Δ͜ͱΛ໌ࣔ͢Δ ߴ֊ Lemma ૬ޓ࠶ؼͨ͠ Lemma ͷݕূʹ࢖͏ શশྔԽ͞Ε໋ͨ୊ 27 forall_(૊ΈࠐΈߏจ) Λ࢖͏ is_forall_t(ඪ४ϥΠϒϥϦຐज़) Λ࢖͏ 26͜ΕͰશͯͰ͸ͳ͍ɻbin/ͱ examples/ΛړΔ΂͠ 27࣮͸ࣄલ৚݅Ͱಋೖ͞Εͨม਺͸શশྔԽ͞Ε͍ͯΔͱݟ၏ͤΔ 2016/11/19 VeriFast Introduction 77 / 77