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