/** * * OOAS Compiler (Deprecated) * * Copyright 2015, Institute for Software Technology, Graz University of * Technology. Portions are copyright 2015 by the AIT Austrian Institute * of Technology. All rights reserved. * * SEE THE "LICENSE" FILE FOR THE TERMS UNDER WHICH THIS FILE IS PROVIDED. * * Please notice that this version of the OOAS compiler is considered de- * precated. Only the Java version is maintained. * * Contributors: * Willibald Krenn (TU Graz/AIT) * Stefan Tiran (TU Graz/AIT) */ /* * === Prolog Emitter === * */ using System; using System.Collections.Generic; using System.Text; using TUG.Mogentes; using TUG.Mogentes.Codegen.Prolog; namespace TUG.Mogentes.Codegen { public class OoaPrologVisitor : OoaCompleteAstTraversalVisitor { protected OoaCodeEmitter m_emitter; private string PrologIdentifier(Identifier id) { OoaPrologIdentifier identifierVisitor = m_idFactory.create(); id.Accept(identifierVisitor); return identifierVisitor.ToString(); } protected void ExportMethodsAndActions(MainModule mainModule) { StringBuilder varActions = new StringBuilder(); m_emitter.AppendLine(); m_emitter.AppendLine("% action system"); m_emitter.AppendLineIncIndent("as :- "); /* export methods */ m_emitter.AppendLine("methods ("); ExportMethods(mainModule); m_emitter.AppendLine("), "); m_emitter.AppendLine("actions ("); ExportNamedActions(mainModule, varActions); m_emitter.AppendLine("), "); m_emitter.AppendLine("dood ("); ExportDoOdBlock(mainModule.instance.doOdBlock, m_emitter); m_emitter.AppendLine("), qdes (none)"); m_emitter.DecIndent(); m_emitter.AppendLine("."); m_emitter.AppendLine(""); m_emitter.Append(varActions.ToString()); } private void ExportMethods(MainModule mainModule) { int y = 0; foreach (var x in mainModule.instance.symbols.symbolList) { if (x.kind == IdentifierKind.MethodIdentifier) { if (y != 0) m_emitter.AppendLine(", "); else y++; MethodIdentifier theMethod = (MethodIdentifier)x; OoaPrologIdentifier pIdent = m_idFactory.create(); theMethod.Accept(pIdent); /* method */ StringBuilder parameter = new StringBuilder(); if (theMethod.parameter.Count > 0 || ((FunctionType)theMethod.type).returnType != null) { parameter.Append("("); int z = 0; foreach (var param in theMethod.parameter) { if (z != 0) { parameter.Append(", "); } else z++; OoaPrologIdentifier pParamIdent = m_idFactory.create(); param.Accept(pParamIdent); parameter.Append(pParamIdent.ToString()); } if (((FunctionType)theMethod.type).returnType != null) { if (z != 0) parameter.Append(", "); parameter.Append("RESULT"); } parameter.Append(")"); } m_emitter.AppendLineIncIndent(String.Format("{0}{1} = (", pIdent.ToString(), parameter.ToString())); OoaPrologStatement pBody = createStatementVisitor(); ((MethodIdentifier)x).body.Accept(pBody); m_emitter.Append(pBody.ToString()); m_emitter.Append(")"); m_emitter.DecIndent(); } } if (y == 0) m_emitter.Append(" none "); } private void ExportNamedActions(MainModule mainModule, StringBuilder varActions) { int y = 0; foreach (var x in mainModule.instance.symbols.symbolList) { if (x.kind == IdentifierKind.NamedActionIdentifier) { if (y != 0) m_emitter.AppendLine(", "); else y++; NamedActionIdentifier action = (NamedActionIdentifier)x; OoaPrologIdentifier pIdent = m_idFactory.create(); action.Accept(pIdent); if (((FunctionType)action.type).functionType != FunctionTypeEnum.Continuous) { /* discrete actions */ StringBuilder parameter = new StringBuilder(); StringBuilder parametertype = new StringBuilder(); if (action.parameter.Count > 0) { parameter.Append("("); parametertype.Append("("); int z = 0; foreach (var param in action.parameter) { if (z != 0) { parameter.Append(", "); parametertype.Append(", "); } else z++; OoaPrologIdentifier pParamIdent = m_idFactory.create(); param.Accept(pParamIdent); parameter.Append(pParamIdent.ToString()); OoaPrologType pParamType = createTypeVisitor(); // bugfix me! param.type.Accept(pParamType); parametertype.Append(pParamType.ToString()); } parametertype.Append(")"); parameter.Append(")"); } //if (parametertype.Length > 0) // varActions.AppendLine(String.Format("{0}{1}.", pIdent.ToString(), parametertype.ToString())); m_emitter.AppendLineIncIndent(String.Format("{0}{1}::", pIdent.ToString(), parameter.ToString())); } else { /* observable state vars outside... */ StringBuilder parameter = new StringBuilder(); int z = 0; foreach (var stmt in ((GuardedCommand)action.body.statements.First.Value).body.statements) { QualitativeConstraintStatement qstmt = (QualitativeConstraintStatement)stmt; if (qstmt.operation == QualitativeConstraintOperation.Equal && qstmt.variable1.kind == IdentifierKind.AttributeIdentifier && ((AttributeIdentifier)qstmt.variable1).isObservable) { if (z != 0) parameter.Append(", "); else z++; qstmt.tag = true; OoaPrologIdentifier pParamIdent1 = m_idFactory.create(); OoaPrologIdentifier pParamIdent2 = m_idFactory.create(); qstmt.variable0.Accept(pParamIdent1); qstmt.variable1.Accept(pParamIdent2); parameter.Append(String.Format("{0}({1})", pParamIdent2.ToString(), pParamIdent1.ToString())); } } m_emitter.AppendLineIncIndent(String.Format("[{0}]::", parameter.ToString())); } OoaPrologStatement pBody = createStatementVisitor(); ((NamedActionIdentifier)x).body.Accept(pBody); m_emitter.Append(pBody.ToString()); m_emitter.DecIndent(); } } } private void ExportDoOdBlock(Block block, OoaCodeEmitter m_emitter) { OoaPrologStatement statement = createStatementVisitor(); block.Accept(statement); m_emitter.Append(statement.ToString()); } protected int ExportControllableActions(MainModule mainModule) { m_emitter.AppendLine(""); m_emitter.AppendLine("%emit controllable actions"); m_emitter.Append("input(["); int y = 0; foreach (var x in mainModule.instance.symbols.symbolList) { if (x.kind == IdentifierKind.NamedActionIdentifier) { if (((FunctionType)((NamedActionIdentifier)x).type).functionType == FunctionTypeEnum.Controllable) { if (y != 0) m_emitter.Append(", "); else y++; OoaPrologIdentifier pIdent = m_idFactory.create(); ((NamedActionIdentifier)x).Accept(pIdent); m_emitter.Append(pIdent.ToString()); } } } m_emitter.AppendLine("])."); return y; } protected int ExportObservableActions(MainModule mainModule) { m_emitter.AppendLine(""); m_emitter.AppendLine("%emit observable actions"); m_emitter.Append("output(["); int y = 0; foreach (var x in mainModule.instance.symbols.symbolList) { if (x.kind == IdentifierKind.NamedActionIdentifier) { if (((FunctionType)((NamedActionIdentifier)x).type).functionType == FunctionTypeEnum.Observable) { if (y != 0) m_emitter.Append(", "); else y++; OoaPrologIdentifier pIdent = m_idFactory.create(); ((NamedActionIdentifier)x).Accept(pIdent); m_emitter.Append(pIdent.ToString()); } } } m_emitter.AppendLine("])."); return y; } protected void ExportInitialState(MainModule mainModule) { m_emitter.AppendLine(""); m_emitter.AppendLine("%emit initial state"); List initPreds = new List(); List initVars = new List(); int y = 0; foreach (var x in mainModule.instance.symbols.symbolList) { if (x.kind == IdentifierKind.AttributeIdentifier) { OoaPrologExpression anExprVis = createExpressionVisitor(); ((AttributeIdentifier)x).initializer.Accept(anExprVis); System.Diagnostics.Debug.Assert(anExprVis.tmpVariables.Count == 1); string initPredName = String.Format("attr_{0}_init({1})", x.tokenText, anExprVis.tmpVariables[0]); m_emitter.AppendLine(String.Format("{0} :- {1} 1=1.", initPredName, anExprVis.ToString())); initPreds.Add(initPredName); initVars.Add(anExprVis.tmpVariables[0]); } } m_emitter.Append("init(["); y = 0; foreach (var x in initVars) { if (y != 0) m_emitter.Append(","); else y++; m_emitter.Append(x); } m_emitter.Append("]) :-"); y = 0; foreach (var x in initPreds) { if (y != 0) m_emitter.Append(","); else y++; m_emitter.Append(x); } m_emitter.AppendLine("."); } protected int ExportState(MainModule mainModule) { m_emitter.AppendLine(""); m_emitter.AppendLine("%emit state definition"); m_emitter.Append("state_def(["); int y = 0; foreach (var x in mainModule.instance.symbols.symbolList) { if (x.kind == IdentifierKind.AttributeIdentifier) { if (y != 0) m_emitter.Append(", "); else y++; OoaPrologIdentifier pid = m_idFactory.create(); x.Accept(pid); m_emitter.Append(pid.ToString()); } } m_emitter.AppendLine("])."); return y; } protected void ExportVariables(MainModule mainModule) { m_emitter.AppendLine(""); m_emitter.AppendLine("%emit type of state variables"); Dictionary varlist = new Dictionary(); foreach (var x in mainModule.instance.symbols.symbolList) { if (x.kind == IdentifierKind.AttributeIdentifier) { OoaPrologIdentifier pid = m_idFactory.create(); OoaPrologType ptype = createTypeVisitor(); x.Accept(pid); x.type.Accept(ptype); string key = x.type.kind != TypeKind.QrType ? ptype.ToString() : "qvar"; if (varlist.ContainsKey(key)) { varlist[key].Append(String.Format(", {0}", pid.ToString())); } else { varlist.Add(key, new StringBuilder(String.Format("[{0}", pid.ToString()))); } } } foreach (var key in varlist.Keys) m_emitter.AppendLine(String.Format("var({0}], {1}).", varlist[key], key)); } protected void ExportTypes(MainModule mainModule) { foreach (var x in mainModule.symbolTable.symbolList) { if (x.kind == IdentifierKind.TypeIdentifier) OoaPrologType.EmitType(((TypeIdentifier)x).type, m_idFactory); } } public override void visit(MainModule mainModule) { m_emitter.AppendLine("% Argos Generated"); m_emitter.AppendLine(String.Format("%{0}", Mogentes.Program.GetProgramVersion().ToString().Replace(Environment.NewLine, Environment.NewLine + "%"))); m_emitter.AppendLine("% Code-Gen Version: 0.2"); m_emitter.Append("% Generated: "); m_emitter.AppendLine(System.DateTime.Now.ToString()); m_emitter.AppendLine("%------------------------------------------------------------------------"); m_emitter.AppendLine(""); String nameSpace = TUG.Mogentes.Program.Options.nameSpace; m_emitter.AppendLine(":- module("+nameSpace+", [var/2, input/1, searchDepth/1, qspace/2])."); m_emitter.AppendLine(":- use_module(library(file_systems))."); m_emitter.AppendLine(":- use_module(library(process))."); m_emitter.AppendLine(":- use_module(library(clpfd))."); m_emitter.AppendLine(":- use_module(library(clpb))."); m_emitter.AppendLine(":- use_module(library(lists))."); m_emitter.AppendLine(":- use_module(library(avl))."); m_emitter.AppendLine(":- use_module(library(ordsets))."); m_emitter.AppendLine(":- use_module(library(system))."); //m_emitter.AppendLine(":- use_module(library(gauge))."); m_emitter.AppendLine(":- use_module(library(terms))."); m_emitter.AppendLine(":- use_module(library(sets))."); m_emitter.AppendLine(":- use_module(library(random))."); m_emitter.AppendLine(":- use_module(ulysseslib, _, [ulyssesListHead/2, ulyssesListLength/2, ulyssesListTail/2, ulyssesListConc/3, ulyssesTupleAccess/3, ulyssesListAccess/3, ulyssesListWrite/4, ulyssesMapAccess/3])."); m_emitter.AppendLine(":- public(as/0)."); m_emitter.AppendLine(":- dynamic(as/0)."); m_emitter.AppendLine(":- dynamic(qstate_init/1)."); m_emitter.AppendLine(":- dynamic(qstate_constraints/1)."); m_emitter.AppendLine(":- public(qstate_init/1)."); m_emitter.AppendLine(":- public(qstate_constraints/1)."); /*definition of search depth*/ m_emitter.AppendLine(""); m_emitter.AppendLine("% maximal search depth (change at will)"); m_emitter.AppendLine("searchDepth("+TUG.Mogentes.Program.Options.searchDepth+")."); m_emitter.AppendLine(""); /*definition of types*/ ExportTypes(mainModule); /* variable definition */ ExportVariables(mainModule); /* state definition */ ExportState(mainModule); /* initial state */ ExportInitialState(mainModule); /* input actions (controllables) */ ExportControllableActions(mainModule); /* output actions (observables) */ ExportObservableActions(mainModule); /* named actions */ ExportMethodsAndActions(mainModule); /* all types */ m_emitter.AppendLine("%definition of types"); m_emitter.AppendLine(OoaPrologType.typeDefinitions.ToString()); m_emitter.AppendLine(createTypeVisitor().GetInternalTypeDefinitions()); } public override string ToString() { return m_emitter.ToString(); } protected OoaPrologIdentifier createIdentifierVisitor() { return m_idFactory.create(); } protected OoaPrologType createTypeVisitor() { return m_typeFactory.create(m_idFactory); } protected OoaPrologExpression createExpressionVisitor() { return m_exprFactory.create(m_idFactory, m_typeFactory); } protected OoaPrologStatement createStatementVisitor() { return m_stmtFactory.create(m_exprFactory, m_idFactory, m_typeFactory); } private readonly OoaPrologExpression.Factory m_exprFactory; private readonly OoaPrologIdentifier.Factory m_idFactory; private readonly OoaPrologStatement.Factory m_stmtFactory; private readonly OoaPrologType.Factory m_typeFactory; protected OoaPrologVisitor( ParserState aState, OoaPrologExpression.Factory exprFactory, OoaPrologIdentifier.Factory idFactory, OoaPrologStatement.Factory stmtFactory, OoaPrologType.Factory tpeFactory) : base(aState) { m_emitter = new OoaCodeEmitter(); m_exprFactory = exprFactory; m_idFactory = idFactory; m_stmtFactory = stmtFactory; m_typeFactory = tpeFactory; } public OoaPrologVisitor(ParserState aState) : this( aState, new OoaPrologExpression.Factory(), new OoaPrologIdentifier.Factory(), new OoaPrologStatement.Factory(), new OoaPrologType.Factory()) { } } }