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