4 # Morgan Deters <mdeters@cs.nyu.edu> for CVC4
5 # Copyright (c) 2010-2013 The CVC4 Project
7 # The purpose of this script is to create theory_traits.h from a template
8 # and a list of theory kinds.
12 # mktheorytraits template-file theory-kind-files...
14 # Output is to standard out.
19 filename
=`basename "$1" | sed 's,_template,,'`
22 /********************* */
25 ** Copyright $copyright New York University and The University of Iowa,
28 ** This header file automatically generated by:
32 ** for the CVC4 project.
44 theory_for_each_macro
="#define CVC4_FOR_EACH_THEORY \\
47 type_enumerator_includes
=
48 mk_type_enumerator_cases
=
50 theory_has_check
="false"
51 theory_has_propagate
="false"
52 theory_has_ppStaticLearn
="false"
53 theory_has_notifyRestart
="false"
54 theory_has_presolve
="false"
55 theory_has_postsolve
="false"
56 theory_has_getNextDecisionRequest
="false"
58 theory_stable_infinite
="false"
61 theory_parametric
="false"
73 seen_theory_builtin
=false
78 lineno
=${BASH_LINENO[0]}
81 echo "$kf:$lineno: error: multiple theories defined in one file !?" >&2
85 # this script doesn't care about the theory class information, but
86 # makes does make sure it's there
88 if [ "$1" = THEORY_BUILTIN
]; then
89 if $seen_theory_builtin; then
90 echo "$kf:$lineno: error: \"builtin\" theory redefined" >&2
93 seen_theory_builtin
=true
94 elif [ -z "$1" -o -z "$2" -o -z "$3" ]; then
95 echo "$kf:$lineno: error: \"theory\" directive missing class or header argument" >&2
97 elif ! expr "$2" : '\(::*\)' >/dev
/null
; then
98 echo "$kf:$lineno: warning: theory class \`$2' isn't fully-qualified (e.g., ::CVC4::theory::foo)" >&2
99 elif ! expr "$2" : '\(::CVC4::theory::*\)' >/dev
/null
; then
100 echo "$kf:$lineno: warning: theory class not under ::CVC4::theory namespace" >&2
107 theory_includes
="${theory_includes}#include \"$theory_header\"
109 theory_for_each_macro
="${theory_for_each_macro} CVC4_FOR_EACH_THEORY_STATEMENT(CVC4::theory::${theory_id}) \\
114 # alternate ID name T header
116 lineno
=${BASH_LINENO[0]}
118 if $seen_theory; then
119 echo "$kf:$lineno: error: multiple theories defined in one file !?" >&2
127 theory_includes
="${theory_includes}#include \"$theory_header\"
130 eval "alternate_for_$1=\"\${alternate_for_$1}
131 if(options::theoryAlternates()[\\\"$2\\\"]) {
132 engine->addTheory< $3 >($1);
138 # rewriter class header
139 lineno
=${BASH_LINENO[0]}
145 theory_includes
="${theory_includes}#include \"$2\"
151 lineno
=${BASH_LINENO[0]}
156 theory_constructors
="${theory_constructors}
158 \$alternate_for_$theory_id
159 engine->addTheory< $theory_class >($theory_id);
163 theory_traits
="${theory_traits}
165 struct TheoryTraits<${theory_id}> {
166 // typedef ${theory_class} theory_class;
167 typedef ${rewriter_class} rewriter_class;
169 static const bool isStableInfinite = ${theory_stable_infinite};
170 static const bool isFinite = ${theory_finite};
171 static const bool isPolite = ${theory_polite};
172 static const bool isParametric = ${theory_parametric};
174 static const bool hasCheck = ${theory_has_check};
175 static const bool hasPropagate = ${theory_has_propagate};
176 static const bool hasPpStaticLearn = ${theory_has_ppStaticLearn};
177 static const bool hasNotifyRestart = ${theory_has_notifyRestart};
178 static const bool hasPresolve = ${theory_has_presolve};
179 static const bool hasPostsolve = ${theory_has_postsolve};
180 static const bool hasGetNextDecisionRequest = ${theory_has_getNextDecisionRequest};
181 };/* struct TheoryTraits<${theory_id}> */
184 # warnings about theory content and properties
185 dir
="$(dirname "$kf")/../../"
186 if [ -e "$dir/$theory_header" ]; then
187 for function in check propagate ppStaticLearn notifyRestart presolve postsolve getNextDecisionRequest
; do
188 if eval "\$theory_has_$function"; then
189 grep '\<'"$function"' *\((\|;\)' "$dir/$theory_header" |
grep -vq '^ */\(/\|\*\)' ||
190 echo "$kf: warning: $theory_class has property \"$function\" in its kinds file but doesn't appear to declare the function" >&2
192 grep '\<'"$function"' *\((\|;\)' "$dir/$theory_header" |
grep -vq '^ */\(/\|\*\)' &&
193 echo "$kf: warning: $theory_class does not have property \"$function\" in its kinds file but appears to declare the function" >&2
197 echo "$me: warning: theory header \"$theory_header\" does not exist or is unreadable" >&2
200 theory_has_check
="false"
201 theory_has_propagate
="false"
202 theory_has_ppStaticLearn
="false"
203 theory_has_notifyRestart
="false"
204 theory_has_presolve
="false"
205 theory_has_postsolve
="false"
206 theory_has_getNextDecisionRequest
="false"
208 theory_stable_infinite
="false"
209 theory_finite
="false"
210 theory_polite
="false"
211 theory_parametric
="false"
222 lineno
=${BASH_LINENO[0]}
225 function enumerator
{
226 # enumerator KIND enumerator-class header
227 lineno
=${BASH_LINENO[0]}
229 type_enumerator_includes
="${type_enumerator_includes}
230 #line $lineno \"$kf\"
232 if expr "$type_constants" : '.* '"$1"' ' &>/dev
/null
; then
233 mk_type_enumerator_type_constant_cases
="${mk_type_enumerator_type_constant_cases}
234 #line $lineno \"$kf\"
236 #line $lineno \"$kf\"
239 elif expr "$type_kinds" : '.* '"$1"' ' &>/dev
/null
; then
240 mk_type_enumerator_cases
="${mk_type_enumerator_cases}
241 #line $lineno \"$kf\"
243 #line $lineno \"$kf\"
247 echo "$kf:$lineno: error: don't know anything about $1; enumerator must appear after definition" >&2
248 echo "type_constants: $type_constants" >&2
249 echo "type_kinds : $type_kinds" >&2
254 function typechecker
{
256 lineno
=${BASH_LINENO[0]}
261 # typerule OPERATOR typechecking-class
262 lineno
=${BASH_LINENO[0]}
267 # construle OPERATOR isconst-checking-class
268 lineno
=${BASH_LINENO[0]}
272 function properties
{
273 # properties property*
274 lineno
=${BASH_LINENO[0]}
280 finite
) theory_finite
="true";;
281 stable-infinite
) theory_stable_infinite
="true";;
282 parametric
) theory_parametric
="true";;
283 polite
) theory_polite
="true";;
284 check
) theory_has_check
="true";;
285 propagate
) theory_has_propagate
="true";;
286 ppStaticLearn
) theory_has_ppStaticLearn
="true";;
287 presolve
) theory_has_presolve
="true";;
288 postsolve
) theory_has_postsolve
="true";;
289 getNextDecisionRequest
) theory_has_getNextDecisionRequest
="true";;
290 notifyRestart
) theory_has_notifyRestart
="true";;
291 *) echo "$kf:$lineno: error: unknown theory property \"$property\"" >&2; exit 1;;
298 # sort TYPE cardinality [well-founded ground-term header | not-well-founded] ["comment"]
299 lineno
=${BASH_LINENO[0]}
301 if [ "$3" = well-founded
]; then
302 register_sort
"$1" "$2" "$6"
304 register_sort
"$1" "$2" "$4"
308 function cardinality
{
309 # cardinality TYPE cardinality-computer [header]
310 lineno
=${BASH_LINENO[0]}
314 function well-founded
{
315 # well-founded TYPE wellfoundedness-computer [header]
316 lineno
=${BASH_LINENO[0]}
321 # variable K ["comment"]
322 lineno
=${BASH_LINENO[0]}
324 register_kind
"$1" 0 "$2"
328 # operator K #children ["comment"]
329 lineno
=${BASH_LINENO[0]}
331 register_kind
"$1" "$2" "$3"
334 function parameterized
{
335 # parameterized K1 K2 #children ["comment"]
336 lineno
=${BASH_LINENO[0]}
338 register_kind
"$1" "$3" "$4"
342 # constant K T Hasher header ["comment"]
343 lineno
=${BASH_LINENO[0]}
345 register_kind
"$1" 0 "$5"
348 function register_sort
{
352 type_constant_to_theory_id
="${type_constant_to_theory_id} case $id: return $theory_id; break;
354 type_constants
="${type_constants} $1 "
357 function register_kind
{
361 kind_to_theory_id
="${kind_to_theory_id} case kind::$r: return $theory_id; break;
363 type_kinds
="${type_kinds} $1 "
366 function check_theory_seen
{
367 if $seen_endtheory; then
368 echo "$kf:$lineno: error: command after \"endtheory\" declaration (endtheory has to be last)" >&2
371 if ! $seen_theory; then
372 echo "$kf:$lineno: error: no \"theory\" declaration found (it has to be first)" >&2
377 function check_builtin_theory_seen
{
378 if ! $seen_theory_builtin; then
379 echo "$me: warning: no declaration for the builtin theory found" >&2
383 while [ $# -gt 0 ]; do
387 b
=$
(basename $
(dirname "$kf"))
389 if ! $seen_theory; then
390 echo "$kf: error: no theory content found in file!" >&2
393 if ! $seen_endtheory; then
394 echo "$kf:$lineno: error: no \"endtheory\" declaration found (it is required at the end)" >&2
399 check_builtin_theory_seen
403 eval "theory_constructors=\"$theory_constructors\""
405 # generate warnings about incorrect #line annotations in templates
406 nl -ba -s' ' "$template" |
grep '^ *[0-9][0-9]* # *line' |
407 awk '{OFS="";if($1+1!=$3) print "'"$template"':",$1,": warning: incorrect annotation \"#line ",$3,"\" (it should be \"#line ",($1+1),"\")"}' >&2
409 text
=$
(cat "$template")
412 theory_for_each_macro \
414 theory_constructors \
416 type_enumerator_includes \
417 mk_type_enumerator_type_constant_cases \
418 mk_type_enumerator_cases \
420 eval text
="\${text//\\\$\\{$var\\}/\${$var}}"
422 error
=`expr "$text" : '.*\${\([^}]*\)}.*'`
423 if [ -n "$error" ]; then
424 echo "$template:0: error: undefined replacement \${$error}" >&2