--/////////////////////////////////////////////////////////////////////////////
-- Copyright (c) 2000-2021 Ericsson Telecom AB
-- All rights reserved. This program and the accompanying materials
-- are made available under the terms of the Eclipse Public License v2.0
-- which accompanies this distribution, and is available at
-- https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
--
-- Contributors:
--   Balasko, Jeno
--   Raduly, Csaba
--
--/////////////////////////////////////////////////////////////////////////////
ObjectClassWithSyntax DEFINITIONS
  AUTOMATIC TAGS ::=
BEGIN 

IMPORTS /* nothing */ ;


MatrixWS ::= SEQUENCE OF SEQUENCE OF INTEGER

TwoMatWS ::= [9] SEQUENCE {
  left  MatrixWS,
  right MatrixWS
}


zeroWS MatrixWS ::=
{{0, 0, 0, 0},
 {0, 0, 0, 0},
 {0, 0, 0, 0},
 {0, 0, 0, 0}}

identityWS MatrixWS ::=
{{1, 0, 0, 0},
 {0, 1, 0, 0},
 {0, 0, 1, 0},
 {0, 0, 0, 1}}

pimatWS MatrixWS ::=
{{3, 1, 4, 1},
 {5, 9, 2, 6},
 {5, 3, 5, 8},
 {9, 7, 9, 3}}

invpimatWS MatrixWS ::= -- the adjugate of pimat
{{-467, -123,   79,   191},
 { 171,   57,  -39,   -67},
 { 326,   76,  -52,  -122},
 {  24,    8,   10,   -18}}

matrixPairWS TwoMatWS ::= { left identityWS, right pimatWS }


-- object class definition


OPERATIONWS ::= CLASS
{
  &ArgumentType OPTIONAL,
  &ResultType OPTIONAL,
  &Errors ERRORWS OPTIONAL,
  &Linked OPERATIONWS OPTIONAL,
  &resultReturned BOOLEAN DEFAULT TRUE,
  &operationCode PrintableString UNIQUE
}
WITH SYNTAX
{
  [ARGUMENT &ArgumentType]
  [RESULT &ResultType]
  [RETURN RESULT &resultReturned]
  [ERRORS &Errors]
  [LINKED &Linked]
  CODE &operationCode
}


ERRORWS ::= CLASS
{
  &ParameterType OPTIONAL,
  &errorCode INTEGER UNIQUE
}
WITH SYNTAX
{
  [PARAMETER &ParameterType]
  CODE &errorCode
}


-- object assignment, defined syntax

invertMatrixWS OPERATIONWS ::=
{
  ARGUMENT MatrixWS
  RESULT   MatrixWS
  ERRORS {determinantIsZeroWS}
  CODE "invert"
}

determinantIsZeroWS ERRORWS ::=
{
  CODE 1
}

addMatricesWS OPERATIONWS ::=
{
  ARGUMENT TwoMatWS
  RESULT MatrixWS
  ERRORS {sizeMismatchWS}
  CODE "add"
}

subtractMatricesWS OPERATIONWS ::=
{
  ARGUMENT TwoMatWS
  RESULT MatrixWS
  ERRORS {sizeMismatchWS}
  CODE "subtract"
}


sizeMismatchWS ERRORWS ::=
{
  CODE 2
}


-- object set

MatrixOperationsWS OPERATIONWS ::=
{
  invertMatrixWS
  | addMatricesWS
  | subtractMatricesWS
--  | multiplyMatrices
}

-- types

MatOpWS ::= SEQUENCE {
  op  OPERATIONWS.&operationCode ({MatrixOperationsWS}),
  arg OPERATIONWS.&ArgumentType  ({MatrixOperationsWS} {@op}),
  rez OPERATIONWS.&ResultType    ({MatrixOperationsWS} {@op})
  -- This is not how a real protocol would be put together
}

-- objects

additionWS MatOpWS ::= {
  op "add",
  arg twoMatWS : { left zeroWS, right pimatWS },
  rez matrixWS : pimatWS
}

subtractionWS MatOpWS ::= {
  op "subtract",
  arg twoMatWS : { left identityWS, right identityWS },
  rez matrixWS : zeroWS
}

inversionWS MatOpWS ::= {
  op "invert",
  arg matrixWS : pimatWS,
  rez matrixWS : invpimatWS
}

/*
addMatrices OPERATION ::=
{
  ARGUMENT SEQUENCE {
    left  Matrix,
    right Matrix
  }
  RESULT Matrix
  ERRORS {sizeMismatch}
  CODE 8
}

-- Titan can't handle the inline type for arg
two-plus-two MatOp ::= {
  op 8,
  arg SEQUENCE { left Matrix, right Matrix } : { left zero, right identity },
  rez matrix : zero
}

*/

-- -- -- -- -- Handmade types -- -- -- -- --

AMat ::= SEQUENCE OF SEQUENCE OF INTEGER
ATwoMat ::= SEQUENCE { left AMat, right AMat }

AMatOp-arg-type ::= CHOICE { matrix AMat, twoMat ATwoMat }
AMatOp-rez-type ::= CHOICE { matrix AMat }

AMatOp ::= SEQUENCE {
  oph  PrintableString,
  argh AMatOp-arg-type,
  rezh AMatOp-rez-type
}

-- -- -- -- -- Handmade values -- -- -- -- --

mat-zero AMat ::= { {0,0}, {0,0} }
mat-one  AMat ::= { {1,0}, {0,1} }

matmul AMatOp ::= {
  oph  "mul",
  argh twoMat : { left mat-zero, right mat-one },
  rezh matrix : mat-zero
}

matinv AMatOp ::= {
  oph  "inv",
  argh matrix : mat-one,
  rezh matrix : mat-one
}

END
