1 /*
2
3 This file is part of the Maude 2 interpreter.
4
5 Copyright 1997-2003 SRI International, Menlo Park, CA 94025, USA.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
20
21 */
22
23 //
24 // Implementation for class TemporalSymbol.
25 //
26
27 // utility stuff
28 #include "macros.hh"
29 #include "vector.hh"
30
31 // forward declarations
32 #include "temporal.hh"
33 #include "interface.hh"
34 #include "core.hh"
35 #include "freeTheory.hh"
36 #include "builtIn.hh"
37 #include "higher.hh"
38
39 // interface class definitions
40 #include "symbol.hh"
41 #include "dagNode.hh"
42 #include "term.hh"
43
44 // core class definitions
45 #include "dagArgumentIterator.hh"
46 #include "rewritingContext.hh"
47 #include "symbolMap.hh"
48
49 // free theory class definitions
50 #include "freeDagNode.hh"
51
52 // built in class definitions
53 #include "bindingMacros.hh"
54
55 // temporal class definitions
56 #include "logicFormula.hh"
57
58 // higher class definitions
59 #include "temporalSymbol.hh"
60
TemporalSymbol(int id,int arity)61 TemporalSymbol::TemporalSymbol(int id, int arity)
62 : FreeSymbol(id, arity)
63 {
64 trueSymbol = 0;
65 falseSymbol = 0;
66 notSymbol = 0;
67 nextSymbol = 0;
68 andSymbol = 0;
69 orSymbol = 0;
70 untilSymbol = 0;
71 releaseSymbol = 0;
72 }
73
74 bool
attachSymbol(const char * purpose,Symbol * symbol)75 TemporalSymbol::attachSymbol(const char* purpose, Symbol* symbol)
76 {
77 BIND_SYMBOL(purpose, symbol, trueSymbol, Symbol*);
78 BIND_SYMBOL(purpose, symbol, falseSymbol, Symbol*);
79 BIND_SYMBOL(purpose, symbol, notSymbol, Symbol*);
80 BIND_SYMBOL(purpose, symbol, nextSymbol, Symbol*);
81 BIND_SYMBOL(purpose, symbol, andSymbol, Symbol*);
82 BIND_SYMBOL(purpose, symbol, orSymbol, Symbol*);
83 BIND_SYMBOL(purpose, symbol, untilSymbol, Symbol*);
84 BIND_SYMBOL(purpose, symbol, releaseSymbol, Symbol*);
85 return FreeSymbol::attachSymbol(purpose, symbol);
86 }
87
88 void
copyAttachments(Symbol * original,SymbolMap * map)89 TemporalSymbol::copyAttachments(Symbol* original, SymbolMap* map)
90 {
91 TemporalSymbol* orig = safeCast(TemporalSymbol*, original);
92 COPY_SYMBOL(orig, trueSymbol, map, Symbol*);
93 COPY_SYMBOL(orig, falseSymbol, map, Symbol*);
94 COPY_SYMBOL(orig, notSymbol, map, Symbol*);
95 COPY_SYMBOL(orig, nextSymbol, map, Symbol*);
96 COPY_SYMBOL(orig, andSymbol, map, Symbol*);
97 COPY_SYMBOL(orig, orSymbol, map, Symbol*);
98 COPY_SYMBOL(orig, untilSymbol, map, Symbol*);
99 COPY_SYMBOL(orig, releaseSymbol, map, Symbol*);
100 FreeSymbol::copyAttachments(original, map);
101 }
102
103 void
getSymbolAttachments(Vector<const char * > & purposes,Vector<Symbol * > & symbols)104 TemporalSymbol::getSymbolAttachments(Vector<const char*>& purposes,
105 Vector<Symbol*>& symbols)
106 {
107 APPEND_SYMBOL(purposes, symbols, trueSymbol);
108 APPEND_SYMBOL(purposes, symbols, falseSymbol);
109 APPEND_SYMBOL(purposes, symbols, notSymbol);
110 APPEND_SYMBOL(purposes, symbols, nextSymbol);
111 APPEND_SYMBOL(purposes, symbols, andSymbol);
112 APPEND_SYMBOL(purposes, symbols, orSymbol);
113 APPEND_SYMBOL(purposes, symbols, untilSymbol);
114 APPEND_SYMBOL(purposes, symbols, releaseSymbol);
115 FreeSymbol::getSymbolAttachments(purposes, symbols);
116 }
117
118 int
build(LogicFormula & formula,DagNodeSet & propositions,DagNode * dagNode) const119 TemporalSymbol::build(LogicFormula& formula, DagNodeSet& propositions, DagNode* dagNode) const
120 {
121 Symbol* s = dagNode->symbol();
122 if (s == trueSymbol)
123 return formula.makeOp(LogicFormula::LTL_TRUE);
124 if (s == falseSymbol)
125 return formula.makeOp(LogicFormula::LTL_FALSE);
126 if (s == notSymbol || s == nextSymbol)
127 {
128 LogicFormula::Op op = (s == notSymbol) ? LogicFormula::NOT : LogicFormula::NEXT;
129 DagArgumentIterator i(*dagNode);
130 if (i.valid())
131 {
132 int a = build(formula, propositions, i.argument());
133 if (a != NONE &&
134 (op != LogicFormula::NOT || formula.getOp(a) == LogicFormula::PROPOSITION))
135 return formula.makeOp(op, a);
136 }
137 return NONE;
138 }
139 if (s == andSymbol || s == orSymbol)
140 {
141 LogicFormula::Op op = (s == andSymbol) ? LogicFormula::AND : LogicFormula::OR;
142 DagArgumentIterator i(*dagNode);
143 if (i.valid())
144 {
145 int a = build(formula, propositions, i.argument());
146 i.next();
147 if (a != NONE && i.valid())
148 {
149 int b;
150 for (;;)
151 {
152 b = build(formula, propositions, i.argument());
153 if (b == NONE)
154 break;
155 a = formula.makeOp(op, a, b);
156 i.next();
157 if (!(i.valid()))
158 return a;
159 }
160 }
161 }
162 return NONE;
163 }
164 if (s == untilSymbol || s == releaseSymbol)
165 {
166 LogicFormula::Op op = (s == untilSymbol) ? LogicFormula::UNTIL : LogicFormula::RELEASE;
167 DagArgumentIterator i(*dagNode);
168 if (i.valid())
169 {
170 int a = build(formula, propositions, i.argument());
171 i.next();
172 if (a != NONE && i.valid())
173 {
174 int b = build(formula, propositions, i.argument());
175 if (b != NONE)
176 return formula.makeOp(op, a, b);
177 }
178 }
179 return NONE;
180 }
181 int propIndex = propositions.dagNode2Index(dagNode);
182 if (propIndex == NONE)
183 {
184 propIndex = propositions.cardinality();
185 propositions.insert(dagNode);
186 }
187 return formula.makeProp(propIndex);
188 }
189
190 DagNode*
conjunct(Vector<DagNode * > & args) const191 TemporalSymbol::conjunct(Vector<DagNode*>& args) const
192 {
193 int last = args.length() - 1;
194 if (last < 0)
195 return trueSymbol->makeDagNode(args);
196
197 static Vector<DagNode*> pair(2);
198 pair[1] = args[last];
199 for (int i = last - 1; i >= 0; --i)
200 {
201 pair[0] = args[i];
202 pair[1] = andSymbol->makeDagNode(pair);
203 }
204 return pair[1];
205 }
206