@ -12,11 +12,17 @@ open PulseBasicInterface
module AbductiveDomain = PulseAbductiveDomain
module AbductiveDomain = PulseAbductiveDomain
module LatentIssue = PulseLatentIssue
module LatentIssue = PulseLatentIssue
type t =
(* The type variable is needed to distinguish summaries from plain states.
| AbortProgram of AbductiveDomain . t
| ContinueProgram of AbductiveDomain . t
Some of the variants have summary - typed states instead of plain states , to ensure we have
| ExitProgram of AbductiveDomain . t
normalized them and don't need to normalize them again . * )
| LatentAbortProgram of { astate : AbductiveDomain . t ; latent_issue : LatentIssue . t }
type ' abductive_domain_t base_t =
| ContinueProgram of ' abductive_domain_t
| ExitProgram of ' abductive_domain_t
| AbortProgram of AbductiveDomain . summary
| LatentAbortProgram of { astate : AbductiveDomain . summary ; latent_issue : LatentIssue . t }
type t = AbductiveDomain . t base_t
let continue astate = ContinueProgram astate
let continue astate = ContinueProgram astate
@ -24,13 +30,14 @@ let mk_initial pdesc = ContinueProgram (AbductiveDomain.mk_initial pdesc)
let leq ~ lhs ~ rhs =
let leq ~ lhs ~ rhs =
match ( lhs , rhs ) with
match ( lhs , rhs ) with
| AbortProgram astate1 , AbortProgram astate2
| AbortProgram astate1 , AbortProgram astate2 ->
| ContinueProgram astate1 , ContinueProgram astate2
AbductiveDomain . leq ~ lhs : ( astate1 :> AbductiveDomain . t ) ~ rhs : ( astate2 :> AbductiveDomain . t )
| ExitProgram astate1 , ExitProgram astate2 ->
| ContinueProgram astate1 , ContinueProgram astate2 | ExitProgram astate1 , ExitProgram astate2 ->
AbductiveDomain . leq ~ lhs : astate1 ~ rhs : astate2
AbductiveDomain . leq ~ lhs : ( astate1 :> AbductiveDomain . t ) ~ rhs : ( astate2 :> AbductiveDomain . t )
| ( LatentAbortProgram { astate = astate1 ; latent_issue = issue1 }
| ( LatentAbortProgram { astate = astate1 ; latent_issue = issue1 }
, LatentAbortProgram { astate = astate2 ; latent_issue = issue2 } ) ->
, LatentAbortProgram { astate = astate2 ; latent_issue = issue2 } ) ->
LatentIssue . equal issue1 issue2 && AbductiveDomain . leq ~ lhs : astate1 ~ rhs : astate2
LatentIssue . equal issue1 issue2
&& AbductiveDomain . leq ~ lhs : ( astate1 :> AbductiveDomain . t ) ~ rhs : ( astate2 :> AbductiveDomain . t )
| _ ->
| _ ->
false
false
@ -39,36 +46,40 @@ let pp fmt = function
| ContinueProgram astate ->
| ContinueProgram astate ->
AbductiveDomain . pp fmt astate
AbductiveDomain . pp fmt astate
| ExitProgram astate ->
| ExitProgram astate ->
F . fprintf fmt " {ExitProgram %a} " AbductiveDomain . pp astate
F . fprintf fmt " {ExitProgram %a} " AbductiveDomain . pp ( astate :> AbductiveDomain . t )
| AbortProgram astate ->
| AbortProgram astate ->
F . fprintf fmt " {AbortProgram %a} " AbductiveDomain . pp astate
F . fprintf fmt " {AbortProgram %a} " AbductiveDomain . pp ( astate :> AbductiveDomain . t )
| LatentAbortProgram { astate ; latent_issue } ->
| LatentAbortProgram { astate ; latent_issue } ->
let diagnostic = LatentIssue . to_diagnostic latent_issue in
let diagnostic = LatentIssue . to_diagnostic latent_issue in
let message = Diagnostic . get_message diagnostic in
let message = Diagnostic . get_message diagnostic in
let location = Diagnostic . get_location diagnostic in
let location = Diagnostic . get_location diagnostic in
F . fprintf fmt " {LatentAbortProgram(%a: %s) %a} " Location . pp location message
F . fprintf fmt " {LatentAbortProgram(%a: %s) %a} " Location . pp location message
AbductiveDomain . pp astate
AbductiveDomain . pp
( astate :> AbductiveDomain . t )
let map ~ f exec_state =
let map ~ f exec_state =
match exec_state with
match exec_state with
| AbortProgram astate ->
AbortProgram ( f astate )
| ContinueProgram astate ->
| ContinueProgram astate ->
ContinueProgram ( f astate )
ContinueProgram ( f astate )
| ExitProgram astate ->
| ExitProgram astate ->
ExitProgram ( f astate )
ExitProgram ( f astate )
| AbortProgram astate ->
AbortProgram astate
| LatentAbortProgram { astate ; latent_issue } ->
| LatentAbortProgram { astate ; latent_issue } ->
LatentAbortProgram { astate = f astate ; latent_issue }
LatentAbortProgram { astate ; latent_issue }
type summary = AbductiveDomain . summary base_t
let of_posts pdesc posts =
let summary_ of_posts pdesc posts =
List . filter_mapi posts ~ f : ( fun i exec_state ->
List . filter_mapi posts ~ f : ( fun i exec_state ->
let ( AbortProgram astate
let astate =
| ContinueProgram astate
match exec_state with
| ExitProgram astate
| AbortProgram astate | LatentAbortProgram { astate } ->
| LatentAbortProgram { astate } ) =
( astate :> AbductiveDomain . t )
exec_state
| ContinueProgram astate | ExitProgram astate ->
astate
in
in
L . d_printfln " Creating spec out of state #%d:@ \n %a " i pp exec_state ;
L . d_printfln " Creating spec out of state #%d:@ \n %a " i pp exec_state ;
let astate , is_unsat = PulseArithmetic . is_unsat_expensive astate in
let astate , is_unsat = PulseArithmetic . is_unsat_expensive astate in
@ -77,4 +88,4 @@ let of_posts pdesc posts =
Some
Some
( map exec_state ~ f : ( fun _ astate ->
( map exec_state ~ f : ( fun _ astate ->
(* prefer [astate] since it is an equivalent state that has been normalized *)
(* prefer [astate] since it is an equivalent state that has been normalized *)
AbductiveDomain . of_post pdesc astate ) ) )
AbductiveDomain . summary_ of_post pdesc astate ) ) )