sooth 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/Gemfile +12 -0
- data/Gemfile.lock +90 -0
- data/README.md +28 -0
- data/Rakefile +47 -0
- data/UNLICENSE +24 -0
- data/VERSION +1 -0
- data/ext/sooth_native/extconf.rb +2 -0
- data/ext/sooth_native/native.c +190 -0
- data/ext/sooth_native/sooth_context.h +21 -0
- data/ext/sooth_native/sooth_predictor.c +257 -0
- data/ext/sooth_native/sooth_predictor.h +33 -0
- data/ext/sooth_native/sooth_statistic.h +19 -0
- data/lib/sooth.rb +1 -0
- data/sooth.gemspec +80 -0
- data/spec/memory_spec.rb +35 -0
- data/spec/predictor_spec.rb +64 -0
- data/spec/spec_helper.rb +30 -0
- metadata +174 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 35b7050c2c66e43c65ee1afc05bb4534267d01e3
|
4
|
+
data.tar.gz: 79302a0867744f4cd86d4090adcc3b1c792f22c5
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ae6731afecca1a16085d65601c7f01ff8157d9e5a2d2f9fff987b6bd74dec00efd1de9a8f51402327669101e6646dee2d9971e6b267240453247d2443efae39b
|
7
|
+
data.tar.gz: 44b75b169a0c4ffed66eb873d92c93f6ddb305dc037c6dc14e8411d39d50f1ee3bd8a0f16723cadbcd14d5cea2041bb403d5613003bd9ab7cfe573a8322d085b
|
data/Gemfile
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
group :development do
|
4
|
+
gem 'rspec', '~> 3.1'
|
5
|
+
gem 'yard', '~> 0.8'
|
6
|
+
gem 'rdoc', '~> 4.1'
|
7
|
+
gem 'bundler', '~> 1.7'
|
8
|
+
gem 'jeweler', '~> 2.0'
|
9
|
+
gem 'simplecov', '~> 0.9'
|
10
|
+
gem 'byebug', '~> 3.5'
|
11
|
+
gem 'rake-compiler', '~> 0.9'
|
12
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
GEM
|
2
|
+
remote: https://rubygems.org/
|
3
|
+
specs:
|
4
|
+
addressable (2.3.6)
|
5
|
+
builder (3.2.2)
|
6
|
+
byebug (3.5.1)
|
7
|
+
columnize (~> 0.8)
|
8
|
+
debugger-linecache (~> 1.2)
|
9
|
+
slop (~> 3.6)
|
10
|
+
columnize (0.9.0)
|
11
|
+
debugger-linecache (1.2.0)
|
12
|
+
descendants_tracker (0.0.4)
|
13
|
+
thread_safe (~> 0.3, >= 0.3.1)
|
14
|
+
diff-lcs (1.2.5)
|
15
|
+
docile (1.1.5)
|
16
|
+
faraday (0.9.0)
|
17
|
+
multipart-post (>= 1.2, < 3)
|
18
|
+
git (1.2.8)
|
19
|
+
github_api (0.12.2)
|
20
|
+
addressable (~> 2.3)
|
21
|
+
descendants_tracker (~> 0.0.4)
|
22
|
+
faraday (~> 0.8, < 0.10)
|
23
|
+
hashie (>= 3.3)
|
24
|
+
multi_json (>= 1.7.5, < 2.0)
|
25
|
+
nokogiri (~> 1.6.3)
|
26
|
+
oauth2
|
27
|
+
hashie (3.3.2)
|
28
|
+
highline (1.6.21)
|
29
|
+
jeweler (2.0.1)
|
30
|
+
builder
|
31
|
+
bundler (>= 1.0)
|
32
|
+
git (>= 1.2.5)
|
33
|
+
github_api
|
34
|
+
highline (>= 1.6.15)
|
35
|
+
nokogiri (>= 1.5.10)
|
36
|
+
rake
|
37
|
+
rdoc
|
38
|
+
json (1.8.1)
|
39
|
+
jwt (1.2.0)
|
40
|
+
mini_portile (0.6.1)
|
41
|
+
multi_json (1.10.1)
|
42
|
+
multi_xml (0.5.5)
|
43
|
+
multipart-post (2.0.0)
|
44
|
+
nokogiri (1.6.5)
|
45
|
+
mini_portile (~> 0.6.0)
|
46
|
+
oauth2 (1.0.0)
|
47
|
+
faraday (>= 0.8, < 0.10)
|
48
|
+
jwt (~> 1.0)
|
49
|
+
multi_json (~> 1.3)
|
50
|
+
multi_xml (~> 0.5)
|
51
|
+
rack (~> 1.2)
|
52
|
+
rack (1.5.2)
|
53
|
+
rake (10.4.2)
|
54
|
+
rake-compiler (0.9.3)
|
55
|
+
rake
|
56
|
+
rdoc (4.2.0)
|
57
|
+
json (~> 1.4)
|
58
|
+
rspec (3.1.0)
|
59
|
+
rspec-core (~> 3.1.0)
|
60
|
+
rspec-expectations (~> 3.1.0)
|
61
|
+
rspec-mocks (~> 3.1.0)
|
62
|
+
rspec-core (3.1.7)
|
63
|
+
rspec-support (~> 3.1.0)
|
64
|
+
rspec-expectations (3.1.2)
|
65
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
66
|
+
rspec-support (~> 3.1.0)
|
67
|
+
rspec-mocks (3.1.3)
|
68
|
+
rspec-support (~> 3.1.0)
|
69
|
+
rspec-support (3.1.2)
|
70
|
+
simplecov (0.9.1)
|
71
|
+
docile (~> 1.1.0)
|
72
|
+
multi_json (~> 1.0)
|
73
|
+
simplecov-html (~> 0.8.0)
|
74
|
+
simplecov-html (0.8.0)
|
75
|
+
slop (3.6.0)
|
76
|
+
thread_safe (0.3.4)
|
77
|
+
yard (0.8.7.6)
|
78
|
+
|
79
|
+
PLATFORMS
|
80
|
+
ruby
|
81
|
+
|
82
|
+
DEPENDENCIES
|
83
|
+
bundler (~> 1.7)
|
84
|
+
byebug (~> 3.5)
|
85
|
+
jeweler (~> 2.0)
|
86
|
+
rake-compiler (~> 0.9)
|
87
|
+
rdoc (~> 4.1)
|
88
|
+
rspec (~> 3.1)
|
89
|
+
simplecov (~> 0.9)
|
90
|
+
yard (~> 0.8)
|
data/README.md
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
[](http://badge.fury.io/rb/sooth)
|
2
|
+
[](https://gemnasium.com/jasonhutchens/sooth)
|
3
|
+
[](http://travis-ci.org/#!/jasonhutchens/sooth)
|
4
|
+
[](https://codeclimate.com/github/jasonhutchens/sooth)
|
5
|
+
|
6
|
+
Sooth
|
7
|
+
=====
|
8
|
+
|
9
|
+
Sooth is a simple stochastic predictive model.
|
10
|
+
|
11
|
+
Getting Started
|
12
|
+
---------------
|
13
|
+
|
14
|
+
Apart from the specs, look at the [API docs](http://rubydoc.info/github/jasonhutchens/sooth/master/frames) to get up to speed.
|
15
|
+
|
16
|
+
Next
|
17
|
+
----
|
18
|
+
|
19
|
+
* Implement save and load (with specs)
|
20
|
+
* Version 0.9
|
21
|
+
* Hook up to all services
|
22
|
+
* Version 1
|
23
|
+
* MegaHAL that uses it
|
24
|
+
|
25
|
+
Copyright
|
26
|
+
---------
|
27
|
+
|
28
|
+
Copyright (c) 2014 Jason Hutchens. See UNLICENSE for further details.
|
data/Rakefile
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
begin
|
6
|
+
Bundler.setup(:default, :development)
|
7
|
+
rescue Bundler::BundlerError => e
|
8
|
+
$stderr.puts e.message
|
9
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
+
exit e.status_code
|
11
|
+
end
|
12
|
+
require 'rake'
|
13
|
+
|
14
|
+
require 'jeweler'
|
15
|
+
Jeweler::Tasks.new do |gem|
|
16
|
+
# gem is a Gem::Specification... see http://guides.rubygems.org/specification-reference/ for more options
|
17
|
+
gem.name = "sooth"
|
18
|
+
gem.homepage = "http://github.com/jasonhutchens/sooth"
|
19
|
+
gem.license = "MIT"
|
20
|
+
gem.summary = %Q{A small thing for generating codes for users to type into places}
|
21
|
+
gem.description = %Q{Does what it says on the box}
|
22
|
+
gem.email = "jasonhutchens@gmail.com"
|
23
|
+
gem.authors = ["Jason Hutchens"]
|
24
|
+
gem.required_ruby_version = "~> 2.1"
|
25
|
+
# dependencies defined in Gemfile
|
26
|
+
end
|
27
|
+
Jeweler::RubygemsDotOrgTasks.new
|
28
|
+
|
29
|
+
require 'rake/extensiontask'
|
30
|
+
Rake::ExtensionTask.new('sooth_native')
|
31
|
+
|
32
|
+
require 'rspec/core'
|
33
|
+
require 'rspec/core/rake_task'
|
34
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
35
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
36
|
+
end
|
37
|
+
|
38
|
+
desc "Code coverage detail"
|
39
|
+
task :simplecov do
|
40
|
+
ENV['COVERAGE'] = "true"
|
41
|
+
Rake::Task['spec'].execute
|
42
|
+
end
|
43
|
+
|
44
|
+
task :default => :spec
|
45
|
+
|
46
|
+
require 'yard'
|
47
|
+
YARD::Rake::YardocTask.new
|
data/UNLICENSE
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
This is free and unencumbered software released into the public domain.
|
2
|
+
|
3
|
+
Anyone is free to copy, modify, publish, use, compile, sell, or
|
4
|
+
distribute this software, either in source code form or as a compiled
|
5
|
+
binary, for any purpose, commercial or non-commercial, and by any
|
6
|
+
means.
|
7
|
+
|
8
|
+
In jurisdictions that recognize copyright laws, the author or authors
|
9
|
+
of this software dedicate any and all copyright interest in the
|
10
|
+
software to the public domain. We make this dedication for the benefit
|
11
|
+
of the public at large and to the detriment of our heirs and
|
12
|
+
successors. We intend this dedication to be an overt act of
|
13
|
+
relinquishment in perpetuity of all present and future rights to this
|
14
|
+
software under copyright law.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
19
|
+
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
20
|
+
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
21
|
+
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
22
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
23
|
+
|
24
|
+
For more information, please refer to <http://unlicense.org/>
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
@@ -0,0 +1,190 @@
|
|
1
|
+
//==============================================================================
|
2
|
+
|
3
|
+
#include <ruby.h>
|
4
|
+
|
5
|
+
#include "sooth_predictor.h"
|
6
|
+
|
7
|
+
//------------------------------------------------------------------------------
|
8
|
+
|
9
|
+
VALUE Sooth = Qnil;
|
10
|
+
VALUE SoothNative = Qnil;
|
11
|
+
|
12
|
+
VALUE method_sooth_native_allocate(VALUE klass);
|
13
|
+
void method_sooth_native_deallocate(void * predictor);
|
14
|
+
|
15
|
+
/* @!parse [ruby]
|
16
|
+
* module Sooth
|
17
|
+
* # A very simple stochastic predictor. Implemented in C for efficiency.
|
18
|
+
* # The idea here is to build up more complicated learning algorithms using
|
19
|
+
* # a trivial Markovian predictor.
|
20
|
+
* class Predictor
|
21
|
+
* def initialize(error_symbol)
|
22
|
+
* end
|
23
|
+
* def observe(bigram, symbol)
|
24
|
+
* # (native code)
|
25
|
+
* end
|
26
|
+
* def count(bigram)
|
27
|
+
* # (native code)
|
28
|
+
* end
|
29
|
+
* def select(bigram, limit)
|
30
|
+
* # (native code)
|
31
|
+
* end
|
32
|
+
* end
|
33
|
+
* end
|
34
|
+
*
|
35
|
+
* Returns a new Sooth::Predictor instance.
|
36
|
+
*
|
37
|
+
* @param [Fixnum] error_symbol The symbol to be returned by #select when no
|
38
|
+
* prediction can be made.
|
39
|
+
*/
|
40
|
+
VALUE method_sooth_native_initialize(VALUE self, VALUE error_symbol);
|
41
|
+
|
42
|
+
/*
|
43
|
+
* Add an observation of the given symbol in the context of the bigram.
|
44
|
+
*
|
45
|
+
* @param [Array] bigram A pair of symbols that provide context, allowing the
|
46
|
+
* predictor to maintain observation statistics for
|
47
|
+
* different contexts.
|
48
|
+
* @param [Fixnum] symbol The symbol that has been observed.
|
49
|
+
* @return [Fixnum] A count of the number of times the symbol has been
|
50
|
+
* observed in the context of the bigram.
|
51
|
+
*/
|
52
|
+
VALUE method_sooth_native_observe(VALUE self, VALUE bigram, VALUE symbol);
|
53
|
+
|
54
|
+
/*
|
55
|
+
* Return a count of the number of times the bigram has been observed.
|
56
|
+
*
|
57
|
+
* @param [Array] bigram A pair of symbols.
|
58
|
+
* @return [Fixnum] A count of the number of times the bigram has been
|
59
|
+
* observed. This is guaranteed to be equal to the sum
|
60
|
+
* of the counts of observations of all symbols in the
|
61
|
+
* context of the bigram.
|
62
|
+
*/
|
63
|
+
VALUE method_sooth_native_count(VALUE self, VALUE bigram);
|
64
|
+
|
65
|
+
/*
|
66
|
+
* Return a symbol that may occur in the context of the bigram. The
|
67
|
+
* limit is used to select a symbol. This is done by iterating through
|
68
|
+
* all of the symbols that have been observed in the context of the
|
69
|
+
* bigram, subtracting the observation count of each symbol from the
|
70
|
+
* supplied limit. For this reason, limit should be between 1 and the
|
71
|
+
* observation count of the bigram itself, as returned by #count.
|
72
|
+
*
|
73
|
+
* @param [Array] bigram A pair of symbols.
|
74
|
+
* @param [Fixnum] limit The total numbe of symbol observations to be
|
75
|
+
* analysed before returning a symbol.
|
76
|
+
* @return [Fixnum] A symbol that has been observed previously in the
|
77
|
+
* context of the bigram, or the error_symbol if no
|
78
|
+
* such symbol exists, or if the supplied limit was
|
79
|
+
* too large.
|
80
|
+
*/
|
81
|
+
VALUE method_sooth_native_select(VALUE self, VALUE bigram, VALUE limit);
|
82
|
+
|
83
|
+
//------------------------------------------------------------------------------
|
84
|
+
|
85
|
+
void Init_sooth_native()
|
86
|
+
{
|
87
|
+
Sooth = rb_define_module("Sooth");
|
88
|
+
SoothNative = rb_define_class_under(Sooth, "Predictor", rb_cObject);
|
89
|
+
|
90
|
+
rb_define_alloc_func(SoothNative, method_sooth_native_allocate);
|
91
|
+
rb_define_method(SoothNative, "initialize", method_sooth_native_initialize, 1);
|
92
|
+
|
93
|
+
rb_define_method(SoothNative, "observe", method_sooth_native_observe, 2);
|
94
|
+
rb_define_method(SoothNative, "count", method_sooth_native_count, 1);
|
95
|
+
rb_define_method(SoothNative, "select", method_sooth_native_select, 2);
|
96
|
+
}
|
97
|
+
|
98
|
+
//------------------------------------------------------------------------------
|
99
|
+
|
100
|
+
VALUE
|
101
|
+
method_sooth_native_allocate(VALUE klass)
|
102
|
+
{
|
103
|
+
SoothPredictor * predictor = sooth_predictor_init();
|
104
|
+
if (predictor == NULL)
|
105
|
+
{
|
106
|
+
return Qnil;
|
107
|
+
}
|
108
|
+
return Data_Wrap_Struct(klass, NULL, method_sooth_native_deallocate, predictor);
|
109
|
+
}
|
110
|
+
|
111
|
+
//------------------------------------------------------------------------------
|
112
|
+
|
113
|
+
void
|
114
|
+
method_sooth_native_deallocate(void * predictor)
|
115
|
+
{
|
116
|
+
sooth_predictor_free((SoothPredictor *)predictor);
|
117
|
+
}
|
118
|
+
|
119
|
+
//------------------------------------------------------------------------------
|
120
|
+
|
121
|
+
VALUE
|
122
|
+
method_sooth_native_initialize(VALUE self, VALUE error_symbol)
|
123
|
+
{
|
124
|
+
SoothPredictor * predictor = NULL;
|
125
|
+
Check_Type(error_symbol, T_FIXNUM);
|
126
|
+
Data_Get_Struct(self, SoothPredictor, predictor);
|
127
|
+
predictor->error_symbol = NUM2UINT(error_symbol);
|
128
|
+
return self;
|
129
|
+
}
|
130
|
+
|
131
|
+
//------------------------------------------------------------------------------
|
132
|
+
|
133
|
+
VALUE
|
134
|
+
method_sooth_native_observe(VALUE self, VALUE bigram, VALUE symbol)
|
135
|
+
{
|
136
|
+
SoothPredictor * predictor = NULL;
|
137
|
+
Check_Type(symbol, T_FIXNUM);
|
138
|
+
Check_Type(bigram, T_ARRAY);
|
139
|
+
if (RARRAY_LEN(bigram) != 2)
|
140
|
+
{
|
141
|
+
rb_raise(rb_eTypeError, "bigram must be an array of exactly two symbols");
|
142
|
+
}
|
143
|
+
Check_Type(RARRAY_PTR(bigram)[0], T_FIXNUM);
|
144
|
+
Check_Type(RARRAY_PTR(bigram)[1], T_FIXNUM);
|
145
|
+
Data_Get_Struct(self, SoothPredictor, predictor);
|
146
|
+
uint32_t c_bigram[2] = {NUM2UINT(RARRAY_PTR(bigram)[0]), NUM2UINT(RARRAY_PTR(bigram)[1])};
|
147
|
+
uint32_t count = sooth_predictor_observe(predictor, c_bigram, NUM2UINT(symbol));
|
148
|
+
return UINT2NUM(count);
|
149
|
+
}
|
150
|
+
|
151
|
+
//------------------------------------------------------------------------------
|
152
|
+
|
153
|
+
VALUE
|
154
|
+
method_sooth_native_count(VALUE self, VALUE bigram)
|
155
|
+
{
|
156
|
+
SoothPredictor * predictor = NULL;
|
157
|
+
Check_Type(bigram, T_ARRAY);
|
158
|
+
if (RARRAY_LEN(bigram) != 2)
|
159
|
+
{
|
160
|
+
rb_raise(rb_eTypeError, "bigram must be an array of exactly two symbols");
|
161
|
+
}
|
162
|
+
Check_Type(RARRAY_PTR(bigram)[0], T_FIXNUM);
|
163
|
+
Check_Type(RARRAY_PTR(bigram)[1], T_FIXNUM);
|
164
|
+
Data_Get_Struct(self, SoothPredictor, predictor);
|
165
|
+
uint32_t c_bigram[2] = {NUM2UINT(RARRAY_PTR(bigram)[0]), NUM2UINT(RARRAY_PTR(bigram)[1])};
|
166
|
+
uint64_t count = sooth_predictor_count(predictor, c_bigram);
|
167
|
+
return UINT2NUM(count);
|
168
|
+
}
|
169
|
+
|
170
|
+
//------------------------------------------------------------------------------
|
171
|
+
|
172
|
+
VALUE
|
173
|
+
method_sooth_native_select(VALUE self, VALUE bigram, VALUE limit)
|
174
|
+
{
|
175
|
+
SoothPredictor * predictor = NULL;
|
176
|
+
Check_Type(limit, T_FIXNUM);
|
177
|
+
Check_Type(bigram, T_ARRAY);
|
178
|
+
if (RARRAY_LEN(bigram) != 2)
|
179
|
+
{
|
180
|
+
rb_raise(rb_eTypeError, "bigram must be an array of exactly two symbols");
|
181
|
+
}
|
182
|
+
Check_Type(RARRAY_PTR(bigram)[0], T_FIXNUM);
|
183
|
+
Check_Type(RARRAY_PTR(bigram)[1], T_FIXNUM);
|
184
|
+
Data_Get_Struct(self, SoothPredictor, predictor);
|
185
|
+
uint32_t c_bigram[2] = {NUM2UINT(RARRAY_PTR(bigram)[0]), NUM2UINT(RARRAY_PTR(bigram)[1])};
|
186
|
+
uint32_t symbol = sooth_predictor_select(predictor, c_bigram, NUM2UINT(limit));
|
187
|
+
return UINT2NUM(symbol);
|
188
|
+
}
|
189
|
+
|
190
|
+
//==============================================================================
|
@@ -0,0 +1,21 @@
|
|
1
|
+
#ifndef SOOTH_CONTEXT_H
|
2
|
+
#define SOOTH_CONTEXT_H
|
3
|
+
|
4
|
+
//==============================================================================
|
5
|
+
|
6
|
+
#include <stdint.h>
|
7
|
+
|
8
|
+
typedef struct
|
9
|
+
{
|
10
|
+
uint32_t bigram[2];
|
11
|
+
uint64_t count;
|
12
|
+
uint32_t statistics_size;
|
13
|
+
uint64_t statistics_offset;
|
14
|
+
}
|
15
|
+
SoothContext;
|
16
|
+
|
17
|
+
//------------------------------------------------------------------------------
|
18
|
+
|
19
|
+
//==============================================================================
|
20
|
+
|
21
|
+
#endif
|
@@ -0,0 +1,257 @@
|
|
1
|
+
//==============================================================================
|
2
|
+
|
3
|
+
#include <stdlib.h>
|
4
|
+
#include <string.h>
|
5
|
+
|
6
|
+
#include "sooth_predictor.h"
|
7
|
+
|
8
|
+
//------------------------------------------------------------------------------
|
9
|
+
|
10
|
+
SoothPredictor *
|
11
|
+
sooth_predictor_init()
|
12
|
+
{
|
13
|
+
SoothPredictor * predictor = malloc(sizeof(SoothPredictor));
|
14
|
+
|
15
|
+
if (predictor == NULL)
|
16
|
+
{
|
17
|
+
return NULL;
|
18
|
+
}
|
19
|
+
|
20
|
+
predictor->error_symbol = 0;
|
21
|
+
|
22
|
+
predictor->contexts = NULL;
|
23
|
+
predictor->contexts_size = 0;
|
24
|
+
|
25
|
+
predictor->statistics = NULL;
|
26
|
+
predictor->statistics_size = 0;
|
27
|
+
|
28
|
+
return predictor;
|
29
|
+
}
|
30
|
+
|
31
|
+
//------------------------------------------------------------------------------
|
32
|
+
|
33
|
+
void
|
34
|
+
sooth_predictor_free(SoothPredictor * predictor)
|
35
|
+
{
|
36
|
+
free(predictor->contexts);
|
37
|
+
free(predictor->statistics);
|
38
|
+
|
39
|
+
predictor->contexts = NULL;
|
40
|
+
predictor->contexts_size = 0;
|
41
|
+
|
42
|
+
predictor->statistics = NULL;
|
43
|
+
predictor->statistics_size = 0;
|
44
|
+
|
45
|
+
free(predictor);
|
46
|
+
}
|
47
|
+
|
48
|
+
//------------------------------------------------------------------------------
|
49
|
+
|
50
|
+
void
|
51
|
+
sooth_predictor_save(const char * const filename, SoothPredictor * predictor)
|
52
|
+
{
|
53
|
+
}
|
54
|
+
|
55
|
+
//------------------------------------------------------------------------------
|
56
|
+
|
57
|
+
SoothPredictor *
|
58
|
+
sooth_predictor_load(const char * const filename)
|
59
|
+
{
|
60
|
+
return NULL;
|
61
|
+
}
|
62
|
+
|
63
|
+
//------------------------------------------------------------------------------
|
64
|
+
SoothContext *
|
65
|
+
sooth_predictor_find_context(SoothPredictor * predictor, uint32_t bigram[2])
|
66
|
+
{
|
67
|
+
SoothContext * context = NULL;
|
68
|
+
uint64_t mid = 0;
|
69
|
+
|
70
|
+
if (predictor->contexts_size > 0)
|
71
|
+
{
|
72
|
+
uint64_t low = 0;
|
73
|
+
uint64_t high = predictor->contexts_size - 1;
|
74
|
+
|
75
|
+
while (low <= high)
|
76
|
+
{
|
77
|
+
mid = low + (high - low) / 2;
|
78
|
+
context = &(predictor->contexts[mid]);
|
79
|
+
if (context->bigram[0] < bigram[0] || context->bigram[0] == bigram[0] && context->bigram[1] < bigram[1])
|
80
|
+
{
|
81
|
+
low = mid + 1;
|
82
|
+
}
|
83
|
+
else if (context->bigram[0] > bigram[0] || context->bigram[0] == bigram[0] && context->bigram[1] > bigram[1])
|
84
|
+
{
|
85
|
+
if (mid == 0)
|
86
|
+
{
|
87
|
+
break;
|
88
|
+
}
|
89
|
+
high = mid - 1;
|
90
|
+
}
|
91
|
+
else
|
92
|
+
{
|
93
|
+
return context;
|
94
|
+
}
|
95
|
+
}
|
96
|
+
|
97
|
+
mid = low;
|
98
|
+
}
|
99
|
+
|
100
|
+
predictor->contexts_size += 1;
|
101
|
+
SoothContext * new_memory = realloc(predictor->contexts, sizeof(SoothContext) * predictor->contexts_size);
|
102
|
+
if (new_memory == NULL)
|
103
|
+
{
|
104
|
+
return NULL;
|
105
|
+
}
|
106
|
+
predictor->contexts = new_memory;
|
107
|
+
|
108
|
+
if ((mid + 1) < predictor->contexts_size)
|
109
|
+
{
|
110
|
+
SoothContext * src = &(predictor->contexts[mid]);
|
111
|
+
SoothContext * dest = &(predictor->contexts[mid+1]);
|
112
|
+
(void)memmove(dest, src, sizeof(SoothContext) * (predictor->contexts_size - mid - 1));
|
113
|
+
}
|
114
|
+
|
115
|
+
context = &(predictor->contexts[mid]);
|
116
|
+
context->bigram[0] = bigram[0];
|
117
|
+
context->bigram[1] = bigram[1];
|
118
|
+
context->count = 0;
|
119
|
+
context->statistics_size = 0;
|
120
|
+
|
121
|
+
return context;
|
122
|
+
}
|
123
|
+
|
124
|
+
//------------------------------------------------------------------------------
|
125
|
+
|
126
|
+
SoothStatistic *
|
127
|
+
sooth_predictor_find_statistic(SoothPredictor * predictor, SoothContext * context, uint32_t symbol)
|
128
|
+
{
|
129
|
+
SoothStatistic * statistic = NULL;
|
130
|
+
uint64_t mid = 0;
|
131
|
+
|
132
|
+
if (context->statistics_size > 0)
|
133
|
+
{
|
134
|
+
uint64_t low = 0;
|
135
|
+
uint64_t high = context->statistics_size - 1;
|
136
|
+
|
137
|
+
while (low <= high)
|
138
|
+
{
|
139
|
+
mid = low + (high - low) / 2;
|
140
|
+
statistic = &(predictor->statistics[mid + context->statistics_offset]);
|
141
|
+
if (statistic->symbol < symbol)
|
142
|
+
{
|
143
|
+
low = mid + 1;
|
144
|
+
}
|
145
|
+
else if (statistic->symbol > symbol)
|
146
|
+
{
|
147
|
+
if (mid == 0)
|
148
|
+
{
|
149
|
+
break;
|
150
|
+
}
|
151
|
+
high = mid - 1;
|
152
|
+
}
|
153
|
+
else
|
154
|
+
{
|
155
|
+
return statistic;
|
156
|
+
}
|
157
|
+
}
|
158
|
+
|
159
|
+
mid = low;
|
160
|
+
}
|
161
|
+
|
162
|
+
if (context->statistics_size == 0)
|
163
|
+
{
|
164
|
+
context->statistics_offset = predictor->statistics_size;
|
165
|
+
}
|
166
|
+
context->statistics_size += 1;
|
167
|
+
mid += context -> statistics_offset;
|
168
|
+
|
169
|
+
predictor->statistics_size += 1;
|
170
|
+
SoothStatistic * new_memory = realloc(predictor->statistics, sizeof(SoothStatistic) * predictor->statistics_size);
|
171
|
+
if (new_memory == NULL)
|
172
|
+
{
|
173
|
+
return NULL;
|
174
|
+
}
|
175
|
+
predictor->statistics = new_memory;
|
176
|
+
|
177
|
+
if ((mid + 1) < predictor->statistics_size)
|
178
|
+
{
|
179
|
+
SoothStatistic * src = &(predictor->statistics[mid]);
|
180
|
+
SoothStatistic * dest = &(predictor->statistics[mid+1]);
|
181
|
+
(void)memmove(dest, src, sizeof(SoothStatistic) * (predictor->statistics_size - mid - 1));
|
182
|
+
}
|
183
|
+
|
184
|
+
statistic = &(predictor->statistics[mid]);
|
185
|
+
statistic->symbol = symbol;
|
186
|
+
statistic->count = 0;
|
187
|
+
|
188
|
+
return statistic;
|
189
|
+
}
|
190
|
+
|
191
|
+
//------------------------------------------------------------------------------
|
192
|
+
|
193
|
+
uint32_t
|
194
|
+
sooth_predictor_observe(SoothPredictor * predictor, uint32_t bigram[2], uint32_t symbol)
|
195
|
+
{
|
196
|
+
SoothContext * context = sooth_predictor_find_context(predictor, bigram);
|
197
|
+
|
198
|
+
if (context == NULL)
|
199
|
+
{
|
200
|
+
return 0;
|
201
|
+
}
|
202
|
+
|
203
|
+
SoothStatistic * statistic = sooth_predictor_find_statistic(predictor, context, symbol);
|
204
|
+
|
205
|
+
if (statistic == NULL)
|
206
|
+
{
|
207
|
+
return 0;
|
208
|
+
}
|
209
|
+
|
210
|
+
statistic->count += 1;
|
211
|
+
context->count += 1;
|
212
|
+
|
213
|
+
return statistic->count;
|
214
|
+
}
|
215
|
+
|
216
|
+
//------------------------------------------------------------------------------
|
217
|
+
|
218
|
+
uint64_t
|
219
|
+
sooth_predictor_count(SoothPredictor * predictor, uint32_t bigram[2])
|
220
|
+
{
|
221
|
+
SoothContext * context = sooth_predictor_find_context(predictor, bigram);
|
222
|
+
|
223
|
+
if (context == NULL)
|
224
|
+
{
|
225
|
+
return 0;
|
226
|
+
}
|
227
|
+
|
228
|
+
return context->count;
|
229
|
+
}
|
230
|
+
|
231
|
+
//------------------------------------------------------------------------------
|
232
|
+
|
233
|
+
uint32_t
|
234
|
+
sooth_predictor_select(SoothPredictor * predictor, uint32_t bigram[2], uint64_t limit)
|
235
|
+
{
|
236
|
+
SoothContext * context = sooth_predictor_find_context(predictor, bigram);
|
237
|
+
|
238
|
+
if (context == NULL || limit == 0)
|
239
|
+
{
|
240
|
+
return predictor->error_symbol;
|
241
|
+
}
|
242
|
+
|
243
|
+
for (uint64_t i = 0; i < context->statistics_size; ++i)
|
244
|
+
{
|
245
|
+
SoothStatistic statistic = predictor->statistics[context->statistics_offset + i];
|
246
|
+
if (limit > statistic.count)
|
247
|
+
{
|
248
|
+
limit -= statistic.count;
|
249
|
+
continue;
|
250
|
+
}
|
251
|
+
return statistic.symbol;
|
252
|
+
}
|
253
|
+
|
254
|
+
return predictor->error_symbol;
|
255
|
+
}
|
256
|
+
|
257
|
+
//==============================================================================
|
@@ -0,0 +1,33 @@
|
|
1
|
+
#ifndef SOOTH_PREDICTOR_H
|
2
|
+
#define SOOTH_PREDICTOR_H
|
3
|
+
|
4
|
+
//==============================================================================
|
5
|
+
|
6
|
+
#include <stdint.h>
|
7
|
+
|
8
|
+
#include "sooth_context.h"
|
9
|
+
#include "sooth_statistic.h"
|
10
|
+
|
11
|
+
typedef struct
|
12
|
+
{
|
13
|
+
uint32_t error_symbol;
|
14
|
+
uint64_t contexts_size;
|
15
|
+
SoothContext * contexts;
|
16
|
+
uint64_t statistics_size;
|
17
|
+
SoothStatistic * statistics;
|
18
|
+
}
|
19
|
+
SoothPredictor;
|
20
|
+
|
21
|
+
//------------------------------------------------------------------------------
|
22
|
+
|
23
|
+
SoothPredictor * sooth_predictor_init();
|
24
|
+
void sooth_predictor_free(SoothPredictor * predictor);
|
25
|
+
void sooth_predictor_save(const char * const filename, SoothPredictor * predictor);
|
26
|
+
SoothPredictor * sooth_predictor_load(const char * const filename);
|
27
|
+
uint32_t sooth_predictor_observe(SoothPredictor * predictor, uint32_t bigram[2], uint32_t symbol);
|
28
|
+
uint64_t sooth_predictor_count(SoothPredictor * predictor, uint32_t bigram[2]);
|
29
|
+
uint32_t sooth_predictor_select(SoothPredictor * predictor, uint32_t bigram[2], uint64_t limit);
|
30
|
+
|
31
|
+
//==============================================================================
|
32
|
+
|
33
|
+
#endif
|
@@ -0,0 +1,19 @@
|
|
1
|
+
#ifndef SOOTH_STATISTIC_H
|
2
|
+
#define SOOTH_STATISTIC_H
|
3
|
+
|
4
|
+
//==============================================================================
|
5
|
+
|
6
|
+
#include <stdint.h>
|
7
|
+
|
8
|
+
typedef struct
|
9
|
+
{
|
10
|
+
uint32_t symbol;
|
11
|
+
uint32_t count;
|
12
|
+
}
|
13
|
+
SoothStatistic;
|
14
|
+
|
15
|
+
//------------------------------------------------------------------------------
|
16
|
+
|
17
|
+
//==============================================================================
|
18
|
+
|
19
|
+
#endif
|
data/lib/sooth.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'sooth_native'
|
data/sooth.gemspec
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
# stub: sooth 0.1.0 ruby lib
|
6
|
+
# stub: ext/sooth_native/extconf.rb
|
7
|
+
|
8
|
+
Gem::Specification.new do |s|
|
9
|
+
s.name = "sooth"
|
10
|
+
s.version = "0.1.0"
|
11
|
+
|
12
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
13
|
+
s.require_paths = ["lib"]
|
14
|
+
s.authors = ["Jason Hutchens"]
|
15
|
+
s.date = "2014-12-10"
|
16
|
+
s.description = "Does what it says on the box"
|
17
|
+
s.email = "jasonhutchens@gmail.com"
|
18
|
+
s.extensions = ["ext/sooth_native/extconf.rb"]
|
19
|
+
s.extra_rdoc_files = [
|
20
|
+
"README.md"
|
21
|
+
]
|
22
|
+
s.files = [
|
23
|
+
"Gemfile",
|
24
|
+
"Gemfile.lock",
|
25
|
+
"README.md",
|
26
|
+
"Rakefile",
|
27
|
+
"UNLICENSE",
|
28
|
+
"VERSION",
|
29
|
+
"ext/sooth_native/extconf.rb",
|
30
|
+
"ext/sooth_native/native.c",
|
31
|
+
"ext/sooth_native/sooth_context.h",
|
32
|
+
"ext/sooth_native/sooth_predictor.c",
|
33
|
+
"ext/sooth_native/sooth_predictor.h",
|
34
|
+
"ext/sooth_native/sooth_statistic.h",
|
35
|
+
"lib/sooth.rb",
|
36
|
+
"sooth.gemspec",
|
37
|
+
"spec/memory_spec.rb",
|
38
|
+
"spec/predictor_spec.rb",
|
39
|
+
"spec/spec_helper.rb"
|
40
|
+
]
|
41
|
+
s.homepage = "http://github.com/jasonhutchens/sooth"
|
42
|
+
s.licenses = ["MIT"]
|
43
|
+
s.required_ruby_version = Gem::Requirement.new("~> 2.1")
|
44
|
+
s.rubygems_version = "2.4.4"
|
45
|
+
s.summary = "A small thing for generating codes for users to type into places"
|
46
|
+
|
47
|
+
if s.respond_to? :specification_version then
|
48
|
+
s.specification_version = 4
|
49
|
+
|
50
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
51
|
+
s.add_development_dependency(%q<rspec>, ["~> 3.1"])
|
52
|
+
s.add_development_dependency(%q<yard>, ["~> 0.8"])
|
53
|
+
s.add_development_dependency(%q<rdoc>, ["~> 4.1"])
|
54
|
+
s.add_development_dependency(%q<bundler>, ["~> 1.7"])
|
55
|
+
s.add_development_dependency(%q<jeweler>, ["~> 2.0"])
|
56
|
+
s.add_development_dependency(%q<simplecov>, ["~> 0.9"])
|
57
|
+
s.add_development_dependency(%q<byebug>, ["~> 3.5"])
|
58
|
+
s.add_development_dependency(%q<rake-compiler>, ["~> 0.9"])
|
59
|
+
else
|
60
|
+
s.add_dependency(%q<rspec>, ["~> 3.1"])
|
61
|
+
s.add_dependency(%q<yard>, ["~> 0.8"])
|
62
|
+
s.add_dependency(%q<rdoc>, ["~> 4.1"])
|
63
|
+
s.add_dependency(%q<bundler>, ["~> 1.7"])
|
64
|
+
s.add_dependency(%q<jeweler>, ["~> 2.0"])
|
65
|
+
s.add_dependency(%q<simplecov>, ["~> 0.9"])
|
66
|
+
s.add_dependency(%q<byebug>, ["~> 3.5"])
|
67
|
+
s.add_dependency(%q<rake-compiler>, ["~> 0.9"])
|
68
|
+
end
|
69
|
+
else
|
70
|
+
s.add_dependency(%q<rspec>, ["~> 3.1"])
|
71
|
+
s.add_dependency(%q<yard>, ["~> 0.8"])
|
72
|
+
s.add_dependency(%q<rdoc>, ["~> 4.1"])
|
73
|
+
s.add_dependency(%q<bundler>, ["~> 1.7"])
|
74
|
+
s.add_dependency(%q<jeweler>, ["~> 2.0"])
|
75
|
+
s.add_dependency(%q<simplecov>, ["~> 0.9"])
|
76
|
+
s.add_dependency(%q<byebug>, ["~> 3.5"])
|
77
|
+
s.add_dependency(%q<rake-compiler>, ["~> 0.9"])
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
data/spec/memory_spec.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe Sooth::Predictor do
|
4
|
+
let(:predictor) { Sooth::Predictor.new(42) }
|
5
|
+
|
6
|
+
describe "#observe" do
|
7
|
+
it "does not segfault when sorting bigrams" do
|
8
|
+
expect(predictor.observe([3,3], 1)).to eq(1)
|
9
|
+
expect(predictor.observe([5,5], 1)).to eq(1)
|
10
|
+
expect(predictor.observe([4,4], 1)).to eq(1)
|
11
|
+
expect(predictor.observe([5,5], 1)).to eq(2)
|
12
|
+
expect(predictor.observe([3,3], 1)).to eq(2)
|
13
|
+
expect(predictor.observe([4,4], 1)).to eq(2)
|
14
|
+
expect(predictor.observe([2,2], 1)).to eq(1)
|
15
|
+
expect(predictor.observe([4,4], 1)).to eq(3)
|
16
|
+
expect(predictor.observe([2,2], 1)).to eq(2)
|
17
|
+
expect(predictor.observe([3,3], 1)).to eq(3)
|
18
|
+
expect(predictor.observe([5,5], 1)).to eq(3)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "does not segfault when sorting symbols" do
|
22
|
+
expect(predictor.observe([1,2], 3)).to eq(1)
|
23
|
+
expect(predictor.observe([1,2], 5)).to eq(1)
|
24
|
+
expect(predictor.observe([1,2], 4)).to eq(1)
|
25
|
+
expect(predictor.observe([1,2], 5)).to eq(2)
|
26
|
+
expect(predictor.observe([1,2], 3)).to eq(2)
|
27
|
+
expect(predictor.observe([1,2], 4)).to eq(2)
|
28
|
+
expect(predictor.observe([1,2], 2)).to eq(1)
|
29
|
+
expect(predictor.observe([1,2], 4)).to eq(3)
|
30
|
+
expect(predictor.observe([1,2], 2)).to eq(2)
|
31
|
+
expect(predictor.observe([1,2], 3)).to eq(3)
|
32
|
+
expect(predictor.observe([1,2], 5)).to eq(3)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe Sooth::Predictor do
|
4
|
+
let(:predictor) { Sooth::Predictor.new(42) }
|
5
|
+
|
6
|
+
describe "#observe" do
|
7
|
+
it "increments observation counts" do
|
8
|
+
expect(predictor.observe([1,2], 3)).to eq(1)
|
9
|
+
expect(predictor.observe([1,2], 3)).to eq(2)
|
10
|
+
expect(predictor.observe([1,2], 3)).to eq(3)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "properly sorts and finds bigrams" do
|
14
|
+
expect(predictor.observe([2,1], 3)).to eq(1)
|
15
|
+
expect(predictor.observe([1,3], 2)).to eq(1)
|
16
|
+
expect(predictor.observe([3,2], 1)).to eq(1)
|
17
|
+
expect(predictor.observe([1,3], 2)).to eq(2)
|
18
|
+
expect(predictor.observe([2,1], 3)).to eq(2)
|
19
|
+
expect(predictor.observe([3,2], 1)).to eq(2)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "#count" do
|
24
|
+
it "returns a zero count for an unobserved bigram" do
|
25
|
+
expect(predictor.count([1,2])).to eq(0)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "returns the total count for an observed bigram" do
|
29
|
+
predictor.observe([1,2], 2)
|
30
|
+
predictor.observe([1,2], 1)
|
31
|
+
predictor.observe([1,2], 4)
|
32
|
+
predictor.observe([1,2], 3)
|
33
|
+
predictor.observe([1,2], 0)
|
34
|
+
predictor.observe([1,2], 1)
|
35
|
+
predictor.observe([1,2], 4)
|
36
|
+
expect(predictor.count([1,2])).to eq(7)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "#select" do
|
41
|
+
it "returns the error symbol for an unobserved bigram" do
|
42
|
+
expect(predictor.select([1,2], 1)).to eq(42)
|
43
|
+
end
|
44
|
+
|
45
|
+
it "returns the correct symbol for an observed bigram" do
|
46
|
+
predictor.observe([1,2], 4)
|
47
|
+
predictor.observe([1,2], 3)
|
48
|
+
predictor.observe([1,2], 4)
|
49
|
+
predictor.observe([1,2], 5)
|
50
|
+
expect(predictor.select([1,2], 1)).to eq(3)
|
51
|
+
expect(predictor.select([1,2], 2)).to eq(4)
|
52
|
+
expect(predictor.select([1,2], 3)).to eq(4)
|
53
|
+
expect(predictor.select([1,2], 4)).to eq(5)
|
54
|
+
end
|
55
|
+
|
56
|
+
it "returns the error symbol for a limit that is out of range" do
|
57
|
+
predictor.observe([1,2], 4)
|
58
|
+
predictor.observe([1,2], 3)
|
59
|
+
predictor.observe([1,2], 5)
|
60
|
+
expect(predictor.select([1,2], 0)).to eq(42)
|
61
|
+
expect(predictor.select([1,2], 4)).to eq(42)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'simplecov'
|
2
|
+
|
3
|
+
module SimpleCov::Configuration
|
4
|
+
def clean_filters
|
5
|
+
@filters = []
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
SimpleCov.configure do
|
10
|
+
clean_filters
|
11
|
+
load_profile 'test_frameworks'
|
12
|
+
end
|
13
|
+
|
14
|
+
ENV["COVERAGE"] && SimpleCov.start do
|
15
|
+
add_filter "/.rvm/"
|
16
|
+
end
|
17
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
18
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
19
|
+
|
20
|
+
require 'rspec'
|
21
|
+
|
22
|
+
require 'sooth'
|
23
|
+
|
24
|
+
# Requires supporting files with custom matchers and macros, etc,
|
25
|
+
# in ./support/ and its subdirectories.
|
26
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
27
|
+
|
28
|
+
RSpec.configure do |config|
|
29
|
+
|
30
|
+
end
|
metadata
ADDED
@@ -0,0 +1,174 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sooth
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jason Hutchens
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-12-10 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rspec
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.1'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.1'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: yard
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.8'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.8'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rdoc
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '4.1'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '4.1'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: bundler
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.7'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.7'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: jeweler
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '2.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '2.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: simplecov
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0.9'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0.9'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: byebug
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '3.5'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '3.5'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rake-compiler
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0.9'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0.9'
|
125
|
+
description: Does what it says on the box
|
126
|
+
email: jasonhutchens@gmail.com
|
127
|
+
executables: []
|
128
|
+
extensions:
|
129
|
+
- ext/sooth_native/extconf.rb
|
130
|
+
extra_rdoc_files:
|
131
|
+
- README.md
|
132
|
+
files:
|
133
|
+
- Gemfile
|
134
|
+
- Gemfile.lock
|
135
|
+
- README.md
|
136
|
+
- Rakefile
|
137
|
+
- UNLICENSE
|
138
|
+
- VERSION
|
139
|
+
- ext/sooth_native/extconf.rb
|
140
|
+
- ext/sooth_native/native.c
|
141
|
+
- ext/sooth_native/sooth_context.h
|
142
|
+
- ext/sooth_native/sooth_predictor.c
|
143
|
+
- ext/sooth_native/sooth_predictor.h
|
144
|
+
- ext/sooth_native/sooth_statistic.h
|
145
|
+
- lib/sooth.rb
|
146
|
+
- sooth.gemspec
|
147
|
+
- spec/memory_spec.rb
|
148
|
+
- spec/predictor_spec.rb
|
149
|
+
- spec/spec_helper.rb
|
150
|
+
homepage: http://github.com/jasonhutchens/sooth
|
151
|
+
licenses:
|
152
|
+
- MIT
|
153
|
+
metadata: {}
|
154
|
+
post_install_message:
|
155
|
+
rdoc_options: []
|
156
|
+
require_paths:
|
157
|
+
- lib
|
158
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
159
|
+
requirements:
|
160
|
+
- - "~>"
|
161
|
+
- !ruby/object:Gem::Version
|
162
|
+
version: '2.1'
|
163
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
164
|
+
requirements:
|
165
|
+
- - ">="
|
166
|
+
- !ruby/object:Gem::Version
|
167
|
+
version: '0'
|
168
|
+
requirements: []
|
169
|
+
rubyforge_project:
|
170
|
+
rubygems_version: 2.4.4
|
171
|
+
signing_key:
|
172
|
+
specification_version: 4
|
173
|
+
summary: A small thing for generating codes for users to type into places
|
174
|
+
test_files: []
|