Class: SolverSession
- Inherits:
-
Object
- Object
- SolverSession
- Defined in:
- lib/solver-lib.rb
Instance Method Summary collapse
- #associateAssertionIDWith(assertionID, hash) ⇒ Object
- #checkLineForSolverError(line, progress) ⇒ Object
- #declare_const(progress, name, type, info) ⇒ Object
- #emptyReadBuffer(progress) ⇒ Object
- #for_each_const(&block) ⇒ Object
- #from_solver(progress) ⇒ Object
- #generateNextAssertionIDAndAssociateWith(hash) ⇒ Object
- #get_const_info(name) ⇒ Object
- #getAssociationForAssertionID(assertionID) ⇒ Object
- #handleSolverError(progress, options, result) ⇒ Object
-
#initialize(solverFactory, logFileName) ⇒ SolverSession
constructor
A new instance of SolverSession.
- #parse_unsat_core(unsat_core) ⇒ Object
- #read_multiline_from_solver ⇒ Object
- #replace_strings(line) ⇒ Object
- #switch_solver(progress) ⇒ Object
- #to_solver(progress, line) ⇒ Object
- #writeProtocolToFile(progress, filename) ⇒ Object
Constructor Details
#initialize(solverFactory, logFileName) ⇒ SolverSession
Returns a new instance of SolverSession.
8 9 10 11 12 13 14 15 16 |
# File 'lib/solver-lib.rb', line 8 def initialize(solverFactory, logFileName) @solverFactory = solverFactory @solver = @solverFactory.new_solver() @protocol_filename = logFileName @protocol = File.open(@protocol_filename, "w") @assertCounter = -1 @associations = {} @consts = {} end |
Instance Method Details
#associateAssertionIDWith(assertionID, hash) ⇒ Object
142 143 144 145 146 147 |
# File 'lib/solver-lib.rb', line 142 def associateAssertionIDWith(assertionID, hash) if @associations.has_key?(assertionID) then raise RuntimeError.new("AssertionID #{assertionID.inspect} already has info associated with it!") end @associations[assertionID] = hash end |
#checkLineForSolverError(line, progress) ⇒ Object
84 85 86 87 88 |
# File 'lib/solver-lib.rb', line 84 def checkLineForSolverError(line, progress) if line =~ /\(error \"(.*)\"\)/ then progress.print_line("WARN: Solver reported ERROR: #{$1}") end end |
#declare_const(progress, name, type, info) ⇒ Object
53 54 55 56 57 |
# File 'lib/solver-lib.rb', line 53 def declare_const(progress, name, type, info) info[:type] = type @consts[name] = info to_solver(progress, "(declare-const #{name} #{type})") end |
#emptyReadBuffer(progress) ⇒ Object
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/solver-lib.rb', line 31 def emptyReadBuffer(progress) empty = false while !empty do begin c = "" @solver.z3outAndErr.read_nonblock(1, c) line = c + @solver.z3outAndErr.gets checkLineForSolverError(line, progress) @protocol.puts("; Solver Response: #{line}") rescue Errno::EWOULDBLOCK # there is nothing to read -> just continue empty = true rescue Errno::EAGAIN # there is nothing to read -> just continue empty = true rescue EOFError # there is nothing to read -> just continue empty = true end end end |
#for_each_const(&block) ⇒ Object
153 154 155 156 157 |
# File 'lib/solver-lib.rb', line 153 def for_each_const(&block) @consts.each do |key, value| block.call(key, value) end end |
#from_solver(progress) ⇒ Object
91 92 93 94 95 96 |
# File 'lib/solver-lib.rb', line 91 def from_solver(progress) result = @solver.z3outAndErr.gets(chomp: true) checkLineForSolverError(result, progress) @protocol.puts("; Solver Response: #{result}") return result end |
#generateNextAssertionIDAndAssociateWith(hash) ⇒ Object
136 137 138 139 140 |
# File 'lib/solver-lib.rb', line 136 def generateNextAssertionIDAndAssociateWith(hash) nextAssertionID = "a#{@assertCounter += 1}" @associations[nextAssertionID] = hash return nextAssertionID end |
#get_const_info(name) ⇒ Object
159 160 161 |
# File 'lib/solver-lib.rb', line 159 def get_const_info(name) @consts[name] end |
#getAssociationForAssertionID(assertionID) ⇒ Object
149 150 151 |
# File 'lib/solver-lib.rb', line 149 def getAssociationForAssertionID(assertionID) return @associations[assertionID] end |
#handleSolverError(progress, options, result) ⇒ Object
167 168 169 |
# File 'lib/solver-lib.rb', line 167 def handleSolverError(progress, , result) @solver.handleSolverError(progress, self, , result) end |
#parse_unsat_core(unsat_core) ⇒ Object
163 164 165 |
# File 'lib/solver-lib.rb', line 163 def parse_unsat_core(unsat_core) @solver.parse_unsat_core(unsat_core, self) end |
#read_multiline_from_solver ⇒ Object
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 |
# File 'lib/solver-lib.rb', line 102 def read_multiline_from_solver() result = "" for_counting = "" @protocol.puts @protocol.puts("; BEGIN Multiline Solver Response:") line = @solver.z3outAndErr.gets(chomp: true) result += line for_counting = replace_strings(line) @protocol.puts("; #{line}") num_opening = for_counting.count("(") num_closing = for_counting.count(")") while num_opening > num_closing && line != nil do line = @solver.z3outAndErr.gets(chomp: true) if line result += line for_counting = replace_strings(line) @protocol.puts("; #{line}") num_opening += for_counting.count("(") num_closing += for_counting.count(")") end end @protocol.puts("; END Multiline Solver Response") return result end |
#replace_strings(line) ⇒ Object
98 99 100 |
# File 'lib/solver-lib.rb', line 98 def replace_strings(line) line.gsub(/"[^"]*"/, "") end |
#switch_solver(progress) ⇒ Object
18 19 20 21 22 23 24 25 26 27 28 29 |
# File 'lib/solver-lib.rb', line 18 def switch_solver(progress) @solver.close() @solver = @solverFactory.new_solver() # re-feed the session protocol into the new solver to get it up-to-date @protocol.close() File.open(@protocol_filename, "r") do |protocol| protocol.each_line do |line| to_solver(progress, line) end end @protocol = File.open(@protocol_filename, "a") end |
#to_solver(progress, line) ⇒ Object
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/solver-lib.rb', line 59 def to_solver(progress, line) emptyReadBuffer(progress); success = false while (!success) do begin @solver.z3in.puts(line) success = true rescue Errno::EINVAL => e progress.print_line("DEBUG: Invalid argument to puts(): #{line.inspect}") progress.print_line("An Error occured: #{e.}") e.backtrace.each { |stline| progress.print_line(stline) } progress.print_line("=> Switching Solver") switch_solver(progress) progress.print_line("=> Switch successful. Trying again.") rescue Errno::EPIPE => e progress.print_line("An Error occured: #{e.}") e.backtrace.each { |stline| progress.print_line(stline) } progress.print_line("=> Switching Solver") switch_solver(progress) progress.print_line("=> Switch successful. Trying again.") end end @protocol.puts(line) end |
#writeProtocolToFile(progress, filename) ⇒ Object
129 130 131 132 133 134 |
# File 'lib/solver-lib.rb', line 129 def writeProtocolToFile(progress, filename) dir = File.dirname(filename) FileUtils.mkdir_p(dir) unless Dir.exist?(dir) FileUtils.cp(@protocol_filename, filename) unless @protocol_filename == filename progress.print_line "Solver protocol written to file #{filename}" end |