File: DistinctValues.eo

package info (click to toggle)
cvc5 1.3.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 87,260 kB
  • sloc: cpp: 383,850; java: 12,207; python: 12,090; sh: 5,679; ansic: 4,729; lisp: 763; perl: 208; makefile: 38
file content (184 lines) | stat: -rw-r--r-- 8,422 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
(include "../theories/Builtin.eo")
(include "../theories/Arrays.eo")
(include "../theories/Arith.eo")
(include "../theories/BitVectors.eo")
(include "../theories/Strings.eo")
(include "../theories/Sets.eo")
(include "../theories/Datatypes.eo")

(include "Utils.eo")
(include "Datatypes.eo")

; note: This is a forward declaration of $are_distinct_terms_list below.
(program $are_distinct_terms_list () :signature (@List Type) Bool)

; define: $are_distinct_terms
; args:
; - t T: The first term.
; - s T: The second term.
; return: >
;   True if we can shown that t and s are semantically distinct, e.g. (not (= t s)) holds.
(define $are_distinct_terms ((T Type :implicit) (t T) (s T))
  (eo::ite (eo::eq t s) false ($are_distinct_terms_list (@list t s) (eo::typeof t))))

; program: $some_pairwise_distinct_term
; args:
; - ts T: The first list of terms.
; - ss T: The second list of terms.
; return: >
;   True if there is some term in ts and ss at the same position which can be shown to be semantically distinct.
;   This program expects ts and ss to be of the same length.
(program $some_pairwise_distinct_term ((U Type) (t U) (s U) (ts @List :list) (ss @List :list))
  :signature (@List @List) Bool
  (
  (($some_pairwise_distinct_term (@list t ts) (@list s ss))  (eo::ite ($are_distinct_terms t s)
                                                                true
                                                                ($some_pairwise_distinct_term ts ss)))
  (($some_pairwise_distinct_term @list.nil @list.nil)        false)
  ; unevaluated if different lengths
  )
)

;;;;; Theory of sets

; program: $set_is_not_subset
; args:
; - t (Set T): The first set terms.
; - s (Set T): The second set terms.
; return: >
;   True if we can show that t is not a subset of s based on reasoning about values.
(program $set_is_not_subset ((T Type) (t (Set T)) (ts (Set T) :list) (s (Set T)) (ss (Set T) :list) (e1 T) (e2 T))
  :signature ((Set T) (Set T)) Bool
  (
  (($set_is_not_subset (as set.empty (Set T)) s)                              false)
  (($set_is_not_subset (set.singleton e1) (as set.empty (Set T)))             true)
  (($set_is_not_subset (set.singleton e1) (set.singleton e2))                 ($are_distinct_terms e1 e2))
  (($set_is_not_subset (set.singleton e1) (set.union (set.singleton e2) ss))  (eo::ite ($are_distinct_terms e1 e2)
                                                                                ($set_is_not_subset (set.singleton e1) ss)
                                                                                false))
  (($set_is_not_subset (set.union (set.singleton e1) ts) s)                   (eo::ite ($set_is_not_subset (set.singleton e1) s)
                                                                                true
                                                                                ($set_is_not_subset ts s)))

  )
)

;;;;; Theory of sequences

; define: $seq_distinct_terms
; args:
; - t (Seq T): The first term.
; - s (Seq T): The second term.
; return: >
;   True if we can derive that t and s are distinct based on their length,
;   or by a character prefix that can be shown distinct.
(program $seq_distinct_terms ((T Type) (t (Seq T)) (ts (Seq T) :list) (s (Seq T)) (ss (Seq T) :list) (e1 T) (e2 T))
  :signature ((Seq T) (Seq T)) Bool
  (
  ; handle singleton cases
  (($seq_distinct_terms (seq.unit e1) s)                                     ($seq_distinct_terms (seq.++ (seq.unit e1)) s))
  (($seq_distinct_terms t (seq.unit e2))                                     ($seq_distinct_terms t (seq.++ (seq.unit e2))))
  (($seq_distinct_terms (seq.++ (seq.unit e1) ts) (seq.++ (seq.unit e2) ss)) (eo::ite ($are_distinct_terms e1 e2)
                                                                               true
                                                                               ($seq_distinct_terms ts ss)))
  (($seq_distinct_terms t t)                                                 false)
  (($seq_distinct_terms t s)                                                 true) ; otherwise different length
  )
)

;;;;; Theory of datatypes

; program: $dt_distinct_terms_rec
; args:
; - t T: The first term, expected to be of datatype type.
; - s T: The second term, expected to be of datatype type.
; - l1 @List: The accumulated list of arguments of t.
; - l2 @List: The accumulated list of arguments of s.
; return: >
;   True if we can show that t and s denote distinct terms. This is true
;   if t and s are distinct constructor applications, or are applications
;   of the same constructor and one of their arguments can be shown distinct.
(program $dt_distinct_terms_rec ((T Type) (U Type) (V Type) (W Type) (ct T) (cs V) (f (-> U W)) (a U) (l1 @List) (l2 @List))
  :signature (T V @List @List) Bool
  (
    (($dt_distinct_terms_rec (f a) cs l1 l2) ($dt_distinct_terms_rec f cs (eo::cons @list a l1) l2))
    (($dt_distinct_terms_rec ct (f a) l1 l2) ($dt_distinct_terms_rec ct f l1 (eo::cons @list a l2)))
    (($dt_distinct_terms_rec ct cs l1 l2)
      (eo::ite (eo::eq ($dt_is_cons ct) true)
        (eo::ite (eo::eq ct cs)
          ; recurse on each argument
          ($some_pairwise_distinct_term l1 l2)  ; get the argument list of the datatypes
          ; otherwise conflicting only if cs is also a constructor
          (eo::eq ($dt_is_cons cs) true))
        false))
  )
)

; define: $dt_distinct_terms
; args:
; - t T: The first term, expected to be of datatype type.
; - s T: The second term, expected to be of datatype type.
; return: >
;   True if we can show that t and s denote distinct terms. This is true
;   if t and s are distinct constructor applications, or are applications
;   of the same constructor and one of their arguments can be shown distinct.
(define $dt_distinct_terms ((T Type :implicit) (t T) (s T))
  ($dt_distinct_terms_rec t s @list.nil @list.nil))

;;;;; Definitions

; define: $are_distinct_terms_type
; args:
; - t T: The first term.
; - s T: The second term.
; - T Type: The type of the arguments.
; return: >
;   True if we can shown that t and s are semantically distinct, e.g. (not (= t s)) holds.
(program $are_distinct_terms_type
  ((T Type) (t T) (s T) (U Type) (W Type) (n Int) (st (Set U)) (ss (Set U)) (sst (Seq U)) (sss (Seq U)))
  :signature (T T Type) Bool
  (
  (($are_distinct_terms_type t t T)           false)
  (($are_distinct_terms_type t s Int)         (eo::and (eo::is_z t) (eo::is_z s)))
  (($are_distinct_terms_type t s Real)        (eo::and (eo::is_q t) (eo::is_q s)))
  (($are_distinct_terms_type t s String)      (eo::and (eo::is_str t) (eo::is_str s)))
  (($are_distinct_terms_type t s (BitVec n))  (eo::and (eo::is_bin t) (eo::is_bin s)))
  (($are_distinct_terms_type t s Bool)        (eo::and (eo::is_bool t) (eo::is_bool s)))
  (($are_distinct_terms_type st ss (Set U))   (eo::or ($set_is_not_subset st ss) ($set_is_not_subset ss st)))
  (($are_distinct_terms_type sst sss (Seq U)) ($seq_distinct_terms sst sss))
  (($are_distinct_terms_type t s T)           ($dt_distinct_terms t s)) ; otherwise assume we are a user datatype
  )
)

; define: $are_distinct_terms_list_rec
; args:
; - t T: The term.
; - xs @List: A list of terms, each expected to be of type T.
; - T Type: The type of the arguments.
; return: >
;   True if t can be shown to be disequal from all terms in xs.
(program $are_distinct_terms_list_rec ((T Type) (t T) (s T) (xs @List :list))
  :signature (T @List Type) Bool
  (
  (($are_distinct_terms_list_rec t (@list s xs) T)  (eo::ite ($are_distinct_terms_type t s T)
                                                      ($are_distinct_terms_list_rec t xs T)
                                                      false))
  (($are_distinct_terms_list_rec t @list.nil T)     true)
  )
)

; define: $are_distinct_terms_list_rec
; args:
; - xs @List: A list of terms, each expected to be of type T.
; - T Type: The type of the terms in the list.
; return: >
;   True if each pair of terms in xs can be shown to be pairwise disequal.
(program $are_distinct_terms_list ((T Type) (t T) (xs @List :list))
  :signature (@List Type) Bool
  (
  (($are_distinct_terms_list @list.nil T)     true)
  (($are_distinct_terms_list (@list t xs) T)  (eo::ite ($are_distinct_terms_list_rec t xs T)
                                                ($are_distinct_terms_list xs T)
                                                false))
  )
)