1 /*
2 * This file is part of the Yices SMT Solver.
3 * Copyright (C) 2017 SRI International.
4 *
5 * Yices is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * Yices is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with Yices. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include <stdio.h>
20 #include <stdint.h>
21 #include <stdlib.h>
22 #include <inttypes.h>
23 #include <assert.h>
24
25 #include "io/type_printer.h"
26 #include "terms/types.h"
27 #include "utils/refcount_strings.h"
28
29
30 #ifdef MINGW
random(void)31 static inline long int random(void) {
32 return rand();
33 }
34 #endif
35
36
37 /*
38 * Display a type substitution
39 * - v[0 ... n-1] = type variables
40 * - u[0 ... n-1] = types
41 */
show_type_subst(FILE * f,type_table_t * table,type_t v[],type_t u[],uint32_t n)42 static void show_type_subst(FILE *f, type_table_t *table, type_t v[], type_t u[], uint32_t n) {
43 uint32_t i;
44
45 for (i=0; i<n; i++) {
46 print_type(f, table, v[i]);
47 fputs(" := ", f);
48 print_type(f, table, u[i]);
49 fputc('\n', f);
50 }
51 fflush(f);
52 }
53
54
55 /*
56 * Test substitution
57 */
test_type_subst(type_table_t * table,type_t tau,type_t v[],type_t u[],uint32_t n)58 static void test_type_subst(type_table_t *table, type_t tau, type_t v[], type_t u[], uint32_t n) {
59 type_t sigma;
60
61 printf("--- Test substitution ---\n");
62 show_type_subst(stdout, table, v, u, n);
63 printf("input type: ");
64 print_type(stdout, table, tau);
65 fputc('\n', stdout);
66 sigma = type_substitution(table, tau, n, v, u);
67 printf("result: ");
68 print_type(stdout, table, sigma);
69 fputc('\n', stdout);
70 }
71
72
73 /*
74 * Global variables:
75 * var[NVARS] = all variables
76 * tests[NTESTS]
77 */
78 static type_table_t types;
79
80 #define NVARS 12
81 #define NTESTS 20
82
83 static type_t var[NVARS];
84 static type_t tests[NTESTS];
85
86
87 /*
88 * Initialize the variables
89 */
init_variables(void)90 static void init_variables(void) {
91 char name[2];
92 uint32_t i;
93
94 name[0] = 'A';
95 name[1] = '\0';
96
97 for (i=0; i<NVARS; i++) {
98 var[i] = type_variable(&types, i);
99 set_type_name(&types, var[i], clone_string(name));
100 name[0] ++;
101 }
102 }
103
104
105 /*
106 * Initialize the test types
107 */
init_tests(void)108 static void init_tests(void) {
109 type_t aux[12];
110
111 tests[0] = bool_type(&types);
112 tests[1] = int_type(&types);
113 tests[2] = real_type(&types);
114 tests[3] = bv_type(&types, 10);
115 tests[4] = bv_type(&types, 32);
116 tests[5] = new_scalar_type(&types, 6);
117 set_type_name(&types, tests[5], clone_string("s"));
118 tests[6] = new_scalar_type(&types, 1);
119 set_type_name(&types, tests[6], clone_string("u"));
120 tests[7] = new_uninterpreted_type(&types);
121 set_type_name(&types, tests[7], clone_string("aa"));
122 tests[8] = new_uninterpreted_type(&types);
123 set_type_name(&types, tests[8], clone_string("bb"));
124 tests[9] = var[3];
125 tests[10] = var[4];
126 tests[11] = var[5];
127
128 aux[0] = tests[0];
129 aux[1] = var[0];
130 aux[2] = var[3];
131 tests[12] = tuple_type(&types, 3, aux);
132
133 aux[0] = tests[4];
134 aux[1] = tests[4];
135 aux[2] = var[10];
136 aux[3] = var[10];
137 aux[4] = tests[12];
138 aux[5] = tests[1];
139 aux[6] = tests[2];
140 tests[13] = tuple_type(&types, 6, aux);
141
142 tests[14] = function_type(&types, var[6], 4, aux);
143
144 aux[0] = tests[3];
145 aux[1] = tests[4];
146 aux[2] = tests[5];
147 aux[3] = tests[6];
148 aux[4] = tests[7];
149 aux[5] = tests[8];
150 aux[6] = tests[9];
151 aux[7] = tests[10];
152 aux[8] = tests[11];
153 aux[9] = tests[12];
154 aux[10] = tests[13];
155 tests[15] = tuple_type(&types, 10, aux);
156
157 tests[16] = function_type(&types, tests[10], 10, aux);
158
159 aux[0] = tests[4];
160 aux[1] = tests[0];
161 aux[2] = tests[2];
162 tests[17] = tuple_type(&types, 3, aux);
163
164 aux[0] = tests[17];
165 aux[1] = tests[17];
166 tests[18] = tuple_type(&types, 2, aux);
167
168 aux[0] = tests[18];
169 aux[1] = tests[18];
170 aux[2] = tests[18];
171 tests[19] = function_type(&types, tests[18], 3, aux);
172 }
173
174
175 /*
176 * Check whether x occurs in v[0 ... n-1]
177 */
repeated_var(type_t x,uint32_t n,type_t * v)178 static bool repeated_var(type_t x, uint32_t n, type_t *v) {
179 uint32_t i;
180
181 for (i=0; i<n; i++) {
182 if (v[i] == x) return true;
183 }
184
185 return false;
186 }
187
188 /*
189 * Store n random variables in array v
190 */
random_vars(uint32_t n,type_t * v)191 static void random_vars(uint32_t n, type_t *v) {
192 uint32_t i, j;
193 type_t x;
194
195 for (i=0; i<n; i++) {
196 do {
197 j = random() % NVARS;
198 x = var[j];
199 } while (repeated_var(x, i, v));
200 v[i] = x;
201 }
202 }
203
204
205 /*
206 * Store n random types in array u
207 */
random_types(uint32_t n,type_t * u)208 static void random_types(uint32_t n, type_t *u) {
209 uint32_t i, j;
210
211 for (i=0; i<n; i++) {
212 j = random() % NTESTS;
213 u[i] = tests[j];
214 }
215 }
216
217
218 /*
219 * Apply n random substitutions to type tau
220 */
test_random_subst(type_t tau,uint32_t n)221 static void test_random_subst(type_t tau, uint32_t n) {
222 type_t v[6];
223 type_t u[6];
224
225 while (n > 0) {
226 n --;
227 random_vars(4, v);
228 random_types(4, u);
229 test_type_subst(&types, tau, v, u, 4);
230 }
231 printf("\n\n");
232 }
233
234
main(void)235 int main(void) {
236 uint32_t i;
237
238 init_type_table(&types, 0);
239 init_variables();
240 init_tests();
241
242 for (i=0; i<NTESTS; i++) {
243 test_random_subst(tests[i], 5);
244 }
245
246 delete_type_table(&types);
247
248 return 0;
249 }
250