Class: Udb::Z3Solver
- Inherits:
-
Object
- Object
- Udb::Z3Solver
- Extended by:
- Forwardable, T::Sig
- Defined in:
- lib/udb/z3.rb
Overview
Main Z3 solver wrapper for RISC-V architecture validation
This class provides a high-level interface to Z3 for validating RISC-V configurations. It manages:
-
Parameter terms with JSON schema constraints
-
Extension version terms
-
Extension requirement terms
-
Stack-based solver contexts (push/pop)
The solver maintains caches of terms organized in stacks, allowing incremental solving with backtracking via push/pop operations.
Instance Attribute Summary collapse
-
#solver ⇒ Object
readonly
Returns the value of attribute solver.
Class Method Summary collapse
- .configure_parallelization(desired) ⇒ Object
- .parallel_enabled ⇒ Object
- .parallel_enabled=(value) ⇒ Object
Instance Method Summary collapse
- #ext_major(name) ⇒ Object
- #ext_minor(name) ⇒ Object
- #ext_patch(name) ⇒ Object
- #ext_pre(name) ⇒ Object
- #ext_req(name, req, cfg_arch) ⇒ Object
- #ext_ver(name, version, cfg_arch) ⇒ Object
-
#initialize ⇒ Z3Solver
constructor
A new instance of Z3Solver.
- #param(name, schema_hsh) ⇒ Object
- #pop ⇒ Object
- #push ⇒ Object
- #xlen ⇒ Object
Constructor Details
#initialize ⇒ Z3Solver
Returns a new instance of Z3Solver.
1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 |
# File 'lib/udb/z3.rb', line 1118 def initialize if Udb..parallel_z3 Z3Solver.configure_parallelization(true) else Z3Solver.configure_parallelization(false) end @solver = T.let(Z3::Solver.new, Z3::Solver) # Stacks for incremental solving with push/pop @ext_vers = T.let([{}], T::Array[T::Hash[String, Z3ExtensionVersion]]) @ext_reqs = T.let([{}], T::Array[T::Hash[String, Z3ExtensionRequirement]]) @param_terms = T.let([{}], T::Array[T::Hash[String, Z3ParameterTerm]]) # Extension version component terms (shared across versions of same extension) @ext_majors = T.let([{}], T::Array[T::Hash[String, Z3::IntExpr]]) @ext_minors = T.let([{}], T::Array[T::Hash[String, Z3::IntExpr]]) @ext_patches = T.let([{}], T::Array[T::Hash[String, Z3::IntExpr]]) @ext_pres = T.let([{}], T::Array[T::Hash[String, Z3::BoolExpr]]) @xlen = T.let(nil, T.nilable(Z3::IntExpr)) end |
Instance Attribute Details
#solver ⇒ Object (readonly)
Returns the value of attribute solver.
1083 1084 1085 |
# File 'lib/udb/z3.rb', line 1083 def solver @solver end |
Class Method Details
.configure_parallelization(desired) ⇒ Object
1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 |
# File 'lib/udb/z3.rb', line 1101 def configure_parallelization(desired) previous = parallel_enabled if !previous.nil? && previous != desired if desired Udb.logger.warn "Z3 parallelization was previously disabled, but is now being enabled" else Udb.logger.warn "Z3 parallelization was previously enabled, but is now being disabled" end end Z3.set_param("parallel.enable", desired ? "true" : "false") self.parallel_enabled = desired end |
.parallel_enabled ⇒ Object
1091 1092 1093 |
# File 'lib/udb/z3.rb', line 1091 def parallel_enabled @parallel_enabled end |
.parallel_enabled=(value) ⇒ Object
1096 1097 1098 |
# File 'lib/udb/z3.rb', line 1096 def parallel_enabled=(value) @parallel_enabled = value end |
Instance Method Details
#ext_major(name) ⇒ Object
1228 1229 1230 1231 1232 1233 1234 1235 |
# File 'lib/udb/z3.rb', line 1228 def ext_major(name) @ext_majors.reverse_each do |h| if h.key?(name) return h.fetch(name) end end T.must(@ext_majors.last)[name] ||= Z3.Int("#{name}_major") end |
#ext_minor(name) ⇒ Object
1238 1239 1240 1241 1242 1243 1244 1245 |
# File 'lib/udb/z3.rb', line 1238 def ext_minor(name) @ext_minors.reverse_each do |h| if h.key?(name) return h.fetch(name) end end T.must(@ext_minors.last)[name] ||= Z3.Int("#{name}_minor") end |
#ext_patch(name) ⇒ Object
1248 1249 1250 1251 1252 1253 1254 1255 |
# File 'lib/udb/z3.rb', line 1248 def ext_patch(name) @ext_patches.reverse_each do |h| if h.key?(name) return h.fetch(name) end end T.must(@ext_patches.last)[name] ||= Z3.Int("#{name}_patch") end |
#ext_pre(name) ⇒ Object
1258 1259 1260 1261 1262 1263 1264 1265 |
# File 'lib/udb/z3.rb', line 1258 def ext_pre(name) @ext_pres.reverse_each do |h| if h.key?(name) return h.fetch(name) end end T.must(@ext_pres.last)[name] ||= Z3.Bool("#{name}_pre") end |
#ext_req(name, req, cfg_arch) ⇒ Object
1214 1215 1216 1217 1218 1219 1220 1221 1222 |
# File 'lib/udb/z3.rb', line 1214 def ext_req(name, req, cfg_arch) key = [name, req].hash @ext_reqs.reverse_each do |h| if h.key?(key) return h.fetch(key) end end T.must(@ext_reqs.last)[key] ||= Z3ExtensionRequirement.new(name, req, self, cfg_arch) end |
#ext_ver(name, version, cfg_arch) ⇒ Object
1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 |
# File 'lib/udb/z3.rb', line 1195 def ext_ver(name, version, cfg_arch) version_spec = version.is_a?(VersionSpec) ? version : VersionSpec.new(version) key = [name, version_spec].hash # Search from most recent context backwards @ext_vers.reverse_each do |h| if h.key?(key) return h.fetch(key) end end # Create new term in current context ev = Z3ExtensionVersion.new(name, version_spec, self, cfg_arch) T.must(@ext_vers.last)[key] = ev ev end |
#param(name, schema_hsh) ⇒ Object
1273 1274 1275 1276 1277 1278 1279 1280 |
# File 'lib/udb/z3.rb', line 1273 def param(name, schema_hsh) @param_terms.reverse_each do |h| if h.key?(name) return h.fetch(name) end end T.must(@param_terms.last)[name] = Z3ParameterTerm.new(name, self, schema_hsh) end |
#pop ⇒ Object
1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 |
# File 'lib/udb/z3.rb', line 1146 def pop if @ext_vers.size == 1 Udb.logger.error "Popping solver at base level" raise end @ext_vers.pop @ext_reqs.pop @param_terms.pop @ext_majors.pop @ext_minors.pop @ext_patches.pop @ext_pres.pop @solver.pop end |
#push ⇒ Object
1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 |
# File 'lib/udb/z3.rb', line 1166 def push @ext_vers.push({}) @ext_reqs.push({}) @param_terms.push({}) @ext_majors.push({}) @ext_minors.push({}) @ext_patches.push({}) @ext_pres.push({}) @solver.push end |
#xlen ⇒ Object
1182 1183 1184 1185 1186 1187 1188 |
# File 'lib/udb/z3.rb', line 1182 def xlen unless @xlen @xlen = Z3.Int("xlen") @solver.assert_as((@xlen == 32) | (@xlen == 64), "_pxlen") end @xlen end |