Slide 1

Slide 1 text

໨࣍ 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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

໨࣍ 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

Slide 8

Slide 8 text

໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর TPPMark ͷܗࣜԽΛ࢝ΊΔલʹ. . . VeriFast ͷ “࠷΋جຊతͳػೳ” Λղઆ͢Δɻ 2016/11/19 VeriFast Introduction 8 / 77

Slide 9

Slide 9 text

໨࣍ 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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

໨࣍ 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

Slide 12

Slide 12 text

໨࣍ 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

Slide 13

Slide 13 text

໨࣍ 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

Slide 14

Slide 14 text

໨࣍ 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

Slide 15

Slide 15 text

໨࣍ 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

Slide 16

Slide 16 text

໨࣍ 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

Slide 17

Slide 17 text

໨࣍ 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

Slide 18

Slide 18 text

໨࣍ 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

Slide 19

Slide 19 text

໨࣍ 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

Slide 20

Slide 20 text

໨࣍ 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

Slide 21

Slide 21 text

໨࣍ 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

Slide 22

Slide 22 text

໨࣍ 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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

໨࣍ 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

Slide 33

Slide 33 text

໨࣍ 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

Slide 34

Slide 34 text

໨࣍ 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

Slide 35

Slide 35 text

໨࣍ 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

Slide 36

Slide 36 text

໨࣍ 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

Slide 37

Slide 37 text

໨࣍ 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

Slide 38

Slide 38 text

໨࣍ 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

Slide 39

Slide 39 text

໨࣍ 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

Slide 40

Slide 40 text

໨࣍ 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

Slide 41

Slide 41 text

໨࣍ 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

Slide 42

Slide 42 text

໨࣍ 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

Slide 43

Slide 43 text

໨࣍ 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

Slide 44

Slide 44 text

໨࣍ 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

Slide 45

Slide 45 text

໨࣍ 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

Slide 46

Slide 46 text

໨࣍ 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

Slide 47

Slide 47 text

໨࣍ 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

Slide 48

Slide 48 text

໨࣍ 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

Slide 49

Slide 49 text

໨࣍ 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

Slide 50

Slide 50 text

໨࣍ 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

Slide 51

Slide 51 text

໨࣍ 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

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

໨࣍ 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

Slide 54

Slide 54 text

໨࣍ 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

Slide 55

Slide 55 text

໨࣍ 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

Slide 56

Slide 56 text

໨࣍ 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

Slide 57

Slide 57 text

໨࣍ 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

Slide 58

Slide 58 text

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

Slide 59

Slide 59 text

໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর ࢓༷ੈքͷม਺ ࢓༷தͰ΋ม਺͕࢖͑ΔͷͰɺ͜ΕΛ࢖ͬͯϦετͷڍಈΛ֬ೝ͓ͯ͘͠ɻ Ϧετͷಈ࡞Λ֬ೝ void list_sample (void) //@ requires emp; //@ ensures emp; { //@ list xs = cons(3, cons(5, nil )); //@ list 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

Slide 60

Slide 60 text

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

Slide 61

Slide 61 text

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

Slide 62

Slide 62 text

໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর ͦͷଞͷ fixpoint ͜ΕҎ߱Ͱࢀর͢Δؔ਺Λ͍͔͓ͭࣔͯ͘͘͠ 16ɻ ͦͷଞͷϦετ্ͷؔ਺ fixpoint list update (int i, t y, list 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 remove_nth (int n, list 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

Slide 63

Slide 63 text

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

Slide 64

Slide 64 text

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

Slide 65

Slide 65 text

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

Slide 66

Slide 66 text

໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর C ݴޠੈքͱ໋୊ੈքͷ઀ଓ list_t*͕Ϧετ listΛอ͍࣋ͯ͠Δ͜ͱΛ໋ࣔ͢୊ list_p Λఆٛ ͢Δɻ list_t*ͱ listʹ੒Γ໋ཱͭ୊ predicate list_p (struct list_t * lst; list 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

Slide 67

Slide 67 text

໨࣍ 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

Slide 68

Slide 68 text

໨࣍ 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

Slide 69

Slide 69 text

໨࣍ 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

Slide 70

Slide 70 text

໨࣍ 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

Slide 71

Slide 71 text

໨࣍ 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

Slide 72

Slide 72 text

໨࣍ 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

Slide 73

Slide 73 text

໨࣍ 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

Slide 74

Slide 74 text

໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর ϦετͷϦετͷෆม৚݅ (վ) list_list_t*ͱ list >ʹ੒Γ໋ཱͭ୊ predicate list_list_p(struct list_list_t * lst; list > 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

Slide 75

Slide 75 text

໨࣍ 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

Slide 76

Slide 76 text

໨࣍ 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

Slide 77

Slide 77 text

໨࣍ 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

Slide 78

Slide 78 text

໨࣍ VeriFast ֓આ VeriFast ೖ໳ جຊ෦඼ͷఆٛ ओఆཧͷূ໌ ࢀর remove_lst_p ࢒Γͷ࢓༷ͷܗࣜԽʹඞཁͳͷ͸ɺؔ਺ͷ໭Γ஋͕ೖྗϦετʹର͢Δ (࢓ ༷௨Γͷ) ૢ࡞ͷ݁ՌͱҰக͢Δ͜ͱΛද໌͢Δ͜ͱͰ͋Δɻ͜ͷͨΊʹҎ ԼͷΑ͏ͳؔ਺ remove_lst_p Λఆٛ͢Δɻ remove_lst_p fixpoint option > > remove_lst_p (list > 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

Slide 79

Slide 79 text

໨࣍ 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

Slide 80

Slide 80 text

໨࣍ 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

Slide 81

Slide 81 text

໨࣍ 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

Slide 82

Slide 82 text

ࢀߟࢿྉ 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

Slide 83

Slide 83 text

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

Slide 84

Slide 84 text

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

Slide 85

Slide 85 text

Appendix ิ୊ ͋Δ໋୊͕੒Γཱ͍ͬͯΔͱ͖ʹɺ͔ͦ͜Β (ࣗ໌Ͱͳ͍) ໋୊Λಋग़ͨ͠ ͍৔߹ɺ͜ΕΛ lemma ΩʔϫʔυͰఆٛ͢Δ͜ͱ͕Ͱ͖Δɻ lemma ఆٛͷҰൠܗ lemma t mylemma (args ...) requires ..; ensures ..; { open ... close ... } C ݴޠͷؔ਺ͱಉ͡Α͏ʹࣄલ/ࣄޙ৚͕݅ݕࠪ͞ΕΔ 23ɻlemma Λهड़͢ Δͱࣄޙ৚͕݅ VeriFast ͷ؅ཧ͢Δ໋୊ू߹ʹ௥Ճ͞ΕɺҎ߱ͷݕূͰར ༻͞ΕΔɻ 23ୠ͠ lemma ͸ඞͣఀࢭ͢Δඞཁ͕͋ΔͷͰϧʔϓʹ͍ͭͯ͸ invariant ͷଞʹݮগ͢ ΔύϥϝʔλΛ໌ࣔ͢Δඞཁ͕͋Δ 2016/11/19 VeriFast Introduction 67 / 77

Slide 86

Slide 86 text

Appendix ิ୊:remove_nth_minus1len remove ͕ཁૉΛ 1 ݮΒ͢͜ͱΛิ୊ͱͯ͠ఆٛ͢Δɻ Lemma. remove_nth_minus1len lemma list remove_nth_minus1len (int i, list 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

Slide 87

Slide 87 text

Appendix ิ୊ͷূ໌ remove_lst ͷ࣮૷ lemma list remove_nth_minus1len (int i, list 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 rs = remove_nth_minus1len (i-1, xs0); return cons(x,rs); } } } 2016/11/19 VeriFast Introduction 69 / 77

Slide 88

Slide 88 text

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

Slide 89

Slide 89 text

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

Slide 90

Slide 90 text

Appendix ৚݅ 3 Λಋग़͢Δิ୊ ৚݅ 3 ͸ remove_lst ͷࣄޙ৚͔݅Βಋग़Ͱ͖ΔͷͰɺ͜ΕΛิ୊Ͱද͢ɻ Lemma remove_lst_inv lemma void remove_lst_inv (list > 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

Slide 91

Slide 91 text

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

Slide 92

Slide 92 text

Appendix ΋͏Ұͭͷ໰୊ TPPMark ͷग़୊͸ຊจதͰղ͍ͨҰ໰͕ͩɺ࣍ʹࣔ͢Α͏ʹผͷදݱͰͷ ग़୊จ͕ఏࣔ͞Ε͍ͯΔɻ 2016/11/19 VeriFast Introduction 73 / 77

Slide 93

Slide 93 text

Appendix ΋͏Ұͭͷ໰୊ 2.2 ໰୊ʢ࿦ཧతͳදݱʣ ҎԼͷ̏ͭͷσʔλ͕͋Δɻ ϦετͷϦετ lst ੔਺ i ੔਺ j ͜ͷͱ͖ɺlst ͷ i ൪໨ͷϦετͷ j ൪໨ͷ ཁૉΛऔΕΔͳΒ͹ɺҎԼΛຬ ͨ͢Ϧετ͕ʢ།Ұʣଘࡏ͢Δ͜ͱΛࣔͤɻlst ͷதͷ i ൪໨ͷϦετʹ͍ͭͯ͸ɺͦͷ j ൪໨ͷ ཁૉΛऔΓআ͖ɺ ͦΕҎ֎ͷϦετʹ͍ͭͯ͸ɺ΋ͱͷ·· Ͱ͋ΔΑ͏ͳϦετͰɺฦͬͯ͘ΔϦετͨͪͷ௕͞͸ɺ i ൪໨ͷϦετʹ͍ͭͯ͸ɺ΋ͱͷϦετΑΓ 1 ୹͘ͳ͓ͬͯΓɺ ͦΕҎ֎ʹ͍ͭͯ͸ɺ΋ͱͷϦετͱಉ͡ ʹͳ͍ͬͯΔɻ ʢ͜͜Ͱɺઌ಄͸͍ͣΕ΋ 0 ൪໨ͱ͢Δɻ ʣ 2016/11/19 VeriFast Introduction 74 / 77

Slide 94

Slide 94 text

Appendix fixpoint ʮ࿦ཧతͳදݱʯͷग़୊ʹରͯ͠ճ౴͢Δ৔߹Ͱ΋ɺզʑ͸ fixpoint Λ ࢖ͬͯࢦఆ͞Εͨૢ࡞Λఆٛͨ͠ͷͰ 24ɺ ͦͷ݁ՌಘΒΕΔ஋͕Ұҙʹܾ·Δ͜ͱ͸ࣗ໌Ͱ͋Δ 24fixpoint ͸ؔ਺ 2016/11/19 VeriFast Introduction 75 / 77

Slide 95

Slide 95 text

Appendix predicate/lemma predicate ͱͯ͠ఆٛͨ͠৔߹͸;(semicolon) Λ࢖ͬͯؔ਺Ͱ͋Δ͜ͱΛ ͔ࣔ͢ɺͦΕ͕Ͱ͖ͳ͍৔߹͸ 25lemma Ͱࣔ͢͜ͱ͕ग़དྷΔɻ predicate(;) Λ࢖͏ predicate unique_p (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

Slide 96

Slide 96 text

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