Class: PgVerify::Transform::HashTransformation

Inherits:
Object
  • Object
show all
Defined in:
lib/pg-verify/transform/hash_transformation.rb

Instance Method Summary collapse

Instance Method Details

#parse_component(graph, hash) ⇒ Object



39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/pg-verify/transform/hash_transformation.rb', line 39

def parse_component(graph, hash)
    name = hash.keys.first
    states = hash[name]["states"].map(&:to_sym)
    variables = hash[name]["variables"].map { |v| parse_variable(name, v) }
    init_expression = parse_expression(hash[name]["init"])
    transitions = hash[name]["transitions"].map { |t| parse_transition(t) }
    represents_fault = hash[name]["represents_fault"]

    graph.variables += variables

    return Model::Component.new(name: name.to_sym, states: states, 
        transitions: transitions, represents_fault: represents_fault, init_expression: init_expression)
end

#parse_expression(expression) ⇒ Object



89
90
91
92
93
94
# File 'lib/pg-verify/transform/hash_transformation.rb', line 89

def parse_expression(expression)
    return nil if expression.nil?
    string = expression["string"]
    type = expression["type"].to_sym
    return Model::ParsedExpression.new(string, type)
end

#parse_graph(hash) ⇒ Object



16
17
18
19
20
21
22
23
24
25
26
# File 'lib/pg-verify/transform/hash_transformation.rb', line 16

def parse_graph(hash)
    name = hash.keys.first.to_sym
    graph = Model::Graph.new(name)
    components = hash[hash.keys.first]["components"].map { |c| parse_component(graph, c) }
    hazards = hash[hash.keys.first]["hazards"]&.map { |h| parse_hazard(h) } || []
    specification = parse_specification(hash[hash.keys.first]["specification"])
    graph.components = components
    graph.hazards = hazards
    graph.specification = specification
    return graph
end

#parse_hazard(hash) ⇒ Object



117
118
119
# File 'lib/pg-verify/transform/hash_transformation.rb', line 117

def parse_hazard(hash)
    return Model::Hazard.new(hash["label"], hash["expression"])
end

#parse_specification(array) ⇒ Object



127
128
129
130
131
132
# File 'lib/pg-verify/transform/hash_transformation.rb', line 127

def parse_specification(array)
    specs = array.map { |hash|
        Model::Spec.new(hash["label"], parse_expression(hash["expression"]), nil)
    }
    return  Model::Specification.new([Model::SpecSet.wrap(specs)])
end

#parse_transition(hash) ⇒ Object



105
106
107
108
109
110
111
# File 'lib/pg-verify/transform/hash_transformation.rb', line 105

def parse_transition(hash)
    src_state, tgt_state = hash.keys.first.split("->").map(&:strip).map(&:to_sym)
    precon = parse_expression(hash.values.first["precon"])
    guard  = parse_expression(hash.values.first["guard"] )
    action = parse_expression(hash.values.first["action"])
    return Model::Transition.new(src_state, tgt_state, precon: precon, guard: guard, action: action)
end

#parse_variable(owner_name, hash) ⇒ Object



60
61
62
63
64
65
# File 'lib/pg-verify/transform/hash_transformation.rb', line 60

def parse_variable(owner_name, hash)
    name = hash.keys.first
    range = parse_variable_range(hash[name]["range"])
    init_expression = parse_expression(hash[name]["init"])
    return Model::Variable.new(name.to_sym, range, owner_name.to_sym, nil, init: init_expression)
end

#parse_variable_range(range) ⇒ Object



72
73
74
75
76
77
78
79
# File 'lib/pg-verify/transform/hash_transformation.rb', line 72

def parse_variable_range(range)
    # Matches ranges like 1..12 or -1..23
    if range.is_a?(String) && range.match(/\A\-?\d+\.\.\-?\d+\z/)
        first, last = range.split("..")[0], range.split("..")[-1]
        return Range.new(first.to_i, last.to_i)
    end
    return range
end

#transform_component(graph, component) ⇒ Object



28
29
30
31
32
33
34
35
36
37
# File 'lib/pg-verify/transform/hash_transformation.rb', line 28

def transform_component(graph, component)
    variables = graph.variables.select_by_owner(component)
    return { component.name.to_s => {
        "states" => component.states.map(&:to_s),
        "variables" => variables.map { |v| transform_variable(v) },
        "init" => transform_expression(component.init_expression),
        "transitions" => component.transitions.map { |t| transform_transition(t) },
        "represents_fault" => component.represents_fault
    }}
end

#transform_expression(expression) ⇒ Object



81
82
83
84
85
86
87
# File 'lib/pg-verify/transform/hash_transformation.rb', line 81

def transform_expression(expression)
    return nil if expression.nil?
    return { 
        "string" => expression.expression_string, 
        "type" => expression.type.to_s
    }
end

#transform_graph(graph) ⇒ Object



6
7
8
9
10
11
12
13
14
# File 'lib/pg-verify/transform/hash_transformation.rb', line 6

def transform_graph(graph)
    components = graph.components.map { |c| transform_component(graph, c) }
    hazards    = graph.hazards.map { |h| transform_hazard(h) }
    sub_hash = {}
    sub_hash["components"] = components
    sub_hash["hazards"] = hazards unless hazards.empty?
    sub_hash["specification"] = transform_specification(graph.specification)
    return { graph.name.to_s => sub_hash }
end

#transform_hazard(hazard) ⇒ Object



113
114
115
# File 'lib/pg-verify/transform/hash_transformation.rb', line 113

def transform_hazard(hazard)
    return { "label" => hazard.text, "expression" => hazard.expression }
end

#transform_specification(specification) ⇒ Object



121
122
123
124
125
# File 'lib/pg-verify/transform/hash_transformation.rb', line 121

def transform_specification(specification)
    return specification.flatten().map { |spec|
        { "label" => spec.text.strip, "expression" => transform_expression(spec.expression) }
    }
end

#transform_transition(transition) ⇒ Object



96
97
98
99
100
101
102
103
# File 'lib/pg-verify/transform/hash_transformation.rb', line 96

def transform_transition(transition)
    name = "#{transition.src_state} -> #{transition.tgt_state}"
    return { name => {
        "precon" => transform_expression(transition.precon),
        "guard" => transform_expression(transition.guard),
        "action" => transform_expression(transition.action),
    }}
end

#transform_variable(variable) ⇒ Object



53
54
55
56
57
58
# File 'lib/pg-verify/transform/hash_transformation.rb', line 53

def transform_variable(variable)
    return { variable.name.to_s => {
        "range" => transform_variable_range(variable.range),
        "init" => transform_expression(variable.init_expression)
    }}
end

#transform_variable_range(range) ⇒ Object



67
68
69
70
# File 'lib/pg-verify/transform/hash_transformation.rb', line 67

def transform_variable_range(range)
    return "#{range.first}..#{range.last}"if range.is_a?(Range)
    return range
end