Class: Factbase

Inherits:
Object
  • Object
show all
Defined in:
lib/factbase.rb

Overview

Factbase.

This is an entry point to a factbase:

fb = Factbase.new
f = fb.insert # new fact created
f.name = 'Jeff Lebowski'
f.age = 42
found = f.query('(gt 20 age)').each.to_a[0]
assert(found.age == 42)

A factbase may be exported to a file and then imported back:

fb1 = Factbase.new
File.writebin(file, fb1.export)
fb2 = Factbase.new # it's empty
fb2.import(File.readbin(file))

It’s important to use writebin and readbin, because the content is a chain of bytes, not a text.

Author

Yegor Bugayenko ([email protected])

Copyright

Copyright © 2024 Yegor Bugayenko

License

MIT

Defined Under Namespace

Classes: Fact, Inv, Looged, Pre, Query, Rules, Syntax, Term, ToJSON, ToXML, ToYAML, Tuples

Constant Summary collapse

VERSION =

Current version of the gem (changed by .rultor.yml on every release)

'0.0.38'

Instance Method Summary collapse

Constructor Details

#initialize(facts = []) ⇒ Factbase

Constructor.



55
56
57
58
# File 'lib/factbase.rb', line 55

def initialize(facts = [])
  @maps = facts
  @mutex = Mutex.new
end

Instance Method Details

#dupFactbase

Make a duplicate of this factbase.

Returns:



62
63
64
# File 'lib/factbase.rb', line 62

def dup
  Factbase.new(@maps.dup)
end

#exportObject

Export it into a chain of bytes.



120
121
122
# File 'lib/factbase.rb', line 120

def export
  Marshal.dump(@maps)
end

#import(bytes) ⇒ Object

Import from a chain of bytes.



125
126
127
# File 'lib/factbase.rb', line 125

def import(bytes)
  @maps += Marshal.load(bytes)
end

#insertFactbase::Fact

Insert a new fact.

Returns:



74
75
76
77
78
79
80
81
# File 'lib/factbase.rb', line 74

def insert
  require_relative 'factbase/fact'
  map = {}
  @mutex.synchronize do
    @maps << map
  end
  Factbase::Fact.new(@mutex, map)
end

#query(query) ⇒ Object

Create a query capable of iterating.

There is a Lisp-like syntax, for example:

(eq title 'Object Thinking')
(gt time 2024-03-23T03:21:43Z)
(gt cost 42)
(exists seenBy)
(and
  (eq foo 42.998)
  (or
    (gt bar 200)
    (absent zzz)))

Parameters:

  • query (String)

    The query to use for selections



98
99
100
101
# File 'lib/factbase.rb', line 98

def query(query)
  require_relative 'factbase/query'
  Factbase::Query.new(@maps, @mutex, query)
end

#sizeInteger

Size.

Returns:

  • (Integer)

    How many facts are in there



68
69
70
# File 'lib/factbase.rb', line 68

def size
  @maps.size
end

#txn(this = self) {|copy| ... } ⇒ Object

Run an ACID transaction, which will either modify the factbase or rollback in case of an error.

Yields:

  • (copy)


105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/factbase.rb', line 105

def txn(this = self)
  copy = this.dup
  yield copy
  @mutex.synchronize do
    after = Marshal.load(copy.export)
    after.each_with_index do |m, i|
      @maps << {} if i >= @maps.size
      m.each do |k, v|
        @maps[i][k] = v
      end
    end
  end
end