From b26291885e4ffe24bfe49bc728f12cf5690373a0 Mon Sep 17 00:00:00 2001 From: Virgile Prevosto <virgile.prevosto@m4x.org> Date: Thu, 25 Aug 2022 15:56:54 +0200 Subject: [PATCH] [aorai] fix handling of unlimited sequences --- src/plugins/aorai/data_for_aorai.ml | 9 +- .../tests/ya/oracle/seq_unlimited.res.oracle | 168 +++++++++++++++--- .../ya/oracle_prove/seq_unlimited.res.oracle | 5 - 3 files changed, 153 insertions(+), 29 deletions(-) diff --git a/src/plugins/aorai/data_for_aorai.ml b/src/plugins/aorai/data_for_aorai.ml index 5fa579e6e7a..2615a5a92b6 100644 --- a/src/plugins/aorai/data_for_aorai.ml +++ b/src/plugins/aorai/data_for_aorai.ml @@ -1177,11 +1177,14 @@ let rec type_seq default_state tr metaenv env needs_pebble curr_start curr_end s let trans = Path_analysis.get_transitions_of_state st auto in if st.nums = inner_start.nums then begin let loop_trans = - if needs_counter then begin + if has_loop then begin List.fold_left (fun acc tr -> - let init_action = Counter_init (make_counter tr.stop) in - let init_actions = init_action :: tr.actions in + let init_actions = + if needs_counter then + Counter_init (make_counter tr.stop) :: tr.actions + else tr.actions + in let init_trans = new_trans st tr.stop tr.cross init_actions in diff --git a/src/plugins/aorai/tests/ya/oracle/seq_unlimited.res.oracle b/src/plugins/aorai/tests/ya/oracle/seq_unlimited.res.oracle index 0c4ab2b08ea..34b512d7005 100644 --- a/src/plugins/aorai/tests/ya/oracle/seq_unlimited.res.oracle +++ b/src/plugins/aorai/tests/ya/oracle/seq_unlimited.res.oracle @@ -1,17 +1,15 @@ [kernel] Parsing seq_unlimited.i (no preprocessing) -[aorai] seq_unlimited.i:21: Warning: - Call to find does not follow automaton's specification. This path is assumed to be dead -[aorai] Warning: Call to main does not follow automaton's specification. This path is assumed to be dead -[aorai] seq_unlimited.i:23: Warning: - Call to main not conforming to automaton (pre-cond). Assuming it is on a dead path [kernel] Parsing TMPDIR/aorai_seq_unlimited_0.i (no preprocessing) /* Generated by Frama-C */ enum aorai_States { aorai_intermediate_state = 0, - aorai_reject = 1, - b = 2, - c = 3, - fst = 4 + aorai_intermediate_state_0 = 1, + aorai_intermediate_state_1 = 2, + aorai_reject = 3, + b = 4, + c = 5, + fst = 6, + ok = 7 }; enum aorai_ListOper { op_find = 2, @@ -22,6 +20,8 @@ enum aorai_OpStatusList { aorai_Terminated = 1, aorai_Called = 0 }; +/*@ check lemma ok_deterministic_trans{L}: \true; + */ /*@ check lemma fst_deterministic_trans{L}: \true; */ /*@ check lemma c_deterministic_trans{L}: \true; @@ -34,6 +34,20 @@ enum aorai_OpStatusList { */ /*@ ghost enum aorai_ListOper aorai_CurOperation; */ /*@ ghost enum aorai_OpStatusList aorai_CurOpStatus; */ +/*@ +check lemma aorai_intermediate_state_1_deterministic_trans{L}: + ¬(\at(aorai_CurOperation,L) ≡ op_find ∧ + \at(aorai_CurOpStatus,L) ≡ aorai_Terminated ∧ + ¬(\at(aorai_CurOperation,L) ≡ op_find ∧ + \at(aorai_CurOpStatus,L) ≡ aorai_Terminated)); + */ +/*@ +check lemma aorai_intermediate_state_0_deterministic_trans{L}: + ¬(\at(aorai_CurOperation,L) ≡ op_find ∧ + \at(aorai_CurOpStatus,L) ≡ aorai_Called ∧ + \at(aorai_CurOperation,L) ≡ op_main ∧ + \at(aorai_CurOpStatus,L) ≡ aorai_Terminated); + */ /*@ ghost int aorai_CurStates = fst; */ /*@ ghost /@ requires aorai_CurStates ≡ b; @@ -49,6 +63,12 @@ enum aorai_OpStatusList { assumes aorai_CurStates ≢ b; ensures aorai_CurStates ≢ aorai_intermediate_state; + behavior buch_state_aorai_intermediate_state_0_out: + ensures aorai_CurStates ≢ aorai_intermediate_state_0; + + behavior buch_state_aorai_intermediate_state_1_out: + ensures aorai_CurStates ≢ aorai_intermediate_state_1; + behavior buch_state_aorai_reject_out: ensures aorai_CurStates ≢ aorai_reject; @@ -60,13 +80,16 @@ enum aorai_OpStatusList { behavior buch_state_fst_out: ensures aorai_CurStates ≢ fst; + + behavior buch_state_ok_out: + ensures aorai_CurStates ≢ ok; @/ void init_pre_func(int *a, int n) { /@ slevel full; @/ aorai_CurOpStatus = aorai_Called; aorai_CurOperation = op_init; - if (2 == aorai_CurStates) aorai_CurStates = aorai_intermediate_state; + if (4 == aorai_CurStates) aorai_CurStates = aorai_intermediate_state; else aorai_CurStates = aorai_reject; return; } @@ -82,6 +105,12 @@ enum aorai_OpStatusList { behavior buch_state_aorai_intermediate_state_out: ensures aorai_CurStates ≢ aorai_intermediate_state; + behavior buch_state_aorai_intermediate_state_0_out: + ensures aorai_CurStates ≢ aorai_intermediate_state_0; + + behavior buch_state_aorai_intermediate_state_1_out: + ensures aorai_CurStates ≢ aorai_intermediate_state_1; + behavior buch_state_aorai_reject_out: ensures aorai_CurStates ≢ aorai_reject; @@ -98,6 +127,9 @@ enum aorai_OpStatusList { behavior buch_state_fst_out: ensures aorai_CurStates ≢ fst; + + behavior buch_state_ok_out: + ensures aorai_CurStates ≢ ok; @/ void init_post_func(void) { @@ -124,10 +156,13 @@ void init(int *a, int n) /*@ ghost aorai_Loop_Init_2 = 1; */ aorai_loop_2: /*@ loop invariant Aorai: aorai_CurStates ≡ aorai_intermediate_state; + loop invariant Aorai: aorai_CurStates ≢ aorai_intermediate_state_0; + loop invariant Aorai: aorai_CurStates ≢ aorai_intermediate_state_1; loop invariant Aorai: aorai_CurStates ≢ aorai_reject; loop invariant Aorai: aorai_CurStates ≢ b; loop invariant Aorai: aorai_CurStates ≢ c; loop invariant Aorai: aorai_CurStates ≢ fst; + loop invariant Aorai: aorai_CurStates ≢ ok; */ while (i < n) { /*@ ghost aorai_Loop_Init_2 = 0; */ @@ -139,7 +174,9 @@ void init(int *a, int n) } /*@ ghost - /@ requires \false; + /@ requires + aorai_CurStates ≡ aorai_intermediate_state_0 ∨ + aorai_CurStates ≡ c; ensures aorai_CurOpStatus ≡ aorai_Called; ensures aorai_CurOperation ≡ op_find; assigns aorai_CurOpStatus, aorai_CurOperation, aorai_CurStates; @@ -147,6 +184,21 @@ void init(int *a, int n) behavior buch_state_aorai_intermediate_state_out: ensures aorai_CurStates ≢ aorai_intermediate_state; + behavior buch_state_aorai_intermediate_state_0_out: + ensures aorai_CurStates ≢ aorai_intermediate_state_0; + + behavior buch_state_aorai_intermediate_state_1_in: + assumes + aorai_CurStates ≡ c ∨ + aorai_CurStates ≡ aorai_intermediate_state_0; + ensures aorai_CurStates ≡ aorai_intermediate_state_1; + + behavior buch_state_aorai_intermediate_state_1_out: + assumes + aorai_CurStates ≢ c ∧ + aorai_CurStates ≢ aorai_intermediate_state_0; + ensures aorai_CurStates ≢ aorai_intermediate_state_1; + behavior buch_state_aorai_reject_out: ensures aorai_CurStates ≢ aorai_reject; @@ -158,20 +210,26 @@ void init(int *a, int n) behavior buch_state_fst_out: ensures aorai_CurStates ≢ fst; + + behavior buch_state_ok_out: + ensures aorai_CurStates ≢ ok; @/ void find_pre_func(int *a, int n, int k) { /@ slevel full; @/ aorai_CurOpStatus = aorai_Called; aorai_CurOperation = op_find; - aorai_CurStates = aorai_reject; + if (5 == aorai_CurStates) aorai_CurStates = aorai_intermediate_state_1; + else + if (1 == aorai_CurStates) aorai_CurStates = aorai_intermediate_state_1; + else aorai_CurStates = aorai_reject; return; } */ /*@ ghost - /@ requires \false; + /@ requires aorai_CurStates ≡ aorai_intermediate_state_1; ensures aorai_CurOpStatus ≡ aorai_Terminated; ensures aorai_CurOperation ≡ op_find; assigns aorai_CurOpStatus, aorai_CurOperation, aorai_CurStates; @@ -179,6 +237,17 @@ void init(int *a, int n) behavior buch_state_aorai_intermediate_state_out: ensures aorai_CurStates ≢ aorai_intermediate_state; + behavior buch_state_aorai_intermediate_state_0_in: + assumes aorai_CurStates ≡ aorai_intermediate_state_1; + ensures aorai_CurStates ≡ aorai_intermediate_state_0; + + behavior buch_state_aorai_intermediate_state_0_out: + assumes aorai_CurStates ≢ aorai_intermediate_state_1; + ensures aorai_CurStates ≢ aorai_intermediate_state_0; + + behavior buch_state_aorai_intermediate_state_1_out: + ensures aorai_CurStates ≢ aorai_intermediate_state_1; + behavior buch_state_aorai_reject_out: ensures aorai_CurStates ≢ aorai_reject; @@ -190,19 +259,33 @@ void init(int *a, int n) behavior buch_state_fst_out: ensures aorai_CurStates ≢ fst; + + behavior buch_state_ok_out: + ensures aorai_CurStates ≢ ok; @/ void find_post_func(int res) { /@ slevel full; @/ aorai_CurOpStatus = aorai_Terminated; aorai_CurOperation = op_find; - aorai_CurStates = aorai_reject; + if (2 == aorai_CurStates) aorai_CurStates = aorai_intermediate_state_0; + else aorai_CurStates = aorai_reject; return; } */ -/*@ requires \false; */ +/*@ requires + aorai_CurStates ≡ aorai_intermediate_state_0 ∨ + aorai_CurStates ≡ c; + requires aorai_CurStates ≡ c ∨ aorai_CurStates ≢ c; + requires + aorai_CurStates ≡ aorai_intermediate_state_0 ∨ + aorai_CurStates ≢ aorai_intermediate_state_0; + + behavior Buchi_property_behavior: + ensures aorai_CurStates ≡ aorai_intermediate_state_0; + */ int find(int *a, int n, int k) { int __retres; @@ -213,10 +296,19 @@ int find(int *a, int n, int k) /*@ ghost aorai_Loop_Init_12 = 1; */ aorai_loop_12: /*@ loop invariant Aorai: aorai_CurStates ≢ aorai_intermediate_state; + loop invariant Aorai: aorai_CurStates ≢ aorai_intermediate_state_0; + loop invariant Aorai: aorai_CurStates ≡ aorai_intermediate_state_1; loop invariant Aorai: aorai_CurStates ≢ aorai_reject; loop invariant Aorai: aorai_CurStates ≢ b; loop invariant Aorai: aorai_CurStates ≢ c; loop invariant Aorai: aorai_CurStates ≢ fst; + loop invariant Aorai: aorai_CurStates ≢ ok; + loop invariant + Aorai: + aorai_Loop_Init_12 ≢ 0 ⇒ + \at(aorai_CurStates ≢ aorai_intermediate_state_0,Pre) ∧ + \at(aorai_CurStates ≢ c,Pre) ⇒ + aorai_CurStates ≢ aorai_intermediate_state_1; */ while (i < n) { /*@ ghost aorai_Loop_Init_12 = 0; */ @@ -235,7 +327,7 @@ int find(int *a, int n, int k) } /*@ ghost - /@ requires \false; + /@ requires aorai_CurStates ≡ fst; ensures aorai_CurOpStatus ≡ aorai_Called; ensures aorai_CurOperation ≡ op_main; assigns aorai_CurOpStatus, aorai_CurOperation, aorai_CurStates; @@ -243,10 +335,21 @@ int find(int *a, int n, int k) behavior buch_state_aorai_intermediate_state_out: ensures aorai_CurStates ≢ aorai_intermediate_state; + behavior buch_state_aorai_intermediate_state_0_out: + ensures aorai_CurStates ≢ aorai_intermediate_state_0; + + behavior buch_state_aorai_intermediate_state_1_out: + ensures aorai_CurStates ≢ aorai_intermediate_state_1; + behavior buch_state_aorai_reject_out: ensures aorai_CurStates ≢ aorai_reject; + behavior buch_state_b_in: + assumes aorai_CurStates ≡ fst; + ensures aorai_CurStates ≡ b; + behavior buch_state_b_out: + assumes aorai_CurStates ≢ fst; ensures aorai_CurStates ≢ b; behavior buch_state_c_out: @@ -254,20 +357,24 @@ int find(int *a, int n, int k) behavior buch_state_fst_out: ensures aorai_CurStates ≢ fst; + + behavior buch_state_ok_out: + ensures aorai_CurStates ≢ ok; @/ void main_pre_func(void) { /@ slevel full; @/ aorai_CurOpStatus = aorai_Called; aorai_CurOperation = op_main; - aorai_CurStates = aorai_reject; + if (6 == aorai_CurStates) aorai_CurStates = b; + else aorai_CurStates = aorai_reject; return; } */ /*@ ghost - /@ requires \false; + /@ requires aorai_CurStates ≡ aorai_intermediate_state_0; ensures aorai_CurOpStatus ≡ aorai_Terminated; ensures aorai_CurOperation ≡ op_main; assigns aorai_CurOpStatus, aorai_CurOperation, aorai_CurStates; @@ -275,6 +382,12 @@ int find(int *a, int n, int k) behavior buch_state_aorai_intermediate_state_out: ensures aorai_CurStates ≢ aorai_intermediate_state; + behavior buch_state_aorai_intermediate_state_0_out: + ensures aorai_CurStates ≢ aorai_intermediate_state_0; + + behavior buch_state_aorai_intermediate_state_1_out: + ensures aorai_CurStates ≢ aorai_intermediate_state_1; + behavior buch_state_aorai_reject_out: ensures aorai_CurStates ≢ aorai_reject; @@ -286,22 +399,35 @@ int find(int *a, int n, int k) behavior buch_state_fst_out: ensures aorai_CurStates ≢ fst; + + behavior buch_state_ok_in: + assumes aorai_CurStates ≡ aorai_intermediate_state_0; + ensures aorai_CurStates ≡ ok; + + behavior buch_state_ok_out: + assumes aorai_CurStates ≢ aorai_intermediate_state_0; + ensures aorai_CurStates ≢ ok; @/ void main_post_func(int res) { /@ slevel full; @/ aorai_CurOpStatus = aorai_Terminated; aorai_CurOperation = op_main; - aorai_CurStates = aorai_reject; + if (1 == aorai_CurStates) aorai_CurStates = ok; + else aorai_CurStates = aorai_reject; return; } */ -/*@ requires \false; +/*@ requires aorai_CurStates ≡ fst; behavior aorai_acceptance: - ensures \false; */ + ensures aorai_CurStates ≡ ok; + + behavior Buchi_property_behavior: + ensures aorai_CurStates ≡ ok; + */ int main(void) { int __retres; diff --git a/src/plugins/aorai/tests/ya/oracle_prove/seq_unlimited.res.oracle b/src/plugins/aorai/tests/ya/oracle_prove/seq_unlimited.res.oracle index 719a33db757..3bd12d5c212 100644 --- a/src/plugins/aorai/tests/ya/oracle_prove/seq_unlimited.res.oracle +++ b/src/plugins/aorai/tests/ya/oracle_prove/seq_unlimited.res.oracle @@ -1,8 +1,3 @@ [kernel] Parsing seq_unlimited.i (no preprocessing) -[aorai] seq_unlimited.i:21: Warning: - Call to find does not follow automaton's specification. This path is assumed to be dead -[aorai] Warning: Call to main does not follow automaton's specification. This path is assumed to be dead -[aorai] seq_unlimited.i:23: Warning: - Call to main not conforming to automaton (pre-cond). Assuming it is on a dead path [kernel] Parsing TMPDIR/aorai_seq_unlimited_0_prove.i (no preprocessing) [wp] Warning: Missing RTE guards -- GitLab