| ;; Part of the Crubit project, under the Apache License v2.0 with LLVM |
| ;; Exceptions. See /LICENSE for license information. |
| ;; SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| |
| ;; Run: cvc5 --lang smt --incremental --fmf-bound optional_code_synthesis.smt2 |
| |
| (set-option :produce-models true) |
| (set-option :produce-assertions true) |
| (set-option :produce-assignments true) |
| (set-option :produce-unsat-cores true) |
| (set-logic HO_ALL) |
| |
| (declare-datatype FlowConditions |
| ((make-flow-conditions |
| (get-fc-1 Bool) |
| (get-fc-2 Bool) |
| (get-fc-3 Bool) |
| (get-fc-4 Bool) |
| (get-fc-5 Bool)))) |
| |
| (define-fun join-fc ((c Bool) (fc-then Bool) (fc-else Bool)) Bool |
| (or |
| (and c fc-then) |
| (and (not c) fc-else))) |
| |
| (declare-datatype OptionalValue |
| ((make-optional-value (get-x0 Bool)))) |
| |
| (declare-fun get-has-value (OptionalValue) Bool) |
| |
| ;; Args: flow-condition, opt. |
| (declare-fun is-unsafe-to-unwrap (Bool OptionalValue) Bool) |
| |
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| ;; Example RegularCheck |
| ;; |
| ;; ``` |
| ;; void foo(optional<int> x) { |
| ;; // (1) |
| ;; x.value(); |
| ;; if (x.has_value()) { |
| ;; // (2) |
| ;; x.value(); |
| ;; } |
| ;; } |
| ;; ``` |
| |
| (define-fun run-RegularCheck |
| ((x OptionalValue) (body (-> FlowConditions Bool))) Bool |
| (let ((fc-1 true)) |
| (let ((fc-2 (and fc-1 (get-has-value x)))) |
| (body (make-flow-conditions fc-1 fc-2 false false false))))) |
| |
| ;; Every program point is reachable. |
| (assert |
| (exists ((x OptionalValue)) |
| (run-RegularCheck x (lambda ((fcs FlowConditions)) (get-fc-1 fcs))))) |
| |
| (assert |
| (exists ((x OptionalValue)) |
| (run-RegularCheck x (lambda ((fcs FlowConditions)) (get-fc-2 fcs))))) |
| |
| ;; Unwrap at (1) is unsafe. |
| (assert |
| (exists ((x OptionalValue)) |
| (run-RegularCheck |
| x |
| (lambda ((fcs FlowConditions)) |
| (is-unsafe-to-unwrap (get-fc-1 fcs) x))))) |
| |
| ;; Unwrap at (2) is safe. |
| (assert |
| (forall ((x OptionalValue)) |
| (run-RegularCheck |
| x |
| (lambda ((fcs FlowConditions)) |
| (not (is-unsafe-to-unwrap (get-fc-2 fcs) x)))))) |
| |
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| ;; Example MixedValues |
| ;; |
| ;; ``` |
| ;; void foo(optional<int> x, bool b) { |
| ;; // (1) |
| ;; if (b) { |
| ;; // (2) |
| ;; x = 42; |
| ;; // (3) |
| ;; } |
| ;; // (4) |
| ;; x.value(); |
| ;; if (b) { |
| ;; // (5) |
| ;; x.value(); |
| ;; } |
| ;; } |
| ;; ``` |
| |
| (define-fun run-MixedValues |
| ((x OptionalValue) (b Bool) (body (-> FlowConditions Bool))) Bool |
| (let ((fc-1 true)) |
| (let ((fc-2 (and fc-1 b))) |
| (let ((fc-3 (and fc-2 (get-has-value x)))) |
| (let ((fc-4 (join-fc b fc-3 fc-1))) |
| (let ((fc-5 (and fc-4 b))) |
| (body (make-flow-conditions fc-1 fc-2 fc-3 fc-4 fc-5)))))))) |
| |
| ;; Every program point is reachable. |
| (assert |
| (exists ((x OptionalValue) (b Bool)) |
| (run-MixedValues x b (lambda ((fcs FlowConditions)) (get-fc-1 fcs))))) |
| |
| (assert |
| (exists ((x OptionalValue) (b Bool)) |
| (run-MixedValues x b (lambda ((fcs FlowConditions)) (get-fc-2 fcs))))) |
| |
| (assert |
| (exists ((x OptionalValue) (b Bool)) |
| (run-MixedValues x b (lambda ((fcs FlowConditions)) (get-fc-3 fcs))))) |
| |
| (assert |
| (exists ((x OptionalValue) (b Bool)) |
| (run-MixedValues x b (lambda ((fcs FlowConditions)) (get-fc-4 fcs))))) |
| |
| (assert |
| (exists ((x OptionalValue) (b Bool)) |
| (run-MixedValues x b (lambda ((fcs FlowConditions)) (get-fc-5 fcs))))) |
| |
| ;; Unwrap at (4) is unsafe. |
| (assert |
| (exists ((x OptionalValue) (b Bool)) |
| (run-MixedValues |
| x b |
| (lambda ((fcs FlowConditions)) |
| (is-unsafe-to-unwrap (get-fc-4 fcs) x))))) |
| |
| ;; Unwrap at (5) is safe. |
| (assert |
| (forall ((x OptionalValue) (b Bool)) |
| (run-MixedValues |
| x b |
| (lambda ((fcs FlowConditions)) |
| (not (is-unsafe-to-unwrap (get-fc-5 fcs) x)))))) |
| |
| (check-sat) |
| (get-value (get-has-value)) |
| (get-value (is-unsafe-to-unwrap)) |
| |
| ; vim: set syntax=scheme: |