mumuki-prolog-runner 1.0.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/lib/expectations_hook.rb +63 -0
- data/lib/feedback_hook.rb +71 -0
- data/lib/main.pl.erb +107 -0
- data/lib/metadata_hook.rb +16 -0
- data/lib/prolog_runner.rb +19 -0
- data/lib/query_hook.rb +79 -0
- data/lib/test_hook.rb +31 -0
- metadata +135 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 13d4e23a78247d40578287655fbd10a6ed83a2fd
|
4
|
+
data.tar.gz: 335636f3b50c7b702dc2e80538e13a10cb7b2a6b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 08ac692949314e4641f3cc96718577fb776233e1c6fb4ad5240f0640fa444b9a0f59223039e080b696b5dd033edf05871eeff90e3c07793a952003b1cf4c9f23
|
7
|
+
data.tar.gz: 5ed272405a23dff488b813261ae7af1209b9ac805ffb84a21382f06a94b84bb3f6c3409325d8ef2a9ab22e11bc5d5a0888b11b2bac6ae83235e94619b953a249
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'mumukit/inspection'
|
3
|
+
|
4
|
+
class Mumukit::Inspection::PlainInspection
|
5
|
+
def to_term
|
6
|
+
"inspection('#{type}')"
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class Mumukit::Inspection::TargetedInspection
|
11
|
+
def to_term
|
12
|
+
"inspection('#{type}',#{Integer(target)})" rescue "inspection('#{type}','#{target}')"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class Mumukit::Inspection::NegatedInspection
|
17
|
+
def to_term
|
18
|
+
"not(#{@inspection.to_term})"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class PrologExpectationsHook < Mumukit::Templates::FileHook
|
23
|
+
isolated true
|
24
|
+
|
25
|
+
def command_line(filename)
|
26
|
+
"swipl -f #{filename} --quiet -t main 2>&1"
|
27
|
+
end
|
28
|
+
|
29
|
+
def compile_file_content(request)
|
30
|
+
ExpectationsFile.new(request).render
|
31
|
+
end
|
32
|
+
|
33
|
+
def post_process_file(file, result, status)
|
34
|
+
JSON.parse(result)['expectationResults'] rescue []
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class ExpectationsFile
|
39
|
+
def initialize(request)
|
40
|
+
@content = request.content
|
41
|
+
@expectation_terms = self.class.expectations_to_terms(request.expectations)
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.expectations_to_terms(expectations)
|
45
|
+
'[' + expectations.map do |e|
|
46
|
+
"expectation('#{e['binding']}',#{inspection_to_term(e['inspection'])})"
|
47
|
+
end.join(',') + ']'
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.inspection_to_term(s)
|
51
|
+
Mumukit::Inspection.parse(s).to_term
|
52
|
+
end
|
53
|
+
|
54
|
+
def render
|
55
|
+
ERB.new(File.read(template_path)).result(binding)
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def template_path
|
61
|
+
File.expand_path '../main.pl.erb', __FILE__
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
class PrologFeedbackHook < Mumukit::Hook
|
2
|
+
def run!(request, results)
|
3
|
+
content = request.content
|
4
|
+
test_results = results.test_results[0]
|
5
|
+
|
6
|
+
PrologExplainer.new.explain(content, test_results)
|
7
|
+
end
|
8
|
+
|
9
|
+
class PrologExplainer < Mumukit::Explainer
|
10
|
+
def explain_wrong_distinct_operator(content, _)
|
11
|
+
(/.{0,9}(\/=|<>|!=).{0,9}/.match content).try do |it|
|
12
|
+
{near: it[0]}
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def explain_wrong_gte_operator(content, _)
|
17
|
+
(/.{0,9}(=>).{0,9}/.match content).try do |it|
|
18
|
+
{near: it[0]}
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def explain_wrong_lte_operator(content, _)
|
23
|
+
(/.{0,9}(<=).{0,9}/.match content).try do |it|
|
24
|
+
{near: it[0]}
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
def explain_clauses_not_together(_, test_results)
|
30
|
+
(/Clauses of .*:(.*) are not together in the source-file/.match test_results).try do |it|
|
31
|
+
{target: it[1]}
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def explain_singleton_variables(_, test_results)
|
36
|
+
(/Singleton variables: \[(.*)\]/.match test_results).try do |it|
|
37
|
+
{target: it[1]}
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def explain_test_failed(_, test_results)
|
42
|
+
/test (.*): failed/ =~ test_results
|
43
|
+
end
|
44
|
+
|
45
|
+
def explain_not_sufficiently_instantiated(_, test_results)
|
46
|
+
(/received error: (.*): Arguments are not sufficiently instantiated/.match test_results).try do |it|
|
47
|
+
{target: it[1]}
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def explain_operator_error(_, test_results)
|
52
|
+
/ERROR: (.*): Syntax error: Operator expected/ =~ test_results
|
53
|
+
end
|
54
|
+
|
55
|
+
def explain_missing_dot_error(_, test_results)
|
56
|
+
/ERROR: (.*): Syntax error: Operator priority clash/ =~ test_results
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
def explain_wrong_comma(_, test_results)
|
61
|
+
/ERROR: (.*): Full stop in clause-body\? Cannot redefine ,\/2/ =~ test_results
|
62
|
+
end
|
63
|
+
|
64
|
+
def explain_missing_predicate(_, test_results)
|
65
|
+
(/.*:(.*): Undefined procedure: .*:(.*)/.match test_results).try do |it|
|
66
|
+
{target: it[1],
|
67
|
+
missing: it[2]} unless it[1].include? 'unit body'
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
data/lib/main.pl.erb
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
run_expectations(Expectations, Results) :-
|
2
|
+
maplist(run_expectation, Expectations, Results).
|
3
|
+
|
4
|
+
run_expectation(Expectation, result(Expectation, Result)) :- eval_expectation(Expectation,Result).
|
5
|
+
|
6
|
+
eval_expectation(expectation(Binding, Inspection), true) :-
|
7
|
+
call_expectation(Binding, Inspection), !.
|
8
|
+
eval_expectation(_, false).
|
9
|
+
|
10
|
+
call_expectation(Binding, inspection('HasBinding')) :-
|
11
|
+
usesPredicate(pred(Binding, _), _).
|
12
|
+
call_expectation(Binding, inspection('HasForall')) :-
|
13
|
+
hasForall(pred(Binding, _)).
|
14
|
+
call_expectation(Binding, inspection('HasFindall')) :-
|
15
|
+
hasFindall(pred(Binding, _)).
|
16
|
+
call_expectation(Binding, inspection('HasNot')) :-
|
17
|
+
hasNot(pred(Binding, _)).
|
18
|
+
call_expectation(Binding, inspection('HasUsage', Other)) :-
|
19
|
+
usesPredicate(pred(Binding, _), pred(Other, _)).
|
20
|
+
call_expectation(Binding, inspection('HasDirectRecursion')) :-
|
21
|
+
recursive(pred(Binding, _)).
|
22
|
+
call_expectation(Binding, inspection('HasArity', Arity)) :-
|
23
|
+
usesPredicate(pred(Binding, Arity), _).
|
24
|
+
call_expectation(Binding, not(Inspection)) :-
|
25
|
+
\+ call_expectation(Binding, Inspection).
|
26
|
+
call_expectation(Binding, inspection('HasCut')) :-
|
27
|
+
hasCut(pred(Binding, _)).
|
28
|
+
|
29
|
+
<%= @content %>
|
30
|
+
|
31
|
+
predToHead(pred(PredicateName, Arity), Head) :-
|
32
|
+
between(0, 9, Arity),
|
33
|
+
functor(Head, PredicateName, Arity).
|
34
|
+
|
35
|
+
clauseElements(Predicate, Elements):-
|
36
|
+
predToHead(Predicate, Head),
|
37
|
+
clause(Head, Clause),
|
38
|
+
clauseToList(Clause, Elements).
|
39
|
+
|
40
|
+
clauseToList((A,B), [A | BToList]):- clauseToList(B, BToList).
|
41
|
+
clauseToList(A, [A]):- functor(A,Name,_), Name \= (',').
|
42
|
+
|
43
|
+
usesPredicate(Predicate, UsedPredicate):-
|
44
|
+
clauseElements(Predicate, Elements),
|
45
|
+
member(ClauseElement, Elements),
|
46
|
+
isOrContains(ClauseElement, UsedPredicate).
|
47
|
+
|
48
|
+
isOrContains(ClauseElement, Predicate):- predToHead(Predicate, ClauseElement).
|
49
|
+
isOrContains(ClauseElement, Predicate):-
|
50
|
+
ClauseElement =.. [_|Args],
|
51
|
+
member(Arg, Args),
|
52
|
+
not(var(Arg)),
|
53
|
+
isOrContains(Arg, Predicate).
|
54
|
+
|
55
|
+
%% This would require a parametrized expectation
|
56
|
+
numberOfClauses(Predicate, Amount):-
|
57
|
+
predToHead(Predicate, Head),
|
58
|
+
findall(_,clause(Head,_), Clauses),
|
59
|
+
length(Clauses, Amount).
|
60
|
+
|
61
|
+
recursive(Predicate):-
|
62
|
+
usesPredicate(Predicate, Predicate).
|
63
|
+
|
64
|
+
hasForall(Predicate):-
|
65
|
+
usesPredicate(Predicate, pred(forall,2)).
|
66
|
+
|
67
|
+
hasNot(Predicate):-
|
68
|
+
usesPredicate(Predicate, pred(not,1)).
|
69
|
+
|
70
|
+
hasFindall(Predicate):-
|
71
|
+
usesPredicate(Predicate, pred(findall,3)).
|
72
|
+
|
73
|
+
hasCut(Predicate):-
|
74
|
+
usesPredicate(Predicate, pred(!,0)).
|
75
|
+
|
76
|
+
|
77
|
+
main(_) :-
|
78
|
+
Expectations = <%= @expectation_terms %>,
|
79
|
+
run_expectations(Expectations, Results),
|
80
|
+
write_json(Results).
|
81
|
+
|
82
|
+
write_json(Results) :-
|
83
|
+
write('{"expectationResults":['),
|
84
|
+
write_results(Results),
|
85
|
+
write(']}').
|
86
|
+
|
87
|
+
write_results([]).
|
88
|
+
write_results([X1]) :-
|
89
|
+
write_result(X1).
|
90
|
+
write_results([X1,X2|Xs]) :-
|
91
|
+
write_result(X1),
|
92
|
+
write(','),
|
93
|
+
write_results([X2|Xs]).
|
94
|
+
|
95
|
+
write_result(result(expectation(Binding, Inspection), Result)) :-
|
96
|
+
swrite_inspection(Inspection, SInspection),
|
97
|
+
writef('{"expectation":{"binding":"%w", "inspection":"%w"},"result":%w}',
|
98
|
+
[Binding, SInspection, Result]).
|
99
|
+
|
100
|
+
swrite_inspection(inspection(X), S) :-
|
101
|
+
swritef(S, "%w", [X]).
|
102
|
+
swrite_inspection(inspection(X, Y), S) :-
|
103
|
+
swritef(S, "%w:%w", [X, Y]).
|
104
|
+
swrite_inspection(not(Inspection), S2) :-
|
105
|
+
swrite_inspection(Inspection, S1),
|
106
|
+
swritef(S2, "Not:%w", [S1]).
|
107
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class PrologMetadataHook < Mumukit::Hook
|
2
|
+
def metadata
|
3
|
+
{language: {
|
4
|
+
name: 'prolog',
|
5
|
+
icon: {type: 'devicon', name: 'prolog'},
|
6
|
+
version: 'swi-prolog 6.6.4',
|
7
|
+
extension: 'pl',
|
8
|
+
ace_mode: 'prolog',
|
9
|
+
prompt: '?'
|
10
|
+
},
|
11
|
+
test_framework: {
|
12
|
+
name: 'plunit',
|
13
|
+
test_extension: 'pl'
|
14
|
+
}}
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'i18n'
|
2
|
+
|
3
|
+
I18n.load_path += Dir[File.join('.', 'locales', '*.yml')]
|
4
|
+
|
5
|
+
require 'mumukit'
|
6
|
+
|
7
|
+
Mumukit.runner_name = 'prolog'
|
8
|
+
Mumukit.configure do |config|
|
9
|
+
config.docker_image = 'mumuki/mumuki-plunit-worker'
|
10
|
+
config.content_type = 'markdown'
|
11
|
+
end
|
12
|
+
|
13
|
+
require_relative 'test_hook'
|
14
|
+
require_relative 'query_hook'
|
15
|
+
require_relative 'expectations_hook'
|
16
|
+
require_relative 'metadata_hook'
|
17
|
+
require_relative 'feedback_hook'
|
18
|
+
|
19
|
+
|
data/lib/query_hook.rb
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
class PrologQueryHook < Mumukit::Templates::FileHook
|
2
|
+
isolated true
|
3
|
+
|
4
|
+
def command_line(filename)
|
5
|
+
"swipl -f #{filename} --quiet -t main 2>&1"
|
6
|
+
end
|
7
|
+
|
8
|
+
def compile_file_content(req)
|
9
|
+
<<PROLOG
|
10
|
+
#{req.extra}
|
11
|
+
#{req.content}
|
12
|
+
|
13
|
+
main(_):-
|
14
|
+
run_query('#{req.query.gsub('\\', '\\' * 3 )}').
|
15
|
+
|
16
|
+
run_query(Query):-
|
17
|
+
catch(findall(Result, (atom_to_term(Query, Term, Result), Term), ResultSet),
|
18
|
+
error(TypeError,_),
|
19
|
+
(handleQueryError(TypeError, Query), halt(100)) ),
|
20
|
+
prettyWriteResultSet(ResultSet).
|
21
|
+
|
22
|
+
handleQueryError(type_error(callable,_), Query):-
|
23
|
+
writef('ERROR: run_query/1: Expected Callable predicate but instead got %w\\n', [Query]).
|
24
|
+
|
25
|
+
handleQueryError(syntax_error(TypeSyntaxError), Query):-
|
26
|
+
writef('ERROR: run_query/1: Syntax Error: %w in %w\\n', [TypeSyntaxError, Query]).
|
27
|
+
|
28
|
+
handleQueryError(signal(_,Number), _):-
|
29
|
+
SignalStatus is 128 + Number,
|
30
|
+
halt(SignalStatus).
|
31
|
+
|
32
|
+
handleQueryError(GeneralError, Query):-
|
33
|
+
writef('ERROR: run_query/1: %w in \\'%w\\'\\n', [GeneralError, Query]).
|
34
|
+
|
35
|
+
prettyWriteResultSet([]):-
|
36
|
+
writeln('no.').
|
37
|
+
|
38
|
+
prettyWriteResultSet([OneResult]):-
|
39
|
+
prettyWriteOneResult(OneResult),
|
40
|
+
writeln('.').
|
41
|
+
|
42
|
+
prettyWriteResultSet([OneResult | ResultSet]):-
|
43
|
+
ResultSet \\= [],
|
44
|
+
prettyWriteOneResult(OneResult),
|
45
|
+
writeln(' ;'),
|
46
|
+
prettyWriteResultSet(ResultSet).
|
47
|
+
|
48
|
+
prettyWriteOneResult([]):-
|
49
|
+
write('yes').
|
50
|
+
|
51
|
+
prettyWriteOneResult([OneBinding]):-
|
52
|
+
writeBinding(OneBinding).
|
53
|
+
|
54
|
+
prettyWriteOneResult([OneBinding | OneResult]):-
|
55
|
+
OneResult \\= [],
|
56
|
+
writeBinding(OneBinding),
|
57
|
+
writeln(','),
|
58
|
+
prettyWriteOneResult(OneResult).
|
59
|
+
|
60
|
+
writeBinding(OneBinding):-
|
61
|
+
OneBinding=..[(=), VarName, Value],
|
62
|
+
writef('%w = %w', [VarName, Value]).
|
63
|
+
|
64
|
+
writeBinding(NotABinding):-
|
65
|
+
not(NotABinding=..[(=) | _ ]),
|
66
|
+
writef('ERROR: writeBinding/1: Expected Binding, but no equals was found in: %w\\n', [NotABinding]),
|
67
|
+
halt(101).
|
68
|
+
|
69
|
+
PROLOG
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
|
76
|
+
|
77
|
+
|
78
|
+
|
79
|
+
|
data/lib/test_hook.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
class PrologTestHook < Mumukit::Templates::FileHook
|
2
|
+
isolated true
|
3
|
+
|
4
|
+
def post_process_file(file, result, status)
|
5
|
+
if /ERROR: #{file.path}:.*: Syntax error: .*/ =~ result
|
6
|
+
[format_code(result), :failed]
|
7
|
+
elsif /Caught signal 24 \(xcpu\)/ =~ result
|
8
|
+
[format_code(I18n.t(:time_exceeded)), :failed]
|
9
|
+
else
|
10
|
+
[format_code(result), status]
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def command_line(filename)
|
15
|
+
"swipl -f #{filename} --quiet -t run_tests 2>&1"
|
16
|
+
end
|
17
|
+
|
18
|
+
def format_code(code)
|
19
|
+
"```\n#{code}\n```"
|
20
|
+
end
|
21
|
+
|
22
|
+
def compile_file_content(request)
|
23
|
+
<<EOF
|
24
|
+
:- begin_tests(mumuki_submission_test, []).
|
25
|
+
#{request.test}
|
26
|
+
#{request.content}
|
27
|
+
#{request.extra}
|
28
|
+
:- end_tests(mumuki_submission_test).
|
29
|
+
EOF
|
30
|
+
end
|
31
|
+
end
|
metadata
ADDED
@@ -0,0 +1,135 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mumuki-prolog-runner
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Franco Leonardo Bulgarelli
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-09-27 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: mumukit
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.5'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.5'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.7'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.7'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '10.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '10.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.4'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.4'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: codeclimate-test-reporter
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: mumukit-bridge
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '1.3'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '1.3'
|
97
|
+
description:
|
98
|
+
email:
|
99
|
+
- franco@mumuki.org
|
100
|
+
executables: []
|
101
|
+
extensions: []
|
102
|
+
extra_rdoc_files: []
|
103
|
+
files:
|
104
|
+
- lib/expectations_hook.rb
|
105
|
+
- lib/feedback_hook.rb
|
106
|
+
- lib/main.pl.erb
|
107
|
+
- lib/metadata_hook.rb
|
108
|
+
- lib/prolog_runner.rb
|
109
|
+
- lib/query_hook.rb
|
110
|
+
- lib/test_hook.rb
|
111
|
+
homepage: http://github.com/mumuki/mumuki-prolog-server
|
112
|
+
licenses:
|
113
|
+
- MIT
|
114
|
+
metadata: {}
|
115
|
+
post_install_message:
|
116
|
+
rdoc_options: []
|
117
|
+
require_paths:
|
118
|
+
- lib
|
119
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - ">="
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '0'
|
124
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
125
|
+
requirements:
|
126
|
+
- - ">="
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
version: '0'
|
129
|
+
requirements: []
|
130
|
+
rubyforge_project:
|
131
|
+
rubygems_version: 2.4.8
|
132
|
+
signing_key:
|
133
|
+
specification_version: 4
|
134
|
+
summary: Prolog Runner for Mumuki
|
135
|
+
test_files: []
|