Project

General

Profile

root / branches / compiler / cSharp / ooasCompiler / src / codegen / Prolog / ooaPrologVisitor.cs @ 3

1
/**
2
  *
3
  *                      OOAS Compiler (Deprecated)
4
  *
5
  * Copyright 2015, Institute for Software Technology, Graz University of
6
  * Technology. Portions are copyright 2015 by the AIT Austrian Institute
7
  * of Technology. All rights reserved.
8
  *
9
  * SEE THE "LICENSE" FILE FOR THE TERMS UNDER WHICH THIS FILE IS PROVIDED.
10
  *
11
  * Please notice that this version of the OOAS compiler is considered de-
12
  * precated. Only the Java version is maintained.
13
  *
14
  * Contributors:
15
  *               Willibald Krenn (TU Graz/AIT)
16
  *               Stefan Tiran (TU Graz/AIT)
17
  */
18

    
19
/*
20
 *  === Prolog Emitter ===
21
 *
22
 */
23

    
24
using System;
25
using System.Collections.Generic;
26
using System.Text;
27
using TUG.Mogentes;
28
using TUG.Mogentes.Codegen.Prolog;
29

    
30

    
31
namespace TUG.Mogentes.Codegen
32
{
33
    public class OoaPrologVisitor : OoaCompleteAstTraversalVisitor
34
    {
35
        protected OoaCodeEmitter m_emitter;
36

    
37
        private string PrologIdentifier(Identifier id)
38
        {
39
            OoaPrologIdentifier identifierVisitor = m_idFactory.create();
40
            id.Accept(identifierVisitor);
41
            return identifierVisitor.ToString();
42
        }
43

    
44
        protected void ExportMethodsAndActions(MainModule mainModule)
45
        {
46
            StringBuilder varActions = new StringBuilder();
47
            m_emitter.AppendLine();
48
            m_emitter.AppendLine("% action system");
49
            m_emitter.AppendLineIncIndent("as :- ");
50

    
51
            /* export methods */
52
            m_emitter.AppendLine("methods (");
53
            ExportMethods(mainModule);
54
            m_emitter.AppendLine("), ");
55
            m_emitter.AppendLine("actions (");
56
            ExportNamedActions(mainModule, varActions);
57
            m_emitter.AppendLine("), ");
58
            m_emitter.AppendLine("dood (");
59

    
60
            ExportDoOdBlock(mainModule.instance.doOdBlock, m_emitter);
61

    
62

    
63
            m_emitter.AppendLine("), qdes (none)");
64
            m_emitter.DecIndent();
65
            m_emitter.AppendLine(".");
66
            m_emitter.AppendLine("");
67

    
68
            m_emitter.Append(varActions.ToString());
69
        }
70

    
71
        private void ExportMethods(MainModule mainModule)
72
        {
73
            int y = 0;
74
            foreach (var x in mainModule.instance.symbols.symbolList)
75
            {
76
                if (x.kind == IdentifierKind.MethodIdentifier)
77
                {
78
                    if (y != 0)
79
                        m_emitter.AppendLine(", ");
80
                    else
81
                        y++;
82

    
83
                    MethodIdentifier theMethod = (MethodIdentifier)x;
84
                    OoaPrologIdentifier pIdent = m_idFactory.create();
85
                    theMethod.Accept(pIdent);
86

    
87
                    /* method */
88
                    StringBuilder parameter = new StringBuilder();
89
                    if (theMethod.parameter.Count > 0 || ((FunctionType)theMethod.type).returnType != null)
90
                    {
91
                        parameter.Append("(");
92
                        int z = 0;
93
                        foreach (var param in theMethod.parameter)
94
                        {
95
                            if (z != 0)
96
                            {
97
                                parameter.Append(", ");
98
                            }
99
                            else
100
                                z++;
101
                            OoaPrologIdentifier pParamIdent = m_idFactory.create();
102
                            param.Accept(pParamIdent);
103
                            parameter.Append(pParamIdent.ToString());
104
                        }
105

    
106

    
107
                        if (((FunctionType)theMethod.type).returnType != null)
108
                        {
109
                            if (z != 0)
110
                                parameter.Append(", ");
111
                            parameter.Append("RESULT");
112
                        }
113
                        parameter.Append(")");
114
                    }
115
                    m_emitter.AppendLineIncIndent(String.Format("{0}{1} = (", pIdent.ToString(), parameter.ToString()));
116

    
117
                    OoaPrologStatement pBody = createStatementVisitor();
118
                    ((MethodIdentifier)x).body.Accept(pBody);
119
                    m_emitter.Append(pBody.ToString());
120
                    m_emitter.Append(")");
121
                    m_emitter.DecIndent();
122
                }
123
            }
124
            if (y == 0)
125
                m_emitter.Append(" none ");
126
        }
127

    
128
        private void ExportNamedActions(MainModule mainModule, StringBuilder varActions)
129
        {
130
            int y = 0;
131
            foreach (var x in mainModule.instance.symbols.symbolList)
132
            {
133
                if (x.kind == IdentifierKind.NamedActionIdentifier)
134
                {
135
                    if (y != 0)
136
                        m_emitter.AppendLine(", ");
137
                    else
138
                        y++;
139
                    NamedActionIdentifier action = (NamedActionIdentifier)x;
140
                    OoaPrologIdentifier pIdent = m_idFactory.create();
141
                    action.Accept(pIdent);
142

    
143
                    if (((FunctionType)action.type).functionType != FunctionTypeEnum.Continuous)
144
                    {
145
                        /* discrete actions */
146
                        StringBuilder parameter = new StringBuilder();
147
                        StringBuilder parametertype = new StringBuilder();
148
                        if (action.parameter.Count > 0)
149
                        {
150
                            parameter.Append("(");
151
                            parametertype.Append("(");
152
                            int z = 0;
153
                            foreach (var param in action.parameter)
154
                            {
155
                                if (z != 0)
156
                                {
157
                                    parameter.Append(", ");
158
                                    parametertype.Append(", ");
159
                                }
160
                                else
161
                                    z++;
162
                                OoaPrologIdentifier pParamIdent = m_idFactory.create();
163
                                param.Accept(pParamIdent);
164
                                parameter.Append(pParamIdent.ToString());
165

    
166
                                OoaPrologType pParamType = createTypeVisitor();  // bugfix me!
167
                                param.type.Accept(pParamType);
168
                                parametertype.Append(pParamType.ToString());
169

    
170
                            }
171
                            parametertype.Append(")");
172
                            parameter.Append(")");
173
                        }
174
                        //if (parametertype.Length > 0)
175
                        //    varActions.AppendLine(String.Format("{0}{1}.", pIdent.ToString(), parametertype.ToString()));
176
                        m_emitter.AppendLineIncIndent(String.Format("{0}{1}::", pIdent.ToString(), parameter.ToString()));
177
                    }
178
                    else
179
                    {
180
                        /* observable state vars outside... */
181
                        StringBuilder parameter = new StringBuilder();
182
                        int z = 0;
183
                        foreach (var stmt in ((GuardedCommand)action.body.statements.First.Value).body.statements)
184
                        {
185
                            QualitativeConstraintStatement qstmt = (QualitativeConstraintStatement)stmt;
186
                            if (qstmt.operation == QualitativeConstraintOperation.Equal
187
                                && qstmt.variable1.kind == IdentifierKind.AttributeIdentifier
188
                                && ((AttributeIdentifier)qstmt.variable1).isObservable)
189
                            {
190
                                if (z != 0)
191
                                    parameter.Append(", ");
192
                                else
193
                                    z++;
194
                                qstmt.tag = true;
195
                                OoaPrologIdentifier pParamIdent1 = m_idFactory.create();
196
                                OoaPrologIdentifier pParamIdent2 = m_idFactory.create();
197
                                qstmt.variable0.Accept(pParamIdent1);
198
                                qstmt.variable1.Accept(pParamIdent2);
199
                                parameter.Append(String.Format("{0}({1})", pParamIdent2.ToString(), pParamIdent1.ToString()));
200
                            }
201
                        }
202
                        m_emitter.AppendLineIncIndent(String.Format("[{0}]::", parameter.ToString()));
203
                    }
204

    
205
                    OoaPrologStatement pBody = createStatementVisitor();
206
                    ((NamedActionIdentifier)x).body.Accept(pBody);
207
                    m_emitter.Append(pBody.ToString());
208
                    m_emitter.DecIndent();
209

    
210
                }
211
            }
212
        }
213

    
214
        private void ExportDoOdBlock(Block block, OoaCodeEmitter m_emitter)
215
        {
216
            OoaPrologStatement statement = createStatementVisitor();
217
            block.Accept(statement);
218
            m_emitter.Append(statement.ToString());
219
        }
220

    
221
        protected int ExportControllableActions(MainModule mainModule)
222
        {
223
            m_emitter.AppendLine("");
224
            m_emitter.AppendLine("%emit controllable actions");
225
            m_emitter.Append("input([");
226
            int y = 0;
227
            foreach (var x in mainModule.instance.symbols.symbolList)
228
            {
229
                if (x.kind == IdentifierKind.NamedActionIdentifier)
230
                {
231
                    if (((FunctionType)((NamedActionIdentifier)x).type).functionType == FunctionTypeEnum.Controllable)
232
                    {
233
                        if (y != 0)
234
                            m_emitter.Append(", ");
235
                        else
236
                            y++;
237
                        OoaPrologIdentifier pIdent = m_idFactory.create();
238

    
239
                        ((NamedActionIdentifier)x).Accept(pIdent);
240
                        m_emitter.Append(pIdent.ToString());
241
                    }
242
                }
243
            }
244
            m_emitter.AppendLine("]).");
245
            return y;
246
        }
247

    
248
        protected int ExportObservableActions(MainModule mainModule)
249
        {
250
            m_emitter.AppendLine("");
251
            m_emitter.AppendLine("%emit observable actions");
252
            m_emitter.Append("output([");
253
            int y = 0;
254
            foreach (var x in mainModule.instance.symbols.symbolList)
255
            {
256
                if (x.kind == IdentifierKind.NamedActionIdentifier)
257
                {
258
                    if (((FunctionType)((NamedActionIdentifier)x).type).functionType == FunctionTypeEnum.Observable)
259
                    {
260
                        if (y != 0)
261
                            m_emitter.Append(", ");
262
                        else
263
                            y++;
264
                        OoaPrologIdentifier pIdent = m_idFactory.create();
265

    
266
                        ((NamedActionIdentifier)x).Accept(pIdent);
267
                        m_emitter.Append(pIdent.ToString());
268
                    }
269
                }
270
            }
271
            m_emitter.AppendLine("]).");
272
            return y;
273
        }
274

    
275
        protected void ExportInitialState(MainModule mainModule)
276
        {
277
            m_emitter.AppendLine("");
278
            m_emitter.AppendLine("%emit initial state");
279
            List<string> initPreds = new List<string>();
280
            List<string> initVars = new List<string>();
281
            int y = 0;
282
            foreach (var x in mainModule.instance.symbols.symbolList)
283
            {
284
                if (x.kind == IdentifierKind.AttributeIdentifier)
285
                {
286
                    OoaPrologExpression anExprVis = createExpressionVisitor();
287
                    ((AttributeIdentifier)x).initializer.Accept(anExprVis);
288
                    System.Diagnostics.Debug.Assert(anExprVis.tmpVariables.Count == 1);
289
                    string initPredName = String.Format("attr_{0}_init({1})", x.tokenText, anExprVis.tmpVariables[0]);
290
                    m_emitter.AppendLine(String.Format("{0} :- {1} 1=1.", initPredName, anExprVis.ToString()));
291
                    initPreds.Add(initPredName);
292
                    initVars.Add(anExprVis.tmpVariables[0]);
293
                }
294
            }
295

    
296

    
297
            m_emitter.Append("init([");
298
            y = 0;
299
            foreach (var x in 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
            foreach (var x in 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
            foreach (var x in 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
                    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
            Dictionary<string, StringBuilder> varlist = new Dictionary<string, StringBuilder>();
348
            foreach (var x in mainModule.instance.symbols.symbolList)
349
            {
350
                if (x.kind == IdentifierKind.AttributeIdentifier)
351
                {
352
                    OoaPrologIdentifier pid = m_idFactory.create();
353
                    OoaPrologType ptype = createTypeVisitor();
354
                    x.Accept(pid);
355
                    x.type.Accept(ptype);
356

    
357
                    string key = x.type.kind != TypeKind.QrType ? ptype.ToString() : "qvar";
358
                    if (varlist.ContainsKey(key))
359
                    {
360
                        varlist[key].Append(String.Format(", {0}", pid.ToString()));
361
                    }
362
                    else
363
                    {
364
                        varlist.Add(key, new StringBuilder(String.Format("[{0}", pid.ToString())));
365
                    }
366
                }
367
            }
368
            foreach (var key in varlist.Keys)
369
                m_emitter.AppendLine(String.Format("var({0}], {1}).", varlist[key], key));
370
        }
371

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

    
381

    
382
        public override void visit(MainModule mainModule)
383
        {
384
            m_emitter.AppendLine("% Argos Generated");
385
            m_emitter.AppendLine(String.Format("%{0}", Mogentes.Program.GetProgramVersion().ToString().Replace(Environment.NewLine, Environment.NewLine + "%")));
386
            m_emitter.AppendLine("% Code-Gen Version: 0.2");
387
            m_emitter.Append("%        Generated: "); m_emitter.AppendLine(System.DateTime.Now.ToString());
388
            m_emitter.AppendLine("%------------------------------------------------------------------------");
389
            m_emitter.AppendLine("");
390
            String nameSpace = TUG.Mogentes.Program.Options.nameSpace;
391
            m_emitter.AppendLine(":- module("+nameSpace+", [var/2, input/1, searchDepth/1, qspace/2]).");
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)).");
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
            m_emitter.AppendLine("searchDepth("+TUG.Mogentes.Program.Options.searchDepth+").");
418
            m_emitter.AppendLine("");
419

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

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

    
436
            /* all types */
437
            m_emitter.AppendLine("%definition of types");
438
            m_emitter.AppendLine(OoaPrologType.typeDefinitions.ToString());
439
            m_emitter.AppendLine(createTypeVisitor().GetInternalTypeDefinitions());
440
        }
441

    
442

    
443
        public override string ToString()
444
        {
445
            return m_emitter.ToString();
446
        }
447

    
448
        protected OoaPrologIdentifier createIdentifierVisitor() { return m_idFactory.create(); }
449
        protected OoaPrologType createTypeVisitor() { return m_typeFactory.create(m_idFactory); }
450
        protected OoaPrologExpression createExpressionVisitor() { return m_exprFactory.create(m_idFactory, m_typeFactory); }
451
        protected OoaPrologStatement createStatementVisitor() { return m_stmtFactory.create(m_exprFactory, m_idFactory, m_typeFactory); }
452

    
453
        private readonly  OoaPrologExpression.Factory m_exprFactory;
454
        private readonly OoaPrologIdentifier.Factory m_idFactory;
455
        private readonly OoaPrologStatement.Factory m_stmtFactory;
456
        private readonly OoaPrologType.Factory m_typeFactory;
457

    
458
        protected OoaPrologVisitor(
459
            ParserState aState, 
460
            OoaPrologExpression.Factory exprFactory,
461
            OoaPrologIdentifier.Factory idFactory,
462
            OoaPrologStatement.Factory  stmtFactory,
463
            OoaPrologType.Factory       tpeFactory) 
464
            : base(aState)
465
        {
466
            m_emitter = new OoaCodeEmitter();
467
            m_exprFactory = exprFactory;
468
            m_idFactory = idFactory;
469
            m_stmtFactory = stmtFactory;
470
            m_typeFactory = tpeFactory;
471
        }
472

    
473
        public OoaPrologVisitor(ParserState aState)
474
            : this(
475
                aState,
476
                new OoaPrologExpression.Factory(),
477
                new OoaPrologIdentifier.Factory(),
478
                new OoaPrologStatement.Factory(),
479
                new OoaPrologType.Factory())
480
        { }
481
    }
482
}