propose 0.0.1
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/bin/propose +5 -0
- data/lib/propose.rb +19 -0
- data/lib/propose/atom_finder.rb +19 -0
- data/lib/propose/parser.rb +33 -0
- data/lib/propose/repl.rb +67 -0
- data/lib/propose/tree/atom.rb +32 -0
- data/lib/propose/tree/binary_operation.rb +34 -0
- data/lib/propose/tree/conjunction.rb +12 -0
- data/lib/propose/tree/disjunction.rb +12 -0
- data/lib/propose/tree/falsum.rb +24 -0
- data/lib/propose/tree/implication.rb +13 -0
- data/lib/propose/tree/negation.rb +12 -0
- data/lib/propose/tree/node.rb +16 -0
- data/lib/propose/tree/sequent.rb +30 -0
- data/lib/propose/tree/unary_operation.rb +33 -0
- data/lib/propose/tree/verum.rb +24 -0
- data/lib/propose/truth_table.rb +38 -0
- data/lib/propose/version.rb +4 -0
- data/lib/propose/visitor.rb +39 -0
- metadata +147 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 5e51a21663914889a221fc855ab81d9b864e4f7c
|
4
|
+
data.tar.gz: c100032842cfb108b8181ca745767d428921aac4
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0fa8554ec8b5b662c683cf8b8dafd9beecbd90a92ace372f3dd18308d9e21ce05013343288c0394ca32841bdbe0007400f7c0b1e1124e1895cc263207b4697fb
|
7
|
+
data.tar.gz: fd45c6fd818f0255ebae73f43c56feb70ea892b7a9e12fc12739d5604a7a3e7529b6abd5b8c506366b803a7cc3f4e681841fc2e3530c572d9d5689990c4cc576
|
data/bin/propose
ADDED
data/lib/propose.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'propose/parser'
|
2
|
+
require 'propose/repl'
|
3
|
+
require 'propose/truth_table'
|
4
|
+
require 'propose/version'
|
5
|
+
|
6
|
+
require 'propose/visitor'
|
7
|
+
require 'propose/atom_finder'
|
8
|
+
|
9
|
+
require 'propose/tree/node'
|
10
|
+
require 'propose/tree/binary_operation'
|
11
|
+
require 'propose/tree/conjunction'
|
12
|
+
require 'propose/tree/disjunction'
|
13
|
+
require 'propose/tree/falsum'
|
14
|
+
require 'propose/tree/implication'
|
15
|
+
require 'propose/tree/atom'
|
16
|
+
require 'propose/tree/unary_operation'
|
17
|
+
require 'propose/tree/negation'
|
18
|
+
require 'propose/tree/sequent'
|
19
|
+
require 'propose/tree/verum'
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'set'
|
2
|
+
|
3
|
+
module Propose
|
4
|
+
# Finds all atoms in a parse tree.
|
5
|
+
class AtomFinder
|
6
|
+
include Propose::Visitor
|
7
|
+
|
8
|
+
attr_reader :atoms
|
9
|
+
|
10
|
+
def initialize(formula)
|
11
|
+
@atoms = Set.new
|
12
|
+
visit(formula)
|
13
|
+
end
|
14
|
+
|
15
|
+
def visit_atom(atom)
|
16
|
+
@atoms << atom
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'treetop'
|
2
|
+
|
3
|
+
module Propose
|
4
|
+
# Raised when the parser is unable to parse the input.
|
5
|
+
class ParseError < StandardError; end
|
6
|
+
|
7
|
+
# Parses a propositional logic statement into an abstract syntax tree.
|
8
|
+
class Parser
|
9
|
+
GRAMMAR_FILE = File.expand_path(File.join(File.dirname(__FILE__),
|
10
|
+
'..', '..', 'grammar',
|
11
|
+
'propositional_logic.treetop'))
|
12
|
+
|
13
|
+
class << self
|
14
|
+
def parse(string)
|
15
|
+
tree = parser.parse(string)
|
16
|
+
if tree
|
17
|
+
tree.to_ast
|
18
|
+
else
|
19
|
+
raise ParseError, parser.failure_reason
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def parser
|
26
|
+
@parser ||= begin
|
27
|
+
Treetop.load(GRAMMAR_FILE)
|
28
|
+
PropositionalLogicParser.new
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/propose/repl.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'colorize'
|
2
|
+
require 'readline'
|
3
|
+
require 'terminal-table'
|
4
|
+
|
5
|
+
module Propose
|
6
|
+
# Read-Eval-Print-Loop engine, allowing a user to interactively create
|
7
|
+
# and explore the properties of propositional logic statements.
|
8
|
+
class REPL
|
9
|
+
def run
|
10
|
+
while input = Readline.readline('> '.green, true)
|
11
|
+
handle_input(input)
|
12
|
+
end
|
13
|
+
rescue SignalException # rubocop:disable HandleExceptions
|
14
|
+
# User hit Ctrl-C; close gracefully
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def handle_input(input)
|
20
|
+
input = input.strip
|
21
|
+
interpret(input) unless input.empty?
|
22
|
+
rescue ParseError => ex
|
23
|
+
puts "Invalid expression: #{ex.message}".red
|
24
|
+
end
|
25
|
+
|
26
|
+
def interpret(input)
|
27
|
+
statement = Parser.parse(input)
|
28
|
+
|
29
|
+
case statement
|
30
|
+
when Tree::Sequent
|
31
|
+
puts statement.to_s.cyan
|
32
|
+
# TODO: Find and display proof of sequent
|
33
|
+
else
|
34
|
+
print_truth_table(statement)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def print_truth_table(statement)
|
39
|
+
tt = Propose::TruthTable.new(statement)
|
40
|
+
|
41
|
+
atoms = tt.formula_atoms.to_a
|
42
|
+
|
43
|
+
table = Terminal::Table.new do |t|
|
44
|
+
t << atoms + ['Result']
|
45
|
+
t.add_separator
|
46
|
+
tt.evaluations.each do |assignment, result|
|
47
|
+
t << assignment.values.map { |v| shorthand_value(v) } + [shorthand_value(result)]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
table.title = statement.to_s
|
52
|
+
|
53
|
+
(atoms.count + 1).times do |i|
|
54
|
+
table.align_column(i, :center)
|
55
|
+
end
|
56
|
+
|
57
|
+
puts table.to_s
|
58
|
+
.gsub('T', 'T'.green)
|
59
|
+
.gsub('F', 'F'.red)
|
60
|
+
.gsub(table.title, table.title.cyan)
|
61
|
+
end
|
62
|
+
|
63
|
+
def shorthand_value(value)
|
64
|
+
value ? 'T' : 'F'
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Propose::Tree
|
2
|
+
# Declarative statement that can be either true or false.
|
3
|
+
#
|
4
|
+
# For example: "The sun is shining."
|
5
|
+
class Atom < Node
|
6
|
+
attr_reader :name
|
7
|
+
|
8
|
+
def initialize(name)
|
9
|
+
@name = name
|
10
|
+
end
|
11
|
+
|
12
|
+
def ==(other)
|
13
|
+
super || @name == other.name
|
14
|
+
end
|
15
|
+
|
16
|
+
def evaluate(assignment)
|
17
|
+
assignment[self]
|
18
|
+
end
|
19
|
+
|
20
|
+
def literal?
|
21
|
+
true
|
22
|
+
end
|
23
|
+
|
24
|
+
def inspect
|
25
|
+
"#<Atom #{name}>"
|
26
|
+
end
|
27
|
+
|
28
|
+
def to_s
|
29
|
+
name.to_s
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Propose::Tree
|
2
|
+
# Represents two propositional formula joined by a logical connective.
|
3
|
+
class BinaryOperation < Node
|
4
|
+
attr_reader :operator, :left, :right
|
5
|
+
|
6
|
+
def initialize(operator, left, right)
|
7
|
+
@operator = operator
|
8
|
+
@left = left
|
9
|
+
@right = right
|
10
|
+
end
|
11
|
+
|
12
|
+
def ==(other)
|
13
|
+
super || @operator == other.operator &&
|
14
|
+
@left == other.left &&
|
15
|
+
@right == other.right
|
16
|
+
end
|
17
|
+
|
18
|
+
def children
|
19
|
+
[left, right]
|
20
|
+
end
|
21
|
+
|
22
|
+
def inspect
|
23
|
+
"#<#{self.class.name.split('::').last} #{left.inspect} #{right.inspect}>"
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_s
|
27
|
+
output = []
|
28
|
+
output << (left.literal? ? left.to_s : "(#{left})")
|
29
|
+
output << " #{operator} "
|
30
|
+
output << (right.literal? ? right.to_s : "(#{right})")
|
31
|
+
output.join
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Propose::Tree
|
2
|
+
# A conjunction of two expressions, indicating both are true.
|
3
|
+
class Conjunction < BinaryOperation
|
4
|
+
def initialize(left, right)
|
5
|
+
super('∧', left, right)
|
6
|
+
end
|
7
|
+
|
8
|
+
def evaluate(assignment)
|
9
|
+
left.evaluate(assignment) && right.evaluate(assignment)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Propose::Tree
|
2
|
+
# A disjunction of two expressions, indicating at least one of them is true.
|
3
|
+
class Disjunction < BinaryOperation
|
4
|
+
def initialize(left, right)
|
5
|
+
super('∨', left, right)
|
6
|
+
end
|
7
|
+
|
8
|
+
def evaluate(assignment)
|
9
|
+
left.evaluate(assignment) || right.evaluate(assignment)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
|
3
|
+
module Propose::Tree
|
4
|
+
# Represents a contradiction, or falseness.
|
5
|
+
class Falsum < Node
|
6
|
+
include Singleton
|
7
|
+
|
8
|
+
def evaluate(_assignment)
|
9
|
+
false
|
10
|
+
end
|
11
|
+
|
12
|
+
def literal?
|
13
|
+
true
|
14
|
+
end
|
15
|
+
|
16
|
+
def inspect
|
17
|
+
'#<Falsum>'
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_s
|
21
|
+
'⊥'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Propose::Tree
|
2
|
+
# Expresses the concept that the right expression is a logical consequence of
|
3
|
+
# the left expression.
|
4
|
+
class Implication < BinaryOperation
|
5
|
+
def initialize(left, right)
|
6
|
+
super('→', left, right)
|
7
|
+
end
|
8
|
+
|
9
|
+
def evaluate(assignment)
|
10
|
+
!left.evaluate(assignment) || right.evaluate(assignment)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Propose::Tree
|
2
|
+
# Generic definition of a parse tree node for propositional logic.
|
3
|
+
class Node
|
4
|
+
# Nodes which can be considered the children of this node.
|
5
|
+
def children
|
6
|
+
[]
|
7
|
+
end
|
8
|
+
|
9
|
+
# Whether this node can be considered an unambiguous single lexical unit.
|
10
|
+
#
|
11
|
+
# This is used to omit unnecessary parentheses when rendering.
|
12
|
+
def literal?
|
13
|
+
false
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Propose::Tree
|
2
|
+
# Statement indicating that a set of premises (propositional formulae) can be
|
3
|
+
# used to prove to a conclusion (another propositional formula).
|
4
|
+
#
|
5
|
+
# Sequents which the premises do not prove the conclusion are called invalid.
|
6
|
+
class Sequent < Node
|
7
|
+
attr_reader :premises, :conclusion
|
8
|
+
|
9
|
+
def initialize(premises, conclusion)
|
10
|
+
@premises = premises
|
11
|
+
@conclusion = conclusion
|
12
|
+
end
|
13
|
+
|
14
|
+
def ==(other)
|
15
|
+
super || @premises == other.premises && @conclusion == other.conclusion
|
16
|
+
end
|
17
|
+
|
18
|
+
def children
|
19
|
+
premises + [conclusion]
|
20
|
+
end
|
21
|
+
|
22
|
+
def inspect
|
23
|
+
"#<Sequent [#{premises.map(&:inspect).join(', ')}] ⊢ #{conclusion.inspect}"
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_s
|
27
|
+
"#{premises.map(&:to_s).join(', ')} ⊢ #{conclusion}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Propose::Tree
|
2
|
+
# Represents an operation on a single propositional formula.
|
3
|
+
class UnaryOperation < Node
|
4
|
+
attr_reader :operator, :formula
|
5
|
+
|
6
|
+
def initialize(operator, formula)
|
7
|
+
@operator = operator
|
8
|
+
@formula = formula
|
9
|
+
end
|
10
|
+
|
11
|
+
def ==(other)
|
12
|
+
super || @operator == other.operator && @formula == other.formula
|
13
|
+
end
|
14
|
+
|
15
|
+
def children
|
16
|
+
[formula]
|
17
|
+
end
|
18
|
+
|
19
|
+
def literal?
|
20
|
+
@formula.literal?
|
21
|
+
end
|
22
|
+
|
23
|
+
def inspect
|
24
|
+
"#<#{self.class.name.split('::').last} #{formula.inspect}>"
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_s
|
28
|
+
output = [operator.to_s]
|
29
|
+
output << (formula.literal? ? formula.to_s : "(#{formula})")
|
30
|
+
output.join
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
|
3
|
+
module Propose::Tree
|
4
|
+
# Represents absolute tautological truth.
|
5
|
+
class Verum < Node
|
6
|
+
include Singleton
|
7
|
+
|
8
|
+
def evaluate(_assignment)
|
9
|
+
true
|
10
|
+
end
|
11
|
+
|
12
|
+
def literal?
|
13
|
+
true
|
14
|
+
end
|
15
|
+
|
16
|
+
def inspect
|
17
|
+
'#<Verum>'
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_s
|
21
|
+
'⊤'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Propose
|
2
|
+
# Generates a truth table for a given propositional logic formula.
|
3
|
+
class TruthTable
|
4
|
+
attr_reader :formula, :evaluations
|
5
|
+
|
6
|
+
def initialize(formula)
|
7
|
+
@formula = formula
|
8
|
+
@evaluations = generate(formula)
|
9
|
+
end
|
10
|
+
|
11
|
+
def formula_atoms
|
12
|
+
@formula_atoms ||= AtomFinder.new(formula).atoms
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def generate(formula)
|
18
|
+
assignments = generate_assignments(formula_atoms.to_a)
|
19
|
+
|
20
|
+
assignments.map do |assignment|
|
21
|
+
result = formula.evaluate(assignment)
|
22
|
+
[assignment, result]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def generate_assignments(atoms)
|
27
|
+
return [{}] unless atoms && atoms.count > 0
|
28
|
+
atom = atoms[0]
|
29
|
+
subset = atoms[1..-1]
|
30
|
+
|
31
|
+
sub_assignments = generate_assignments(subset)
|
32
|
+
|
33
|
+
sub_assignments.flat_map do |sub_assign|
|
34
|
+
[{ atom => true }.merge(sub_assign), { atom => false }.merge(sub_assign)]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Propose
|
2
|
+
# Provides basic functionality for traversing a parse tree.
|
3
|
+
#
|
4
|
+
# Classes which include this module can define methods such as
|
5
|
+
# `visit_conjunction` to have the visitor visit all conjunctions in the parse
|
6
|
+
# tree.
|
7
|
+
module Visitor
|
8
|
+
def visit(node)
|
9
|
+
# Keep track of whether this block was consumed by the visitor. This
|
10
|
+
# allows us to visit all nodes by default, but can override the behavior
|
11
|
+
# by specifying `yield false` in a visit method, indicating that no
|
12
|
+
# further visiting should occur for the current node's children.
|
13
|
+
block_called = false
|
14
|
+
|
15
|
+
block = ->(descend = :children) do
|
16
|
+
block_called = true
|
17
|
+
visit_children(node) if descend == :children
|
18
|
+
end
|
19
|
+
|
20
|
+
method = "visit_#{node_name(node)}"
|
21
|
+
|
22
|
+
send(method, node, &block) if respond_to?(method, true)
|
23
|
+
|
24
|
+
visit_children(node) unless block_called
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def visit_children(parent)
|
30
|
+
parent.children.each { |node| visit(node) }
|
31
|
+
end
|
32
|
+
|
33
|
+
def node_name(node)
|
34
|
+
klass = node.class
|
35
|
+
@node_names ||= {}
|
36
|
+
@node_names[klass] ||= klass.name.gsub(/.*::(.*?)$/, '\\1').downcase
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
metadata
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: propose
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Shane da Silva
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-09-03 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: colorize
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.7'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.7'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: terminal-table
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.4'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.4'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: treetop
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.5'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.5'
|
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.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec-its
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rubocop
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - '='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 0.25.0
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 0.25.0
|
97
|
+
description: Create, manipulate, and verify propositional logic sentences
|
98
|
+
email: shane@dasilva.io
|
99
|
+
executables:
|
100
|
+
- propose
|
101
|
+
extensions: []
|
102
|
+
extra_rdoc_files: []
|
103
|
+
files:
|
104
|
+
- bin/propose
|
105
|
+
- lib/propose.rb
|
106
|
+
- lib/propose/atom_finder.rb
|
107
|
+
- lib/propose/parser.rb
|
108
|
+
- lib/propose/repl.rb
|
109
|
+
- lib/propose/tree/atom.rb
|
110
|
+
- lib/propose/tree/binary_operation.rb
|
111
|
+
- lib/propose/tree/conjunction.rb
|
112
|
+
- lib/propose/tree/disjunction.rb
|
113
|
+
- lib/propose/tree/falsum.rb
|
114
|
+
- lib/propose/tree/implication.rb
|
115
|
+
- lib/propose/tree/negation.rb
|
116
|
+
- lib/propose/tree/node.rb
|
117
|
+
- lib/propose/tree/sequent.rb
|
118
|
+
- lib/propose/tree/unary_operation.rb
|
119
|
+
- lib/propose/tree/verum.rb
|
120
|
+
- lib/propose/truth_table.rb
|
121
|
+
- lib/propose/version.rb
|
122
|
+
- lib/propose/visitor.rb
|
123
|
+
homepage: https://github.com/sds/propose
|
124
|
+
licenses:
|
125
|
+
- MIT
|
126
|
+
metadata: {}
|
127
|
+
post_install_message:
|
128
|
+
rdoc_options: []
|
129
|
+
require_paths:
|
130
|
+
- lib
|
131
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
132
|
+
requirements:
|
133
|
+
- - "~>"
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
version: '2.0'
|
136
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
137
|
+
requirements:
|
138
|
+
- - ">="
|
139
|
+
- !ruby/object:Gem::Version
|
140
|
+
version: '0'
|
141
|
+
requirements: []
|
142
|
+
rubyforge_project:
|
143
|
+
rubygems_version: 2.2.2
|
144
|
+
signing_key:
|
145
|
+
specification_version: 4
|
146
|
+
summary: Propositional logic sentence playground
|
147
|
+
test_files: []
|