Sha256: c9a0a041e69b769db7a8aab157667f75dd433a2137a4a2a0b2b5689a7caed6af

Contents?: true

Size: 1.62 KB

Versions: 1

Compression:

Stored size: 1.62 KB

Contents

# frozen_string_literal: true

module PrologMQI
  class PrologMQI
    def initialize(timeout: 5)
      @timeout = timeout

      @process = nil
      @unix_domain_socket = nil
      @running = false
    end

    def running?
      @running
    end

    def session
      start unless running?
      yield self
    ensure
      stop if running?
    end

    def start
      # Start prolog process
      @stdin, @stdout, @stderr, @process =
        Open3.popen3('swipl', '--quiet', '-g', 'mqi_start', '-t', 'halt', '--', '--write_connection_values=true',
                     '--create_unix_domain_socket=true')

      unix_domain_socket = @stdout.gets.chomp
      password = @stdout.gets.chomp

      # Create unix socket
      Timeout.timeout(@timeout) do
        @socket = UNIXSocket.new(unix_domain_socket)
      rescue Errno::ECONNREFUSED
        retry
      end

      # Authenticate
      write(password)
      read
    end

    def query(value)
      timeout_str = @timeout.nil? ? '_' : @timeout.to_s
      write("run(#{value}, #{timeout_str})")
      read
    end

    def read
      bytesize = @socket.gets.chomp(".\n").to_i
      result = @socket.read(bytesize)
      Parser.new(result).parse
    end

    def write(value)
      message = "#{value}.\n"
      # FIXME: in PrologMQI major version 0,
      # the message length is count of Unicode code points, not bytes.
      bytesize = message.bytesize
      @socket.write("#{bytesize}.\n")
      @socket.write(message)
    end

    def stop(kill: false)
      @socket.close
      @stdin.close
      @stdout.close
      @stderr.close
      @process.kill if kill
      @process.close
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
prolog_mqi-0.1.1 lib/prolog_mqi/prolog_mqi.rb