Project

General

Profile

root / trunk / compiler / ooasCompiler / src / org / momut / ooas / codegen / prolog / OoaPrologVisitor.java @ 10

1
/**
2
  *
3
  *                      OOAS Compiler
4
  *
5
  *       Copyright 2015, AIT Austrian Institute of Technology.
6
  * This code is based on the C# Version of the OOAS Compiler, which is
7
  * copyright 2015 by the Institute of Software Technology, Graz University
8
  * of Technology with portions copyright by the AIT Austrian Institute of
9
  * Technology. All rights reserved.
10
  *
11
  * SEE THE "LICENSE" FILE FOR THE TERMS UNDER WHICH THIS FILE IS PROVIDED.
12
  *
13
  * If you modify the file please update the list of contributors below to in-
14
  * clude your name. Please also stick to the coding convention of using TABs
15
  * to do the basic (block-level) indentation and spaces for anything after
16
  * that. (Enable the display of special chars and it should be pretty obvious
17
  * what this means.) Also, remove all trailing whitespace.
18
  *
19
  * Contributors:
20
  *               Willibald Krenn (AIT)
21
  *               Stephan Zimmerer (AIT)
22
  *               Markus Demetz (AIT)
23
  *               Christoph Czurda (AIT)
24
  *
25
  */
26

    
27

    
28
package org.momut.ooas.codegen.prolog;
29

    
30
import java.util.ArrayList;
31
import java.util.Date;
32

    
33
import org.momut.ooas.ast.identifiers.AttributeIdentifier;
34
import org.momut.ooas.ast.identifiers.Identifier;
35
import org.momut.ooas.ast.identifiers.IdentifierKind;
36
import org.momut.ooas.ast.identifiers.MainModule;
37
import org.momut.ooas.ast.identifiers.MethodIdentifier;
38
import org.momut.ooas.ast.identifiers.NamedActionIdentifier;
39
import org.momut.ooas.ast.identifiers.ParameterIdentifier;
40
import org.momut.ooas.ast.identifiers.TypeIdentifier;
41
import org.momut.ooas.ast.statements.Block;
42
import org.momut.ooas.ast.types.FunctionType;
43
import org.momut.ooas.ast.types.FunctionType.FunctionTypeEnum;
44
import org.momut.ooas.codegen.OoasCodeEmitter;
45
import org.momut.ooas.parser.ParserState;
46
import org.momut.ooas.utils.OoasCompilerHashMap;
47
import org.momut.ooas.visitors.OoaCompleteAstTraversalVisitor;
48

    
49
public class OoaPrologVisitor extends OoaCompleteAstTraversalVisitor
50
{
51
        protected OoasCodeEmitter m_emitter;
52
        protected final Scratchbook m_scratchbook = new Scratchbook();
53

    
54
//        private String PrologIdentifier(Identifier id)
55
//        {
56
//                OoaPrologIdentifier identifierVisitor = m_idFactory.create();
57
//                id.Accept(identifierVisitor);
58
//                return identifierVisitor.toString();
59
//        }
60

    
61
        protected void ExportMethodsAndActions(MainModule mainModule)
62
        {
63
                final StringBuilder varActions = new StringBuilder();
64
                m_emitter.AppendLine();
65
                m_emitter.AppendLine("% action system");
66
                m_emitter.AppendLineIncIndent("as :- ");
67

    
68
                /* export methods */
69
                m_emitter.AppendLine("methods (");
70
                ExportMethods(mainModule);
71
                m_emitter.AppendLine("), ");
72
                m_emitter.AppendLine("actions (");
73
                ExportNamedActions(mainModule, varActions);
74
                m_emitter.AppendLine("), ");
75
                m_emitter.AppendLine("dood (");
76

    
77
                ExportDoOdBlock(mainModule.instance().doOdBlock(), m_emitter);
78

    
79

    
80
                m_emitter.AppendLine("), qdes (none)");
81
                m_emitter.DecIndent();
82
                m_emitter.AppendLine(".");
83
                m_emitter.AppendLine("");
84

    
85
                m_emitter.Append(varActions.toString());
86
        }
87

    
88
        private void ExportMethods(MainModule mainModule)
89
        {
90
                int y = 0;
91
                for (final Identifier x: mainModule.instance().symbols().symbolList())
92
                {
93
                        if (x.kind() == IdentifierKind.MethodIdentifier)
94
                        {
95
                                if (y != 0)
96
                                        m_emitter.AppendLine(", ");
97
                                else
98
                                        y++;
99

    
100
                                final MethodIdentifier theMethod = (MethodIdentifier)x;
101
                                final OoaPrologIdentifier pIdent = m_idFactory.create();
102
                                theMethod.Accept(pIdent);
103

    
104
                                /* method */
105
                                final StringBuilder parameter = new StringBuilder();
106
                                if (theMethod.parameter().size() > 0 || ((FunctionType)theMethod.type()).returnType() != null)
107
                                {
108
                                        parameter.append("(");
109
                                        int z = 0;
110
                                        for (final ParameterIdentifier param: theMethod.parameter())
111
                                        {
112
                                                if (z != 0)
113
                                                {
114
                                                        parameter.append(", ");
115
                                                }
116
                                                else
117
                                                        z++;
118
                                                final OoaPrologIdentifier pParamIdent = m_idFactory.create();
119
                                                param.Accept(pParamIdent);
120
                                                parameter.append(pParamIdent.toString());
121
                                        }
122

    
123

    
124
                                        if (((FunctionType)theMethod.type()).returnType() != null)
125
                                        {
126
                                                if (z != 0)
127
                                                        parameter.append(", ");
128
                                                parameter.append("RESULT");
129
                                        }
130
                                        parameter.append(")");
131
                                }
132
                                m_emitter.AppendLineIncIndent(String.format("%s%s = (", pIdent.toString(), parameter.toString()));
133

    
134
                                final OoaPrologStatement pBody = createStatementVisitor();
135
                                ((MethodIdentifier)x).body().Accept(pBody);
136
                                m_emitter.Append(pBody.toString());
137
                                m_emitter.Append(")");
138
                                m_emitter.DecIndent();
139
                        }
140
                }
141
                if (y == 0)
142
                        m_emitter.Append(" none ");
143
        }
144

    
145
        private void ExportNamedActions(MainModule mainModule, StringBuilder varActions)
146
        {
147
                int y = 0;
148
                for (final Identifier x: mainModule.instance().symbols().symbolList())
149
                {
150
                        if (x.kind() == IdentifierKind.NamedActionIdentifier)
151
                        {
152
                                if (y != 0)
153
                                        m_emitter.AppendLine(", ");
154
                                else
155
                                        y++;
156
                                final NamedActionIdentifier action = (NamedActionIdentifier)x;
157
                                final OoaPrologIdentifier pIdent = m_idFactory.create();
158
                                action.Accept(pIdent);
159

    
160
                                if (((FunctionType)action.type()).functionType() != FunctionTypeEnum.Continuous)
161
                                {
162
                                        /* discrete actions */
163
                                        final StringBuilder parameter = new StringBuilder();
164
                                        final StringBuilder parametertype = new StringBuilder();
165
                                        if (action.parameter().size() > 0)
166
                                        {
167
                                                parameter.append("(");
168
                                                parametertype.append("(");
169
                                                int z = 0;
170
                                                for (final ParameterIdentifier param: action.parameter())
171
                                                {
172
                                                        if (z != 0)
173
                                                        {
174
                                                                parameter.append(", ");
175
                                                                parametertype.append(", ");
176
                                                        }
177
                                                        else
178
                                                                z++;
179
                                                        final OoaPrologIdentifier pParamIdent = m_idFactory.create();
180
                                                        param.Accept(pParamIdent);
181
                                                        parameter.append(pParamIdent.toString());
182

    
183
                                                        final OoaPrologType pParamType = createTypeVisitor();  // bugfix me!
184
                                                        param.type().Accept(pParamType);
185
                                                        parametertype.append(pParamType.toString());
186

    
187
                                                }
188
                                                parametertype.append(")");
189
                                                parameter.append(")");
190
                                        }
191
                                        //if (parametertype.Length > 0)
192
                                        //    varActions.AppendLine(String.format("%s%s.", pIdent.toString(), parametertype.toString()));
193
                                        m_emitter.AppendLineIncIndent(String.format("%s%s::", pIdent.toString(), parameter.toString()));
194
                                }
195
                                else
196
                                {
197
                                        // we do not support continuous actions anymore.
198
                                        throw new UnsupportedOperationException();
199
//                                        /* observable state vars outside... */
200
//                                        final StringBuilder parameter = new StringBuilder();
201
//                                        int z = 0;
202
//                                        for (final Statement stmt : ((GuardedCommand)action.body().statements().peekFirst()).body().statements())
203
//                                        {
204
//                                                final QualitativeConstraintStatement qstmt = (QualitativeConstraintStatement)stmt;
205
//                                                if (qstmt.operation() == QualitativeConstraintOperation.Equal
206
//                                                                && qstmt.variable1().kind() == IdentifierKind.AttributeIdentifier
207
//                                                                && ((AttributeIdentifier)qstmt.variable1()).isObservable())
208
//                                                {
209
//                                                        if (z != 0)
210
//                                                                parameter.append(", ");
211
//                                                        else
212
//                                                                z++;
213
//                                                        qstmt.tag = true;
214
//                                                        final OoaPrologIdentifier pParamIdent1 = m_idFactory.create();
215
//                                                        final OoaPrologIdentifier pParamIdent2 = m_idFactory.create();
216
//                                                        qstmt.variable0().Accept(pParamIdent1);
217
//                                                        qstmt.variable1().Accept(pParamIdent2);
218
//                                                        parameter.append(String.format("%s(%s)", pParamIdent2.toString(), pParamIdent1.toString()));
219
//                                                }
220
//                                        }
221
//                                        m_emitter.AppendLineIncIndent(String.format("[%s]::", parameter.toString()));
222
                                }
223

    
224
                                final OoaPrologStatement pBody = createStatementVisitor();
225
                                ((NamedActionIdentifier)x).body().Accept(pBody);
226
                                m_emitter.Append(pBody.toString());
227
                                m_emitter.DecIndent();
228

    
229
                        }
230
                }
231
        }
232

    
233
        private void ExportDoOdBlock(Block block, OoasCodeEmitter m_emitter)
234
        {
235
                final OoaPrologStatement statement = createStatementVisitor();
236
                block.Accept(statement);
237
                m_emitter.Append(statement.toString());
238
        }
239

    
240
        protected int ExportActions(MainModule mainModule, String predName, FunctionTypeEnum actionKind)
241
        {
242
                m_emitter.AppendLine("");
243
                m_emitter.AppendLine("%emit " + actionKind.toString() + " actions");
244
                m_emitter.Append(predName + "([");
245
                int y = 0;
246
                for (final Identifier x: mainModule.instance().symbols().symbolList())
247
                {
248
                        if (x.kind() == IdentifierKind.NamedActionIdentifier)
249
                        {
250
                                if (((FunctionType)((NamedActionIdentifier)x).type()).functionType() == actionKind)
251
                                {
252
                                        if (y != 0)
253
                                                m_emitter.Append(", ");
254
                                        else
255
                                                y++;
256
                                        final OoaPrologIdentifier pIdent = m_idFactory.create();
257

    
258
                                        ((NamedActionIdentifier)x).Accept(pIdent);
259
                                        m_emitter.Append(pIdent.toString());
260
                                }
261
                        }
262
                }
263
                m_emitter.AppendLine("]).");
264
                return y;
265
        }
266

    
267
        protected int ExportControllableActions(MainModule mainModule) {
268
                return ExportActions(mainModule, "input", FunctionTypeEnum.Controllable);
269
        }
270

    
271
        protected int ExportObservableActions(MainModule mainModule) {
272
                return ExportActions(mainModule, "output", FunctionTypeEnum.Observable);
273
        }
274

    
275
        protected void ExportInitialState(MainModule mainModule)
276
        {
277
                m_emitter.AppendLine("");
278
                m_emitter.AppendLine("%emit initial state");
279
                final ArrayList<String> initPreds = new ArrayList<String>();
280
                final ArrayList<String> initVars = new ArrayList<String>();
281
                int y = 0;
282
                for (final Identifier x: mainModule.instance().symbols().symbolList())
283
                {
284
                        if (x.kind() == IdentifierKind.AttributeIdentifier)
285
                        {
286
                                final OoaPrologExpression anExprVis = createExpressionVisitor();
287
                                ((AttributeIdentifier)x).initializer().Accept(anExprVis);
288
                                assert(anExprVis.tmpVariables().size() == 1);
289
                                final String initPredName = String.format("attr_%s_init(%s)", x.tokenText(), anExprVis.tmpVariables().get(0));
290
                                m_emitter.AppendLine(String.format("%s :- %s 1=1.", initPredName, anExprVis.toString()));
291
                                initPreds.add(initPredName);
292
                                initVars.add(anExprVis.tmpVariables().get(0));
293
                        }
294
                }
295

    
296

    
297
                m_emitter.Append("init([");
298
                y = 0;
299
                for (final String x: initVars)
300
                {
301
                        if (y != 0)
302
                                m_emitter.Append(",");
303
                        else
304
                                y++;
305
                        m_emitter.Append(x);
306
                }
307
                m_emitter.Append("]) :-");
308
                y = 0;
309
                for (final String x: initPreds)
310
                {
311
                        if (y != 0)
312
                                m_emitter.Append(",");
313
                        else
314
                                y++;
315
                        m_emitter.Append(x);
316
                }
317
                m_emitter.AppendLine(".");
318
        }
319

    
320
        protected int ExportState(MainModule mainModule)
321
        {
322
                m_emitter.AppendLine("");
323
                m_emitter.AppendLine("%emit state definition");
324
                m_emitter.Append("state_def([");
325
                int y = 0;
326
                for (final Identifier x: mainModule.instance().symbols().symbolList())
327
                {
328
                        if (x.kind() == IdentifierKind.AttributeIdentifier)
329
                        {
330
                                if (y != 0)
331
                                        m_emitter.Append(", ");
332
                                else
333
                                        y++;
334
                                final OoaPrologIdentifier pid = m_idFactory.create();
335
                                x.Accept(pid);
336
                                m_emitter.Append(pid.toString());
337
                        }
338
                }
339
                m_emitter.AppendLine("]).");
340
                return y;
341
        }
342

    
343
        protected void ExportVariables(MainModule mainModule)
344
        {
345
                m_emitter.AppendLine("");
346
                m_emitter.AppendLine("%emit type of state variables");
347
                final OoasCompilerHashMap<String, StringBuilder> varlist = new OoasCompilerHashMap<String, StringBuilder>();
348
                for (final Identifier x: mainModule.instance().symbols().symbolList())
349
                {
350
                        if (x.kind() == IdentifierKind.AttributeIdentifier)
351
                        {
352
                                final OoaPrologIdentifier pid = m_idFactory.create();
353
                                final OoaPrologType ptype = createTypeVisitor();
354
                                x.Accept(pid);
355
                                x.type().Accept(ptype);
356

    
357
                                final String key = ptype.toString();
358
                                if (varlist.containsKey(key))
359
                                {
360
                                        varlist.get(key).append(String.format(", %s", pid.toString()));
361
                                }
362
                                else
363
                                {
364
                                        varlist.putSafe(key, new StringBuilder(String.format("[%s", pid.toString())));
365
                                }
366
                        }
367
                }
368
                for (final String key: varlist.keySet())
369
                        m_emitter.AppendLine(String.format("var(%s], %s).", varlist.get(key), key));
370
        }
371

    
372
        protected void ExportTypes(MainModule mainModule)
373
        {
374
                for (final Identifier x: mainModule.symbolTable().symbolList())
375
                {
376
                        if (x.kind() == IdentifierKind.TypeIdentifier)
377
                                OoaPrologType.EmitType(((TypeIdentifier)x).type(), m_idFactory, m_scratchbook);
378
                }
379
        }
380

    
381

    
382
        @Override
383
        public /*override*/ void visit(MainModule mainModule)
384
        {
385
                m_emitter.AppendLine("% OOAS Compiler Generated");
386
//                m_emitter.AppendLine(String.format("%%%s", Mogentes.Program.GetProgramVersion().toString().Replace(Environment.NewLine, Environment.NewLine + "%")));
387
                m_emitter.AppendLine("% Code-Gen Version: 0.2");
388
                m_emitter.Append("%        Generated: "); m_emitter.AppendLine(new Date().toString());
389
                m_emitter.AppendLine("%------------------------------------------------------------------------");
390
                m_emitter.AppendLine("");
391
                m_emitter.AppendLine(String.format(":- module(%s, [var/2, input/1, searchDepth/1, qspace/2]).", m_nameSpace));
392
                m_emitter.AppendLine(":- use_module(library(file_systems)).");
393
                m_emitter.AppendLine(":- use_module(library(process)).");
394
                m_emitter.AppendLine(":- use_module(library(clpfd)).");
395
                m_emitter.AppendLine(":- use_module(library(clpb)).");
396
                m_emitter.AppendLine(":- use_module(library(lists)).");
397
                m_emitter.AppendLine(":- use_module(library(avl)).");
398
                m_emitter.AppendLine(":- use_module(library(ordsets)).");
399
                m_emitter.AppendLine(":- use_module(library(system)).");
400
                m_emitter.AppendLine("% :- use_module(library(gauge)). % this is a debug lib not supported on Win.");
401
                m_emitter.AppendLine(":- use_module(library(terms)).");
402
                m_emitter.AppendLine(":- use_module(library(sets)).");
403
                m_emitter.AppendLine(":- use_module(library(random)).");
404

    
405
                m_emitter.AppendLine(":- use_module(ulysseslib, _, [ulyssesListHead/2, ulyssesListLength/2, ulyssesListTail/2, ulyssesListConc/3, ulyssesTupleAccess/3, ulyssesListAccess/3, ulyssesListWrite/4, ulyssesMapAccess/3]).");
406

    
407
                m_emitter.AppendLine(":- public(as/0).");
408
                m_emitter.AppendLine(":- dynamic(as/0).");
409
                m_emitter.AppendLine(":- dynamic(qstate_init/1).");
410
                m_emitter.AppendLine(":- dynamic(qstate_constraints/1).");
411
                m_emitter.AppendLine(":- public(qstate_init/1).");
412
                m_emitter.AppendLine(":- public(qstate_constraints/1).");
413

    
414
                /*definition of search depth*/
415
                m_emitter.AppendLine("");
416
                m_emitter.AppendLine("% maximal search depth (change at will)");
417
                // FIXME: HACK
418
                m_emitter.AppendLine(String.format("searchDepth(%s).", m_maxSearchDepth));
419
                m_emitter.AppendLine("");
420

    
421
                /*definition of types*/
422
                ExportTypes(mainModule);
423
                /* variable definition */
424
                ExportVariables(mainModule);
425

    
426
                /* state definition */
427
                ExportState(mainModule);
428
                /* initial state */
429
                ExportInitialState(mainModule);
430
                /* input actions (controllables) */
431
                ExportControllableActions(mainModule);
432
                /* output actions (observables) */
433
                ExportObservableActions(mainModule);
434
                /* named actions */
435
                ExportMethodsAndActions(mainModule);
436

    
437
                /* all types */
438
                m_emitter.AppendLine("%definition of types");
439
                m_emitter.AppendLine(m_scratchbook.typeDefinitions().toString());
440
                m_emitter.AppendLine(createTypeVisitor().GetInternalTypeDefinitions());
441

    
442
                for(final String line: m_ParserState.mappingInformation)
443
                        m_emitter.AppendLine("% " + line);
444
        }
445

    
446

    
447
        @Override
448
        public /*override*/ String toString()
449
        {
450
                return m_emitter.toString();
451
        }
452

    
453
        protected OoaPrologIdentifier createIdentifierVisitor() { return m_idFactory.create(); }
454
        protected OoaPrologType createTypeVisitor() { return m_typeFactory.create(m_idFactory, m_scratchbook); }
455
        protected OoaPrologExpression createExpressionVisitor() { return m_exprFactory.create(m_idFactory, m_typeFactory, m_scratchbook); }
456
        protected OoaPrologStatement createStatementVisitor() { return m_stmtFactory.create(m_exprFactory, m_idFactory, m_typeFactory, m_scratchbook); }
457
        protected final String m_nameSpace;
458
        protected final int m_maxSearchDepth;
459

    
460

    
461
        private final  OoaPrologExpression.Factory m_exprFactory;
462
        private final OoaPrologIdentifier.Factory m_idFactory;
463
        private final OoaPrologStatement.Factory m_stmtFactory;
464
        private final OoaPrologType.Factory m_typeFactory;
465

    
466
        protected OoaPrologVisitor(
467
                        ParserState aState,
468
                        int maxSearchDepth,
469
                        String nameSpace,
470
                        OoaPrologExpression.Factory exprFactory,
471
                        OoaPrologIdentifier.Factory idFactory,
472
                        OoaPrologStatement.Factory  stmtFactory,
473
                        OoaPrologType.Factory       tpeFactory)
474
        {
475
                super(aState);
476
                m_maxSearchDepth = maxSearchDepth;
477
                m_nameSpace = nameSpace;
478
                m_emitter = new OoasCodeEmitter();
479
                m_exprFactory = exprFactory;
480
                m_idFactory = idFactory;
481
                m_stmtFactory = stmtFactory;
482
                m_typeFactory = tpeFactory;
483
        }
484

    
485
        public OoaPrologVisitor(ParserState aState, int maxSearchDepth, String nameSpace) {
486
                this(
487
                                aState,
488
                                maxSearchDepth,
489
                                nameSpace,
490
                                new OoaPrologExpression.Factory(),
491
                                new OoaPrologIdentifier.Factory(),
492
                                new OoaPrologStatement.Factory(),
493
                                new OoaPrologType.Factory());
494
        }
495
}