korekto 1.6.210407 → 2.0.231231
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +95 -0
- data/bin/korekto +45 -21
- data/lib/korekto/main.rb +72 -52
- data/lib/korekto/statement.rb +57 -51
- data/lib/korekto/statements.rb +13 -19
- data/lib/korekto/symbols.rb +39 -41
- data/lib/korekto/syntax.rb +5 -2
- data/lib/korekto.rb +46 -9
- data/rplugin/ruby/korekto.rb +28 -20
- data/start/korekto/syntax/korekto.vim +30 -20
- metadata +118 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3b6d303ce45a7dc14c9dd65923f46d5c78728a7f90b5fa177cacce76a08e032f
|
4
|
+
data.tar.gz: 780b4c3d11b968a6183fe285e00c8d67b976691465694aa3ded19bde58e81d35
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 78b31ad18094000a9de76669b6d7fac178fa547b715e41705267e75c459fdf8e99b5d94ce310526f3991c9e3f5db9d6c92189d4a369bfd33df77b0c1bbd12969
|
7
|
+
data.tar.gz: 1efc9551d93da2507a736d725c5c043b4b710ced992b3d419cc0ee4cf5a10fa85dfd3700be81dd336869cb19808d8fc84d5b7482fb7604cff0d8cc96fe6e5754
|
data/README.md
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
# Korekto
|
2
|
+
|
3
|
+
* [VERSION 2.0.231231](https://github.com/carlosjhr64/korekto/releases)
|
4
|
+
* [github](https://www.github.com/carlosjhr64/korekto)
|
5
|
+
* [rubygems](https://rubygems.org/gems/korekto)
|
6
|
+
|
7
|
+
## DESCRIPTION:
|
8
|
+
|
9
|
+
A general proof checker.
|
10
|
+
|
11
|
+
Works with [neovim](https://github.com/neovim/neovim).
|
12
|
+
|
13
|
+
## INSTALL:
|
14
|
+
```shell
|
15
|
+
$ gem install korekto
|
16
|
+
$ korekto --install
|
17
|
+
$ ### And if missing:
|
18
|
+
$ gem install neovim # Provides neovim-ruby-host
|
19
|
+
```
|
20
|
+
## SYNOPSIS:
|
21
|
+
```korekto
|
22
|
+
### Patterns ###
|
23
|
+
# 'Hello World!'.scan(/\w+|\S|\s/) #=> ["Hello", " ", "World", "!"]
|
24
|
+
! scanner: '\w+|\S|\s'
|
25
|
+
! .Newline /\n/
|
26
|
+
! .Newline {;}
|
27
|
+
! Variables /\w+/
|
28
|
+
! Variables {V W}
|
29
|
+
### Acceptance patterns ###
|
30
|
+
There might be V. #L1 Let 1: There might be .
|
31
|
+
# /If I see (\w+), then I'll probably see (\w+).\nI see \1\nI'll probably see \2/
|
32
|
+
If I see V, then I'll probably see W.;I see V.;I'll probably see W. #I2 Modus ponens: If I see , then ' ll probably
|
33
|
+
### Argument ###
|
34
|
+
There might be Cows. #S3/L1 Let 1: Cows
|
35
|
+
There might be Chickens. #S4/L1 Let 1: Chickens
|
36
|
+
If I see Cows, then I'll probably see Chickens. #P5
|
37
|
+
I see Cows. #P6
|
38
|
+
I'll probably see Chickens. #C7/I2,P5,P6 Modus ponens
|
39
|
+
```
|
40
|
+
## Examples
|
41
|
+
|
42
|
+
* [Tutorial](examples/Tutorial.md)
|
43
|
+
* [ABC music notation](examples/ABC.md)
|
44
|
+
* [Computation](examples/Computation.md)
|
45
|
+
* [Dx x^x](examples/Dxx.md)
|
46
|
+
* [Sqrt(2) is irrational! (Classic Proof)](examples/Sqrt2.md)
|
47
|
+
* [Squash Function](examples/Squash.md)
|
48
|
+
|
49
|
+
## Help:
|
50
|
+
```shell
|
51
|
+
$ korekto --help
|
52
|
+
Usage:
|
53
|
+
korekto [:options+]
|
54
|
+
Options:
|
55
|
+
-h --help
|
56
|
+
-v --version
|
57
|
+
--scrape Scrape Korekto lines
|
58
|
+
--trace Show trace of each line, not just edits and errors
|
59
|
+
--patch Allow monkey patching in stdin
|
60
|
+
--install Installs the korekto neovim ruby plugin
|
61
|
+
--readme Open korekto github page
|
62
|
+
--heap=SIZE Set heap size (default: 13)
|
63
|
+
Types:
|
64
|
+
SIZE /^\d+$/
|
65
|
+
Exclusive:
|
66
|
+
scrape trace install readme
|
67
|
+
# Example usage:
|
68
|
+
# cat MARKDOWN.md | korekto
|
69
|
+
# korekto < MARKDOWN.md
|
70
|
+
```
|
71
|
+
## LICENSE:
|
72
|
+
|
73
|
+
Copyright (c) 2023 CarlosJHR64
|
74
|
+
|
75
|
+
Permission is hereby granted, free of charge,
|
76
|
+
to any person obtaining a copy of this software and
|
77
|
+
associated documentation files (the "Software"),
|
78
|
+
to deal in the Software without restriction,
|
79
|
+
including without limitation the rights
|
80
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
81
|
+
copies of the Software, and
|
82
|
+
to permit persons to whom the Software is furnished to do so,
|
83
|
+
subject to the following conditions:
|
84
|
+
|
85
|
+
The above copyright notice and this permission notice
|
86
|
+
shall be included in all copies or substantial portions of the Software.
|
87
|
+
|
88
|
+
THE SOFTWARE IS PROVIDED "AS IS",
|
89
|
+
WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
90
|
+
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
91
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
92
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
93
|
+
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
94
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
|
95
|
+
THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/bin/korekto
CHANGED
@@ -1,38 +1,62 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
require '
|
3
|
-
|
4
|
-
OPTIONS = HelpParser['1.6.210407', <<HELP]
|
5
|
-
Usage:
|
6
|
-
korekto [:options]
|
7
|
-
Options:
|
8
|
-
-h --help
|
9
|
-
-v --version
|
10
|
-
--edits \tShow only needed edits
|
11
|
-
--install \tInstalls the korekto neovim ruby plugin
|
12
|
-
--readme \tOpen korekto github page
|
13
|
-
# Example usage:
|
14
|
-
# cat MARKDOWN.md | korekto
|
15
|
-
# korekto < MARKDOWN.md
|
16
|
-
HELP
|
2
|
+
require 'korekto'
|
17
3
|
|
18
|
-
|
4
|
+
def do_install
|
5
|
+
local_pack = File.expand_path '~/.local/share/nvim/site/pack'
|
6
|
+
config_nvim = File.expand_path '~/.config/nvim'
|
7
|
+
unless File.directory?(local_pack) && File.directory?(config_nvim)
|
8
|
+
warn "Expected directories:\n\t#{local_pack}\n\t#{config_nvim}"
|
9
|
+
exit 78 # EX_CONFIG
|
10
|
+
end
|
19
11
|
require 'fileutils'
|
20
12
|
# pack
|
21
|
-
dest = File.
|
13
|
+
dest = File.join(local_pack, 'korekto')
|
22
14
|
FileUtils.mkdir_p dest
|
23
15
|
src = File.join File.dirname(__dir__), 'start'
|
24
16
|
FileUtils.cp_r src, dest
|
25
17
|
# rplugin
|
26
|
-
dest =
|
18
|
+
dest = config_nvim
|
27
19
|
src = File.join File.dirname(__dir__), 'rplugin'
|
28
20
|
FileUtils.cp_r src, dest
|
29
21
|
system "nvim -c ':UpdateRemotePlugins|:quit' > /dev/null"
|
30
22
|
exit
|
31
23
|
end
|
32
|
-
|
33
|
-
|
24
|
+
|
25
|
+
def spawn_readme
|
26
|
+
Process.detach spawn('xdg-open', 'https://www.github.com/carlosjhr64/korekto',
|
27
|
+
%i[out err] => '/dev/null')
|
34
28
|
exit
|
35
29
|
end
|
36
30
|
|
37
|
-
|
31
|
+
def handle_options
|
32
|
+
require 'help_parser'
|
33
|
+
options = HelpParser[Korekto::VERSION, <<~HELP]
|
34
|
+
Usage:
|
35
|
+
korekto [:options+]
|
36
|
+
Options:
|
37
|
+
-h --help
|
38
|
+
-v --version
|
39
|
+
--scrape \tScrape Korekto lines
|
40
|
+
--trace \tShow trace of each line, not just edits and errors
|
41
|
+
--patch \tAllow monkey patching in stdin
|
42
|
+
--install \tInstalls the korekto neovim ruby plugin
|
43
|
+
--readme \tOpen korekto github page
|
44
|
+
--heap=SIZE \tSet heap size (default: #{Korekto.heap})
|
45
|
+
Types:
|
46
|
+
SIZE /^\\d+$/
|
47
|
+
Exclusive:
|
48
|
+
scrape trace install readme
|
49
|
+
# Example usage:
|
50
|
+
# cat MARKDOWN.md | korekto
|
51
|
+
# korekto < MARKDOWN.md
|
52
|
+
HELP
|
53
|
+
do_install if options.install?
|
54
|
+
spawn_readme if options.readme?
|
55
|
+
Korekto.scrape = options.scrape?
|
56
|
+
Korekto.trace = options.trace?
|
57
|
+
Korekto.patch = options.patch?
|
58
|
+
Korekto.heap = options.heap.to_i if options.heap?
|
59
|
+
end
|
60
|
+
|
61
|
+
handle_options unless ARGV.empty?
|
38
62
|
Korekto.run
|
data/lib/korekto/main.rb
CHANGED
@@ -1,12 +1,14 @@
|
|
1
1
|
module Korekto
|
2
2
|
class Main
|
3
|
-
|
3
|
+
# rubocop: disable Layout/LineLength
|
4
|
+
MD_STATEMENT_CODE_TITLE = %r{^(?<statement>.*)\s#(?<code>[A-Z](\d+(\.\w+)?(/[\w,.]+)?)?)(\s+(?<title>[^#]+))?$}
|
4
5
|
MD_FILENAME = %r{^< (?<filename>[/\w\-.]+)$}
|
5
6
|
MD_KLASS_METHOD_DEFINITION = /^(?<klass>::[A-Z]\w+)#(?<method>\w+)(?<definition>[^=]*=.+)$/ # patch
|
6
7
|
MD_RULE = /^[?] (?<rule>\S.*)$/
|
7
|
-
MD_TYPE_PATTERN = %r{^! (?<type>\S+)\s
|
8
|
-
MD_TYPE_VARIABLES = /^! (?<type>\S+)\s
|
9
|
-
MD_KEY_VALUE = /^! (?<key>\w+):\s
|
8
|
+
MD_TYPE_PATTERN = %r{^! (?<type>\S+)\s+/(?<pattern>.*)/$}
|
9
|
+
MD_TYPE_VARIABLES = /^! (?<type>\S+)\s+\{(?<variables>\S+( \S+)*)\}$/
|
10
|
+
MD_KEY_VALUE = /^! (?<key>\w+):\s+'(?<value>.*)'$/
|
11
|
+
# rubocop: enable Layout/LineLength
|
10
12
|
|
11
13
|
M_FENCE = /^```\s*$/
|
12
14
|
M_COMMENT_LINE = /^\s*#/
|
@@ -18,12 +20,12 @@ class Main
|
|
18
20
|
@imports.push @filename.freeze
|
19
21
|
@line,@active = nil,false
|
20
22
|
@section = File.basename(@filename,'.*')
|
21
|
-
@m_fence_korekto = /^```korekto$/
|
23
|
+
@m_fence_korekto = /^```korekto$/ # default fence
|
22
24
|
end
|
23
25
|
|
24
26
|
def type_pattern(type, pattern)
|
25
27
|
t2p = @statements.symbols.t2p
|
26
|
-
raise Error, "type #{type} in use" if t2p.
|
28
|
+
raise Error, "type #{type} in use" if t2p.key? type
|
27
29
|
t2p[type] = pattern
|
28
30
|
end
|
29
31
|
|
@@ -32,53 +34,26 @@ class Main
|
|
32
34
|
pattern = t2p[type]
|
33
35
|
raise Error, "type #{type} not defined" unless pattern
|
34
36
|
variables.each do |variable|
|
35
|
-
raise Error, "variable #{variable} in use" if v2t.
|
37
|
+
raise Error, "variable #{variable} in use" if v2t.key? variable
|
36
38
|
v2t[variable] = type
|
37
39
|
end
|
38
40
|
end
|
39
41
|
|
40
|
-
def active?
|
41
|
-
case @line
|
42
|
-
when @m_fence_korekto
|
43
|
-
raise Error, 'unexpected fence' if @active
|
44
|
-
@active = true
|
45
|
-
false
|
46
|
-
when M_FENCE
|
47
|
-
@active = false
|
48
|
-
false
|
49
|
-
else
|
50
|
-
@active and not M_COMMENT_LINE.match?(@line)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
42
|
def patch(klass, method, definition)
|
55
|
-
|
43
|
+
if Object.const_get(klass).method_defined?(method)
|
44
|
+
raise Error, "overrides: #{klass}##{method}"
|
45
|
+
end
|
46
|
+
# rubocop: disable Security/Eval
|
47
|
+
# rubocop: disable Style/DocumentDynamicEvalDefinition
|
48
|
+
# rubocop: disable Style/EvalWithLocation
|
56
49
|
eval <<~EVAL
|
57
50
|
class #{klass}
|
58
51
|
def #{method}#{definition}
|
59
52
|
end
|
60
53
|
EVAL
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
case key
|
65
|
-
when 'scanner'
|
66
|
-
@statements.symbols.set_scanner value
|
67
|
-
when 'fence'
|
68
|
-
@m_fence_korekto = Regexp.new "^```#{value}$"
|
69
|
-
when 'section'
|
70
|
-
@section = value
|
71
|
-
when 'save'
|
72
|
-
BACKUPS[value] = Marshal.dump(@statements)
|
73
|
-
when 'restore'
|
74
|
-
if backup = BACKUPS[value]
|
75
|
-
@statements = Marshal.load(backup)
|
76
|
-
else
|
77
|
-
raise Error, "nothing saved as '#{value}'"
|
78
|
-
end
|
79
|
-
else
|
80
|
-
raise Error, "key '#{key}' not implemented"
|
81
|
-
end
|
54
|
+
# rubocop: enable Style/EvalWithLocation
|
55
|
+
# rubocop: enable Style/DocumentDynamicEvalDefinition
|
56
|
+
# rubocop: enable Security/Eval
|
82
57
|
end
|
83
58
|
|
84
59
|
def preprocess?
|
@@ -89,6 +64,10 @@ class Main
|
|
89
64
|
Main.new(filename, statements:@statements, imports:@imports).run
|
90
65
|
end
|
91
66
|
when MD_KLASS_METHOD_DEFINITION
|
67
|
+
if @filename=='-' && !Korekto.patch?
|
68
|
+
# We'll trust files, but not stdin.
|
69
|
+
raise Error, 'monkey patching not allowed on stdin'
|
70
|
+
end
|
92
71
|
patch($~[:klass],$~[:method],$~[:definition])
|
93
72
|
when MD_RULE
|
94
73
|
@statements.syntax.push $~[:rule].strip
|
@@ -104,19 +83,49 @@ class Main
|
|
104
83
|
true
|
105
84
|
end
|
106
85
|
|
86
|
+
def key_value(key, value)
|
87
|
+
case key
|
88
|
+
when 'scanner'
|
89
|
+
@statements.symbols.set_scanner value
|
90
|
+
when 'fence'
|
91
|
+
@m_fence_korekto = Regexp.new "^```#{value}$" # user defined fence
|
92
|
+
when 'section'
|
93
|
+
@section = value
|
94
|
+
when 'save'
|
95
|
+
BACKUPS[value] = Marshal.dump(@statements)
|
96
|
+
when 'restore'
|
97
|
+
if (backup = BACKUPS[value])
|
98
|
+
@statements = Marshal.load(backup)
|
99
|
+
else
|
100
|
+
raise Error, "nothing saved as '#{value}'"
|
101
|
+
end
|
102
|
+
else
|
103
|
+
raise Error, "key '#{key}' not implemented"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
107
|
def parse(lines)
|
108
108
|
statement_number = line_number = 0
|
109
|
-
while @line = lines.shift
|
109
|
+
while (@line = lines.shift)
|
110
110
|
begin
|
111
111
|
line_number += 1
|
112
112
|
next unless active?
|
113
113
|
next if preprocess?
|
114
|
-
if md = MD_STATEMENT_CODE_TITLE.match
|
114
|
+
if (md = MD_STATEMENT_CODE_TITLE.match @line)
|
115
115
|
code,title = @statements.add(md[:statement].strip,
|
116
116
|
md[:code],
|
117
117
|
md[:title],
|
118
|
-
@section
|
119
|
-
|
118
|
+
@section
|
119
|
+
# Block executes if statement is new.
|
120
|
+
# Method recieves the return value.
|
121
|
+
){ statement_number += 1 }
|
122
|
+
if Korekto.scrape?
|
123
|
+
print @statements.last
|
124
|
+
print "\t##{code}"
|
125
|
+
print " #{title}" unless title.nil? || title.empty?
|
126
|
+
puts
|
127
|
+
elsif Korekto.trace? ||
|
128
|
+
(@filename=='-' && !(md[:code]==code && md[:title]==title))
|
120
129
|
puts "#{@filename}:#{line_number}:#{code}:#{title}"
|
121
130
|
end
|
122
131
|
else
|
@@ -125,19 +134,30 @@ class Main
|
|
125
134
|
rescue Error
|
126
135
|
puts "#{@filename}:#{line_number}:!:#{$!.message}"
|
127
136
|
exit 65
|
128
|
-
rescue
|
137
|
+
rescue StandardError
|
129
138
|
puts "#{@filename}:#{line_number}:?:#{$!.message}"
|
130
|
-
|
139
|
+
warn $!.backtrace
|
131
140
|
exit 1
|
132
141
|
end
|
133
142
|
end
|
134
143
|
end
|
135
144
|
|
136
145
|
def run
|
137
|
-
|
138
|
-
|
146
|
+
parse @filename=='-' ? $stdin.readlines(chomp: true) :
|
147
|
+
File.readlines(@filename, chomp: true)
|
148
|
+
end
|
149
|
+
|
150
|
+
# Is the current line a non-comment Korekto line?
|
151
|
+
def active?
|
152
|
+
case @line
|
153
|
+
when @m_fence_korekto
|
154
|
+
raise Error, 'unexpected fence' if @active
|
155
|
+
@active = true
|
156
|
+
false
|
157
|
+
when M_FENCE
|
158
|
+
@active = false
|
139
159
|
else
|
140
|
-
|
160
|
+
@active && !M_COMMENT_LINE.match?(@line)
|
141
161
|
end
|
142
162
|
end
|
143
163
|
end
|
data/lib/korekto/statement.rb
CHANGED
@@ -1,21 +1,26 @@
|
|
1
1
|
module Korekto
|
2
2
|
class Statement
|
3
3
|
attr_reader :code,:title,:regexp,:section,:statement_number
|
4
|
+
|
5
|
+
# rubocop: disable Metrics/ParameterLists
|
4
6
|
def initialize(statement,code,title,section,statement_number,context)
|
5
|
-
@statement,@code,@title,@section,@statement_number,@context =
|
6
|
-
statement,code,title,section,statement_number,context
|
7
|
+
@statement,@code,@title,@section,@statement_number,@context,@regexp =
|
8
|
+
statement,code,title,section,statement_number,context,nil
|
7
9
|
@statement.freeze; @section.freeze; @statement_number.freeze
|
8
|
-
|
9
|
-
@
|
10
|
+
@title = @title.split(':',2).first if @title
|
11
|
+
syntax_check unless @statement[0]=='/' &&
|
12
|
+
@statement[-1]=='/' &&
|
13
|
+
%w[A L M E I].include?(@code[0])
|
10
14
|
set_acceptance_code
|
11
15
|
@code.freeze; @title.freeze; @regexp.freeze
|
12
16
|
end
|
17
|
+
# rubocop: enable Metrics/ParameterLists
|
13
18
|
|
14
19
|
def type = @code[0]
|
15
20
|
def to_s = @statement
|
16
21
|
def to_str = @statement
|
17
22
|
def match?(statement) = @regexp.match?(statement)
|
18
|
-
def scan(regex, &
|
23
|
+
def scan(regex, &) = @statement.scan(regex, &)
|
19
24
|
def pattern? = !@regexp.nil?
|
20
25
|
def literal_regexp? = @statement[0]=='/' && @statement[-1]=='/'
|
21
26
|
|
@@ -23,8 +28,10 @@ class Statement
|
|
23
28
|
|
24
29
|
def syntax_check
|
25
30
|
@context.syntax.each do |rule|
|
26
|
-
|
27
|
-
|
31
|
+
next if @statement.instance_eval(rule)
|
32
|
+
raise Error, "syntax: #{rule}"
|
33
|
+
rescue StandardError
|
34
|
+
raise if $!.is_a? Error
|
28
35
|
raise Error, "#{$!.class}: #{rule}"
|
29
36
|
end
|
30
37
|
end
|
@@ -46,7 +53,7 @@ class Statement
|
|
46
53
|
when 'T'
|
47
54
|
tautology
|
48
55
|
when 'A', 'L'
|
49
|
-
# Axiom=>
|
56
|
+
# Axiom=>Tautology, Let=>Set,
|
50
57
|
pattern_type(0)
|
51
58
|
when 'M', 'E'
|
52
59
|
# Map=>Result, Existential=>Instantiation(X)
|
@@ -55,14 +62,12 @@ class Statement
|
|
55
62
|
# Inference=>Conclusion
|
56
63
|
pattern_type(2)
|
57
64
|
when 'W'
|
58
|
-
[
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
false
|
65
|
-
end
|
65
|
+
%w[T S R X C].any? do |code|
|
66
|
+
@code[0]=code
|
67
|
+
set_acceptance_code
|
68
|
+
true
|
69
|
+
rescue Error
|
70
|
+
false
|
66
71
|
end or raise Error, 'did not match any statement pattern'
|
67
72
|
else
|
68
73
|
raise Error, "statement type #{@code[0]} not implemented"
|
@@ -71,26 +76,22 @@ class Statement
|
|
71
76
|
|
72
77
|
# Common helper
|
73
78
|
|
74
|
-
def set_statement(support=nil, title=nil)
|
79
|
+
def set_statement(support=nil, title=nil, undefined:nil)
|
75
80
|
@code = "#{@code[0]}#{@statement_number}"
|
76
81
|
@code += '.' + @section unless @section=='-'
|
77
82
|
@code += "/#{support}" if support
|
78
|
-
@title = title
|
83
|
+
@title = title if (title=title&.split(':',2)&.first) && !title.empty?
|
84
|
+
@title = "#{@title}: #{undefined.join(' ')}" if undefined
|
79
85
|
end
|
80
86
|
|
81
|
-
def support(*s)
|
82
|
-
support = []
|
83
|
-
s.each do |s|
|
84
|
-
c = s.code.split('/',2)[0]
|
85
|
-
support.push(c)
|
86
|
-
end
|
87
|
-
return support.join(',')
|
88
|
-
end
|
87
|
+
def support(*s) = s.inject([]){|a,s| a.push(s.code.split('/',2)[0])}.join(',')
|
89
88
|
|
90
89
|
# Pattern helpers
|
91
90
|
|
92
91
|
def newlines_count(n)
|
93
|
-
|
92
|
+
unless n==@regexp.inspect.gsub('\\\\','').scan('\\n').length
|
93
|
+
raise Error, "expected #{n} newlines"
|
94
|
+
end
|
94
95
|
end
|
95
96
|
|
96
97
|
def set_regexp
|
@@ -100,11 +101,8 @@ class Statement
|
|
100
101
|
# Searches
|
101
102
|
|
102
103
|
def detect_statement(type)
|
103
|
-
|
104
|
-
|
105
|
-
end
|
106
|
-
raise Error, "does not match any '#{type}' statement" unless statement
|
107
|
-
return statement
|
104
|
+
@context.type(type).detect{_1.match? @statement} ||
|
105
|
+
raise(Error, "does not match any '#{type}' statement")
|
108
106
|
end
|
109
107
|
|
110
108
|
def heap_combos_search(type)
|
@@ -132,16 +130,13 @@ class Statement
|
|
132
130
|
def expected_instantiations(title=nil, n:nil)
|
133
131
|
undefined = @context.symbols.undefined(self)
|
134
132
|
if n ||= title&.match(/[1-9]\d*/)&.to_s&.to_i
|
135
|
-
|
136
|
-
|
137
|
-
|
133
|
+
unless n==undefined.length
|
134
|
+
raise Error, "expected #{n} undefined: #{undefined.join(' ')}"
|
135
|
+
end
|
136
|
+
elsif undefined.empty?
|
137
|
+
raise Error, 'nothing was undefined'
|
138
138
|
end
|
139
|
-
|
140
|
-
|
141
|
-
def undefined_in_pattern
|
142
|
-
@title = @title.split(':',2).first if @title
|
143
|
-
undefined = @context.symbols.undefined(self)
|
144
|
-
@title = "#{@title}: #{undefined.join(' ')}" unless undefined.empty?
|
139
|
+
undefined.empty? ? nil : undefined
|
145
140
|
end
|
146
141
|
|
147
142
|
# Statement type processing
|
@@ -149,50 +144,61 @@ class Statement
|
|
149
144
|
def pattern_type(nl)
|
150
145
|
set_regexp
|
151
146
|
newlines_count(nl)
|
152
|
-
|
147
|
+
undefined = (_=@context.symbols.undefined(self)).empty? ? nil : _
|
153
148
|
follows = @context.heap.to_a[0..nl].reverse
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
set_statement
|
158
|
-
end
|
149
|
+
support = @regexp.match?(follows.map(&:to_s).join("\n"))?
|
150
|
+
support(*follows) : nil
|
151
|
+
set_statement(support, undefined: undefined)
|
159
152
|
end
|
160
153
|
|
154
|
+
# A Tautology is an accepted true statement that immediately follows from
|
155
|
+
# an Axiom rule. It may not have any undefined terms.
|
161
156
|
def tautology
|
162
157
|
expected_instantiations(n:0)
|
163
158
|
axiom = detect_statement('A')
|
164
159
|
set_statement(support(axiom), axiom.title)
|
165
160
|
end
|
166
161
|
|
162
|
+
# A Set(Assignment) is an allowed true statement that introduces at least one
|
163
|
+
# term as immediately validated by a matching Let rule.
|
167
164
|
def set
|
168
165
|
let = detect_statement('L')
|
169
|
-
expected_instantiations(let.title)
|
170
|
-
set_statement(support(let), let.title)
|
166
|
+
undefined = expected_instantiations(let.title)
|
167
|
+
set_statement(support(let), let.title, undefined: undefined)
|
171
168
|
end
|
172
169
|
|
170
|
+
# A Result is a derived true statement that follows from a Map rule and
|
171
|
+
# matching true statement.
|
173
172
|
def result
|
174
173
|
expected_instantiations(n:0)
|
175
174
|
mapping,s1 = heap_search('M')
|
176
175
|
set_statement(support(mapping,s1), mapping.title)
|
177
176
|
end
|
178
177
|
|
178
|
+
# An Instantiation is a derived true statement that introduces at least one
|
179
|
+
# new term as a result of an Existential rule and matching true statement.
|
179
180
|
def instantiation
|
180
181
|
existential,s1 = heap_search('E')
|
181
|
-
expected_instantiations(existential.title)
|
182
|
-
set_statement(support(existential,s1), existential.title
|
182
|
+
undefined = expected_instantiations(existential.title)
|
183
|
+
set_statement(support(existential,s1), existential.title,
|
184
|
+
undefined: undefined)
|
183
185
|
end
|
184
186
|
|
187
|
+
# A Conclusion is a derived true statement, the result of an Inference rule
|
188
|
+
# that follows from two true statements.
|
185
189
|
def conclusion
|
186
190
|
expected_instantiations(n:0)
|
187
191
|
inference,s1,s2 = heap_combos_search('I')
|
188
192
|
set_statement(support(inference,s1,s2), inference.title)
|
189
193
|
end
|
190
194
|
|
195
|
+
# A Definition is an assumed true statement that defines at least one term.
|
191
196
|
def definition
|
192
197
|
expected_instantiations(@title)
|
193
198
|
set_statement
|
194
199
|
end
|
195
200
|
|
201
|
+
# A Postulate is an assumed true statement with all terms defined.
|
196
202
|
def postulate
|
197
203
|
expected_instantiations(n:0)
|
198
204
|
set_statement
|
data/lib/korekto/statements.rb
CHANGED
@@ -1,42 +1,36 @@
|
|
1
1
|
module Korekto
|
2
2
|
class Statements
|
3
3
|
attr_reader :heap,:symbols,:syntax
|
4
|
+
|
4
5
|
def initialize
|
5
6
|
@statements = []
|
6
|
-
@heap = Heap.new
|
7
|
+
@heap = Heap.new Korekto.heap
|
7
8
|
@symbols = Symbols.new
|
8
9
|
@syntax = Syntax.new
|
9
10
|
end
|
10
11
|
|
11
12
|
def type(c) = @statements.select{_1.type==c}
|
12
|
-
def length
|
13
|
+
def length = @statements.length
|
14
|
+
def last = @statements.last
|
13
15
|
|
14
16
|
def add(statement,code,title,filename)
|
15
17
|
c = code[0]; w = c=='W'
|
16
|
-
if restatement
|
17
|
-
|
18
|
-
|
19
|
-
@heap.add restatement
|
20
|
-
else
|
18
|
+
if (restatement=@statements.detect{(w || _1.type==c) && _1.to_s==statement})
|
19
|
+
unless 'DXSPTCR'.include?(restatement.type)
|
20
|
+
# Only allow heap-able statements to be restated.
|
21
21
|
raise Error, "restatement: #{restatement.code}"
|
22
22
|
end
|
23
|
-
|
23
|
+
@heap.add restatement
|
24
|
+
code, = restatement.code
|
24
25
|
title ||= restatement.title
|
25
26
|
return code, title
|
26
27
|
end
|
27
28
|
statement_number = yield
|
28
|
-
statement
|
29
|
+
statement=Statement.new(statement,code,title,filename,statement_number,self)
|
29
30
|
@statements.push statement
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
when 'D','X','S'
|
34
|
-
@symbols.define! statement
|
35
|
-
@heap.add statement
|
36
|
-
when 'P','T','C','R'
|
37
|
-
@heap.add statement
|
38
|
-
end
|
39
|
-
return statement.code, statement.title
|
31
|
+
@symbols.define! statement if 'AIEMLDXS'.include?(statement.type)
|
32
|
+
@heap.add statement if 'DXSPTCR'.include?(statement.type)
|
33
|
+
[statement.code, statement.title]
|
40
34
|
end
|
41
35
|
end
|
42
36
|
end
|
data/lib/korekto/symbols.rb
CHANGED
@@ -1,66 +1,64 @@
|
|
1
1
|
module Korekto
|
2
2
|
class Symbols
|
3
3
|
attr_reader :t2p, :v2t
|
4
|
+
|
4
5
|
def initialize
|
5
|
-
@
|
6
|
-
@
|
7
|
-
@
|
8
|
-
@scanner = /:\w+|./
|
6
|
+
@set = Set.new # Set of Korekto symbols(strings)
|
7
|
+
@v2t = {} # Variable to Type
|
8
|
+
@t2p = {} # Type to Pattern
|
9
|
+
@scanner = /:\w+|./ # Default scanner
|
9
10
|
end
|
10
11
|
|
12
|
+
# rubocop: disable Naming/AccessorMethodName
|
11
13
|
def set_scanner(value) = @scanner=Regexp.new(value)
|
14
|
+
# rubocop: enable Naming/AccessorMethodName
|
12
15
|
|
13
16
|
def undefined(statement)
|
14
|
-
undefined =
|
17
|
+
undefined = Set.new
|
15
18
|
if statement.pattern?
|
16
19
|
unless statement.literal_regexp?
|
17
|
-
statement.scan(@scanner)
|
20
|
+
statement.scan(@scanner) do |w|
|
21
|
+
undefined<<w unless @v2t.include?(w) || @set.include?(w)
|
22
|
+
end
|
18
23
|
end
|
19
24
|
else
|
20
|
-
statement.scan(@scanner){|w| undefined
|
25
|
+
statement.scan(@scanner){|w| undefined<<w unless @set.include?(w)}
|
21
26
|
end
|
22
|
-
|
27
|
+
undefined
|
23
28
|
end
|
24
29
|
|
25
|
-
def define!(statement)
|
26
|
-
if statement.pattern?
|
27
|
-
unless statement.literal_regexp?
|
28
|
-
statement.scan(@scanner){|w| @h[w]=nil unless @v2t.include?(w) or @h.include?(w)}
|
29
|
-
end
|
30
|
-
else
|
31
|
-
statement.scan(@scanner){|w| @h[w]=nil unless @h.include?(w)}
|
32
|
-
end
|
33
|
-
end
|
30
|
+
def define!(statement) = undefined(statement).each{|w| @set<<w}
|
34
31
|
|
35
32
|
def s2r(statement)
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
count += 1
|
49
|
-
seen[v]=count.to_s
|
50
|
-
pattern << '('+regex+')'
|
51
|
-
end
|
33
|
+
return Regexp.new statement[1..-2] if statement[0]=='/' &&
|
34
|
+
statement[-1]=='/'
|
35
|
+
pattern,count,seen = '\A',0,{}
|
36
|
+
# Build pattern from statement token by token, v.
|
37
|
+
statement.scan(@scanner) do |v|
|
38
|
+
if (n=seen[v])
|
39
|
+
pattern << '\\'+n
|
40
|
+
elsif (type = @v2t[v])
|
41
|
+
regex = @t2p[type]
|
42
|
+
if type[0]=='.'
|
43
|
+
# No capture patterns start with '.'
|
44
|
+
pattern << regex
|
52
45
|
else
|
53
|
-
|
54
|
-
v
|
55
|
-
|
56
|
-
'0123456789'.include?(_=v[0]) and v[0]='['+_+']'
|
57
|
-
pattern << v
|
46
|
+
count += 1
|
47
|
+
seen[v]=count.to_s
|
48
|
+
pattern << '('+regex+')'
|
58
49
|
end
|
50
|
+
else
|
51
|
+
# Escape Regexp specials
|
52
|
+
v = Regexp.quote v
|
53
|
+
# To avoid collisions with back-references,
|
54
|
+
# isolate digit in square brackets:
|
55
|
+
'0123456789'.include?(_=v[0]) and v[0]='['+_+']'
|
56
|
+
pattern << v
|
59
57
|
end
|
60
|
-
raise Error, 'pattern with no captures' if count < 1
|
61
|
-
pattern << '\Z'
|
62
|
-
Regexp.new(pattern)
|
63
58
|
end
|
59
|
+
raise Error, 'pattern with no captures' if count < 1
|
60
|
+
pattern << '\Z'
|
61
|
+
Regexp.new(pattern)
|
64
62
|
end
|
65
63
|
end
|
66
64
|
end
|
data/lib/korekto/syntax.rb
CHANGED
@@ -1,14 +1,17 @@
|
|
1
1
|
module Korekto
|
2
2
|
class Syntax
|
3
3
|
def initialize = @a=[]
|
4
|
-
def each = @a.each{|s|
|
4
|
+
def each(&blk) = @a.each{|s| blk[s]}
|
5
5
|
|
6
6
|
def push(s)
|
7
7
|
# ensure it'll eval on string and returns boolean
|
8
8
|
b = ''.instance_eval(s)
|
9
|
+
# rubocop: disable Style/DoubleNegation
|
9
10
|
raise Error, 'syntax rule must eval boolean' unless b==!!b
|
11
|
+
# rubocop: enable Style/DoubleNegation
|
10
12
|
@a.push(s)
|
11
|
-
rescue
|
13
|
+
rescue StandardError
|
14
|
+
raise if $!.is_a? Error
|
12
15
|
raise Error, "#{$!.class}: #{s}"
|
13
16
|
end
|
14
17
|
end
|
data/lib/korekto.rb
CHANGED
@@ -1,14 +1,51 @@
|
|
1
1
|
module Korekto
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
2
|
+
class Error < RuntimeError; end
|
3
|
+
|
4
|
+
VERSION = '2.0.231231'
|
5
|
+
|
6
|
+
def self.trace=(value)
|
7
|
+
@@trace = value
|
8
|
+
end
|
9
|
+
def self.trace?
|
10
|
+
@@trace
|
11
|
+
end
|
12
|
+
Korekto.trace = false
|
13
|
+
|
14
|
+
def self.patch=(value)
|
15
|
+
@@patch = value
|
16
|
+
end
|
17
|
+
def self.patch?
|
18
|
+
@@patch
|
19
|
+
end
|
20
|
+
Korekto.patch = false
|
21
|
+
|
22
|
+
def self.heap=(value)
|
23
|
+
@@heap = value
|
24
|
+
end
|
25
|
+
def self.heap
|
26
|
+
@@heap
|
27
|
+
end
|
28
|
+
Korekto.heap = 13
|
29
|
+
|
30
|
+
def self.scrape?
|
31
|
+
@@scrape
|
32
|
+
end
|
33
|
+
def self.scrape=(value)
|
34
|
+
@@scrape = value
|
35
|
+
end
|
36
|
+
Korekto.scrape = false
|
37
|
+
|
38
|
+
def self.run
|
39
|
+
require 'korekto/symbols'
|
40
|
+
require 'korekto/syntax'
|
41
|
+
require 'korekto/heap'
|
42
|
+
require 'korekto/statement'
|
43
|
+
require 'korekto/statements'
|
44
|
+
require 'korekto/main'
|
45
|
+
Korekto::Main.new.run
|
46
|
+
end
|
11
47
|
end
|
48
|
+
|
12
49
|
# Requires:
|
13
50
|
# `ruby`
|
14
51
|
# `nvim`
|
data/rplugin/ruby/korekto.rb
CHANGED
@@ -1,30 +1,38 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
module KorektoPlug
|
2
|
+
KOREKTO = `which korekto`.strip
|
3
|
+
VERSION = `#{KOREKTO} --version`.strip
|
4
|
+
|
5
|
+
def self.korekto(nvim, options='')
|
6
|
+
validations = nvim.command_output("w !#{KOREKTO} #{options}")
|
7
|
+
.strip.split("\n").map(&:strip)
|
8
|
+
msg = "Korekto! #{VERSION}"
|
5
9
|
unless validations.empty?
|
6
10
|
buf = nvim.get_current_buf
|
7
|
-
while validation = validations.shift
|
11
|
+
while (validation = validations.shift)
|
8
12
|
fields = validation.split(':',4)
|
9
13
|
n = fields[1].to_i
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
end
|
14
|
+
next unless n.positive?
|
15
|
+
fn,ln,code,title = fields
|
16
|
+
if %w[? !].include?(code)
|
17
|
+
# move onto error if on page
|
18
|
+
nvim.get_current_win.set_cursor([n,0]) if fn=='-'
|
19
|
+
# echo error message
|
20
|
+
msg = "#{fn}:#{ln}: #{title}"
|
21
|
+
# and stop.
|
22
|
+
break
|
23
|
+
elsif fn=='-'
|
24
|
+
line = buf[n].sub(/#.*$/,'').rstrip
|
25
|
+
line << "\t##{code}"
|
26
|
+
line << " #{title}" unless title==''
|
27
|
+
buf[n] = line unless line == buf[n]
|
25
28
|
end
|
26
29
|
end
|
27
30
|
end
|
28
31
|
nvim.command "echom #{msg.inspect}"
|
29
32
|
end
|
33
|
+
|
34
|
+
Neovim.plugin do |plug|
|
35
|
+
plug.command(:Korekto){|nvim| KorektoPlug.korekto(nvim)}
|
36
|
+
plug.command(:KorektoPatch){|nvim| KorektoPlug.korekto(nvim, '--patch')}
|
37
|
+
end
|
30
38
|
end
|
@@ -1,21 +1,31 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
syntax match
|
4
|
-
syntax match
|
5
|
-
syntax match
|
6
|
-
syntax match
|
7
|
-
syntax match
|
8
|
-
|
9
|
-
syntax match
|
10
|
-
syntax match
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
highlight
|
19
|
-
highlight
|
20
|
-
|
1
|
+
"### Korekto Syntax ###
|
2
|
+
" Korekto Type
|
3
|
+
syntax match KorektoUnsup /#[A-Z]\d\+\(\.\w\+\)\?\(\/\)\@!/ containedin=KorektoType
|
4
|
+
syntax match KorektoSup /#[A-Z]\d\+\(\.\w\+\)\?\/\S\+/ contained containedin=KorektoType
|
5
|
+
syntax match KorektoTitle /\(#[A-Z]\d\S*\s\)\@<=[^:]\+/ contained containedin=KorektoType
|
6
|
+
syntax match KorektoUndef /\(:\)\@<=.\+$/ contained containedin=KorektoType
|
7
|
+
syntax match KorektoType /#[A-Z]\d[^#]\+$/ contains=KorektoUnsup,KorektoSup,KorektoTitle,KorektoUndef
|
8
|
+
" Korekto Statement
|
9
|
+
syntax match KorektoLetter /[A-Za-z𝐀-𝟿]/ contained containedin=KorektoStatement
|
10
|
+
syntax match KorektoNumber /[0-9]/ contained containedin=KorektoStatement
|
11
|
+
syntax match KorektoPunctuation /[^0-9A-Za-z𝐀-𝟿]/ contained containedin=KorektoStatement
|
12
|
+
syntax match KorektoStatement /^.\+\(\s#[A-Z]\d\)\@=/ contains=KorektoLetter,KorektoNumber,KorektoPunctuation
|
13
|
+
" Korekto Non-Statement
|
14
|
+
syntax match KorektoComment /^#\+\s.\+/
|
15
|
+
syntax match KorektoPatch /^::[A-Z].\+/
|
16
|
+
syntax match KorektoCommand /^[<!?]\s.\+/
|
17
|
+
"### Korekto Highlighting ###
|
18
|
+
highlight KorektoUnsup ctermfg=brown
|
19
|
+
highlight KorektoSup ctermfg=darkgreen
|
20
|
+
highlight KorektoTitle ctermfg=blue
|
21
|
+
highlight KorektoUndef ctermfg=red
|
22
|
+
highlight KorektoComment ctermfg=darkblue
|
23
|
+
highlight KorektoPatch ctermfg=grey
|
24
|
+
highlight KorektoCommand ctermfg=lightgrey
|
25
|
+
highlight KorektoPunctuation ctermfg=darkgrey
|
26
|
+
highlight KorektoNumber ctermfg=darkred
|
27
|
+
highlight KorektoLetter ctermfg=black
|
28
|
+
"### Settings ###
|
29
|
+
setlocal tabstop=3
|
30
|
+
map <leader><F7> :KorektoPatch<CR>
|
21
31
|
map <F7> :Korekto<CR>
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: korekto
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.231231
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
-
|
8
|
-
autorequire:
|
7
|
+
- CarlosJHR64
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-12-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: help_parser
|
@@ -16,30 +16,131 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '8.2'
|
20
20
|
- - ">="
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version:
|
22
|
+
version: 8.2.230210
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
27
|
- - "~>"
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version: '
|
29
|
+
version: '8.2'
|
30
30
|
- - ">="
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version:
|
32
|
+
version: 8.2.230210
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: colorize
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '1.1'
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: 1.1.0
|
43
|
+
type: :development
|
44
|
+
prerelease: false
|
45
|
+
version_requirements: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - "~>"
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '1.1'
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: 1.1.0
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
name: cucumber
|
55
|
+
requirement: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - "~>"
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '9.1'
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 9.1.0
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - "~>"
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '9.1'
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: 9.1.0
|
73
|
+
- !ruby/object:Gem::Dependency
|
74
|
+
name: parser
|
75
|
+
requirement: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - "~>"
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '3.2'
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 3.2.2
|
83
|
+
type: :development
|
84
|
+
prerelease: false
|
85
|
+
version_requirements: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '3.2'
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: 3.2.2
|
93
|
+
- !ruby/object:Gem::Dependency
|
94
|
+
name: rubocop
|
95
|
+
requirement: !ruby/object:Gem::Requirement
|
96
|
+
requirements:
|
97
|
+
- - "~>"
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '1.59'
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: 1.59.0
|
103
|
+
type: :development
|
104
|
+
prerelease: false
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - "~>"
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '1.59'
|
110
|
+
- - ">="
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: 1.59.0
|
113
|
+
- !ruby/object:Gem::Dependency
|
114
|
+
name: test-unit
|
115
|
+
requirement: !ruby/object:Gem::Requirement
|
116
|
+
requirements:
|
117
|
+
- - "~>"
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
version: '3.6'
|
120
|
+
- - ">="
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: 3.6.1
|
123
|
+
type: :development
|
124
|
+
prerelease: false
|
125
|
+
version_requirements: !ruby/object:Gem::Requirement
|
126
|
+
requirements:
|
127
|
+
- - "~>"
|
128
|
+
- !ruby/object:Gem::Version
|
129
|
+
version: '3.6'
|
130
|
+
- - ">="
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: 3.6.1
|
33
133
|
description: |
|
34
134
|
A general proof checker.
|
35
135
|
|
36
|
-
Works with neovim(
|
136
|
+
Works with [neovim](https://github.com/neovim/neovim).
|
37
137
|
email: carlosjhr64@gmail.com
|
38
138
|
executables:
|
39
139
|
- korekto
|
40
140
|
extensions: []
|
41
141
|
extra_rdoc_files: []
|
42
142
|
files:
|
143
|
+
- README.md
|
43
144
|
- bin/korekto
|
44
145
|
- lib/korekto.rb
|
45
146
|
- lib/korekto/heap.rb
|
@@ -55,7 +156,7 @@ homepage: https://github.com/carlosjhr64/korekto
|
|
55
156
|
licenses:
|
56
157
|
- MIT
|
57
158
|
metadata: {}
|
58
|
-
post_install_message:
|
159
|
+
post_install_message:
|
59
160
|
rdoc_options: []
|
60
161
|
require_paths:
|
61
162
|
- lib
|
@@ -70,12 +171,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
70
171
|
- !ruby/object:Gem::Version
|
71
172
|
version: '0'
|
72
173
|
requirements:
|
73
|
-
- '
|
74
|
-
- '
|
75
|
-
- '
|
76
|
-
- '
|
77
|
-
|
78
|
-
|
174
|
+
- 'git: 2.30'
|
175
|
+
- 'neovim-ruby-host: 0.9'
|
176
|
+
- 'nvim: 0.9'
|
177
|
+
- 'ruby: 3.3'
|
178
|
+
- 'xdg-open: 1.1'
|
179
|
+
rubygems_version: 3.5.3
|
180
|
+
signing_key:
|
79
181
|
specification_version: 4
|
80
182
|
summary: A general proof checker.
|
81
183
|
test_files: []
|