1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
#!/usr/bin/env ruby
def _c s
s.strip.lstrip.gsub("'", '').gsub(/\s+/, "_")
end
class Item
attr_accessor :predicate, :arguments
def initialize predicate='', arguments=[]
@predicate = predicate
@arguments = []
end
def to_s
args = @arguments.each{|i| i.to_s}.to_s.gsub('[','(').gsub(']',')')
"#{@predicate}#{args}"
end
end
def parse_funql s
s = "(#{s})"
structure = Item.new
prev_p = nil
p = structure
collect = ''
just_closed = false
s.each_char { |c|
if c == '('
p.arguments << Item.new(_c(collect))
collect = ''
prev_p = p
p = p.arguments.last
just_closed = false
elsif c == ')'
if collect != ''
p.arguments << _c(collect)
collect = ''
end
p = prev_p
just_closed = true
elsif c == ','
if collect != ''
p.arguments << _c(collect)
collect = ''
end
if just_closed
p = prev_p
end
just_closed = false
else
collect += c
end
}
return structure
end
def flatten_funql a
return "#{a} " if a.class == String
s = "#{a.predicate}$#{a.arguments.size} "
a.arguments.each { |i|
s += flatten_funql(i)
}
return s
end
def _fix_output s
s[5..s.size-1].lstrip.strip.gsub("'", '')
end
def reverse s
s.strip!
open = 0
r = ''
s.split.each { |i|
term, n = i.split '$'
n = n.to_i
out = term
if n == 0
out = "'#{out}'"
elsif n > 0
out += '('
open += 1
else
puts "ERROR"
exit
end
r += out
}
open.times { r += ')' }
return r.gsub("''", "','")
end
def test
a = []
a << "answer(exclude(state(all), next_to_2(stateid('texas'))))"
a << "answer(most(state(traverse_1(river(all)))))"
a << "answer(state(loc_1(river(riverid('red')))))"
a << "answer(smallest_one(area_1(state(next_to_2(stateid('texas'))))))"
a << "answer(smallest_one(density_1(state(all))))"
a << "answer(smallest_one(density_1(state(all))))"
a << "answer(smallest_one(density_1(state(all))))"
a << "answer(state(loc_1(cityid('kalamazoo', _))))"
a.each { |i|
puts i
r = parse_funql(i)
puts r.to_s
puts _fix_output(flatten_funql(r))
puts
}
end
def main
#test
while line = STDIN.gets
x = _fix_output(flatten_funql(parse_funql(line.strip)))
puts line
puts x
puts reverse(x)
puts
end
end
main
|