blob: 93d7a7d592a021c832ad010e8ab53e42b87e7367 [file] [log] [blame]
;; 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: