/******************************************************************************
 * 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
 *   Baranyi, Botond
 *   Delic, Adam
 *   Kovacs, Ferenc
 *   Raduly, Csaba
 *   Szabados, Kristof
 *   Szabo, Janos Zoltan – initial implementation
 *
 ******************************************************************************/
//it is working with only the legacy flag is off ( omit in value list is not allowed)
module TtemplateRec {

type record RP {
  record of record {
  integer i optional,
  charstring s
  } inner
}

type record SR { // simple record
  integer i
}

template RP t_r_all_omit := { { { omit, "omit" } } }


type component templateRec_mycomp {};
type record templateRec_myrec {
 integer f1,
 float f2 };
type record templateRec_rec {
 templateRec_myrec x1,
 templateRec_myrec x2,
 templateRec_myrec x3 optional };
template templateRec_rec templateRec_tSpec :={ //specific values
 x1:={f1:=1,f2:=1.2},
 x2:={f1:=2,f2:=1.2},
 x3:={f1:=3,f2:=1.2} };
template templateRec_rec templateRec_tList :={ //specific value and value list
 x1:={f1:=1,f2:=1.2},
 x2:=({f1:=2,f2:=1.2},{f1:=3,f2:=1.2},{f1:=6,f2:=1.2}),
 x3:={f1:=3,f2:=1.2} };
template templateRec_rec templateRec_tComp :={ //specific value and compl. list
 x1:={f1:=1,f2:=1.2},
 x2:=complement ({f1:=2,f2:=1.2},{f1:=3,f2:=1.2},{f1:=6,f2:=1.2}),
 x3:={f1:=3,f2:=1.2} };
template templateRec_rec templateRec_tOmit :={ //omitting values
 x1:={f1:=1,f2:=1.2},
 x2:={f1:=2,f2:=1.2},
 x3:=omit } ;
template templateRec_rec templateRec_tAny :={ //specific and any value
 x1:={f1:=1,f2:=1.2},
 x2:={f1:=2,f2:=1.2},
 x3:=? } ;
template templateRec_rec templateRec_tAnyorNone :={ //specific and AnyorNone value
 x1:={f1:=1,f2:=1.2},
 x2:={f1:=2,f2:=1.2},
 x3:=* };
template templateRec_rec templateRec_tIfpresent :={ //specific value and ifpresent
 x1:={f1:=1,f2:=1.2},
 x2:={f1:=2,f2:=1.2},
 x3:={f1:=3,f2:=1.2} ifpresent };

testcase pasu() runs on templateRec_mycomp
{
  template integer v_timeUnit              := 60;
  
  var template SR t_sr := { 13 }
  t_sr.i := v_timeUnit;

  template RP v_r modifies t_r_all_omit := {{{
    i := v_timeUnit
  }}}
  setverdict(pass); // if it compiles, that's enough
}

testcase templateRecSpec() runs on templateRec_mycomp {
var templateRec_myrec temp:={f1:=3,f2:=1.2};
var templateRec_rec x1,x2;		//specific value
x1:={ x1:={f1:=1,f2:=1.2},  x2:={f1:=2,f2:=1.2},  x3:=temp };
x2:={ x1:={f1:=2,f2:=1.2},  x2:={f1:=2,f2:=1.2},  x3:=temp };
//match
if (match(x1,templateRec_tSpec)) {setverdict(pass);}
 else {setverdict(fail);}
//no match
if (not(match(x2,templateRec_tSpec))) {setverdict(pass);}
 else {setverdict(fail);}
}

testcase templateRecList() runs on templateRec_mycomp {
var templateRec_myrec temp:={f1:=3,f2:=1.2};
var templateRec_rec x1,x2,x3;		//value list
x1:={ x1:={f1:=1,f2:=1.2},  x2:={f1:=6,f2:=1.2},  x3:=temp };
x2:={ x1:={f1:=1,f2:=1.2},  x2:={f1:=7,f2:=1.2},  x3:=temp };
x3:={ x1:={f1:=8,f2:=1.2},  x2:={f1:=6,f2:=1.2},  x3:=temp };
//match
if (match(x1,templateRec_tList)) {setverdict(pass);}
 else {setverdict(fail, 1);}
//no match: out of list
if (not(match(x2,templateRec_tList))) {setverdict(pass);}
 else {setverdict(fail, 2);}
//no match: other field
if (not(match(x3,templateRec_tList))) {setverdict(pass);}
 else {setverdict(fail, 3);}
}

testcase templateRecComp() runs on templateRec_mycomp {
var templateRec_myrec temp:={f1:=3,f2:=1.2};
var templateRec_rec x1,x2,x3;		//complemented list
x1:={ x1:={f1:=1,f2:=1.2},  x2:={f1:=7,f2:=1.2},  x3:=temp };
x2:={ x1:={f1:=1,f2:=1.2},  x2:={f1:=6,f2:=1.2},  x3:=temp };
x3:={ x1:={f1:=2,f2:=1.2},  x2:={f1:=7,f2:=1.2},  x3:=temp };
//match
if (match(x1,templateRec_tComp)) {setverdict(pass);}
 else {setverdict(fail, 1);}
//no match: in the list
if (not(match(x2,templateRec_tComp))) {setverdict(pass);}
 else {setverdict(fail, 2);}
//no match: other field
if (not(match(x3,templateRec_tComp))) {setverdict(pass);}
 else {setverdict(fail, 3);}
}

testcase templateRecOmit() runs on templateRec_mycomp {
var templateRec_myrec temp:={f1:=3,f2:=1.2};
var templateRec_rec x1,x2,x3;		//omitting value
x1:={ x1:={f1:=1,f2:=1.2},  x2:={f1:=2,f2:=1.2},  x3:=omit };
x2:={ x1:={f1:=1,f2:=1.2},  x2:={f1:=2,f2:=1.2},  x3:=temp };
x3:={ x1:={f1:=2,f2:=1.2},  x2:={f1:=2,f2:=1.2},  x3:=omit };
//match
if (match(x1,templateRec_tOmit)) {setverdict(pass);}
 else {setverdict(fail);}
//no match: not omitted
if (not(match(x2,templateRec_tOmit))) {setverdict(pass);}
 else {setverdict(fail);}
//no match: other field
if (not(match(x3,templateRec_tOmit))) {setverdict(pass);}
 else {setverdict(fail);}
}

testcase templateRecAny() runs on templateRec_mycomp {
var templateRec_myrec temp:={f1:=3,f2:=1.2};
var templateRec_rec x1,x2,x3;		//any value
x1:={ x1:={f1:=1,f2:=1.2},  x2:={f1:=2,f2:=1.2},  x3:=temp };
x2:={ x1:={f1:=1,f2:=1.2},  x2:={f1:=2,f2:=1.2},  x3:=omit };
x3:={ x1:={f1:=2,f2:=1.2},  x2:={f1:=2,f2:=1.2},  x3:=temp };
//match
if (match(x1,templateRec_tAny)) {setverdict(pass);}
 else {setverdict(fail);}
//no match: field omitted
if (not(match(x2,templateRec_tAny))) {setverdict(pass);}
 else {setverdict(fail);}
//no match: other field
if (not(match(x3,templateRec_tAny))) {setverdict(pass);}
 else {setverdict(fail);}
}

testcase templateRecAnyorNone() runs on templateRec_mycomp {
var templateRec_myrec temp:={f1:=3,f2:=1.2};
var templateRec_rec x1,x2,x3;		//AnyorNone value
x1:={ x1:={f1:=1,f2:=1.2},  x2:={f1:=2,f2:=1.2},  x3:=omit };
x2:={ x1:={f1:=1,f2:=1.2},  x2:={f1:=2,f2:=1.2},  x3:=temp };
x3:={ x1:={f1:=2,f2:=1.2},  x2:={f1:=2,f2:=1.2},  x3:=omit };
//match: omitted
if (match(x1,templateRec_tAnyorNone)) {setverdict(pass);}
 else {setverdict(fail);}
//match: value
if (match(x2,templateRec_tAnyorNone)) {setverdict(pass);}
 else {setverdict(fail);}
//no match: other field
if (not(match(x3,templateRec_tAnyorNone))) {setverdict(pass);}
 else {setverdict(fail);}
}

testcase templateRecIfpresent() runs on templateRec_mycomp {
var templateRec_myrec temp1:={f1:=3,f2:=1.2};	//ifpresent
var templateRec_myrec temp2:={f1:=4,f2:=1.2};
var templateRec_rec x1,x2,x3,x4;
x1:={ x1:={f1:=1,f2:=1.2},  x2:={f1:=2,f2:=1.2},  x3:=temp1 };
x2:={ x1:={f1:=1,f2:=1.2},  x2:={f1:=2,f2:=1.2},  x3:=omit };
x3:={ x1:={f1:=1,f2:=1.2},  x2:={f1:=2,f2:=1.2},  x3:=temp2 };
x4:={ x1:={f1:=2,f2:=1.2},  x2:={f1:=2,f2:=1.2},  x3:=omit };
//match: present and match
if (match(x1,templateRec_tIfpresent)) {setverdict(pass);}
else {setverdict(fail);}
//match: not present
if (match(x2,templateRec_tIfpresent)) {setverdict(pass);}
else {setverdict(fail);}
//no match: present and not match
if (not(match(x3,templateRec_tIfpresent))) {setverdict(pass);}
else {setverdict(fail);}
//no match: other field
if (not(match(x4,templateRec_tIfpresent))) {setverdict(pass);}
else {setverdict(fail);}
}


type record R
{
    integer i,
    charstring str optional
}
const R cr := { 1, omit }
template R tRrec1 := { 1 , omit }
template R tRrec2 := { 1, complement ( "a" ) }
template R tRrec3 := { 1, ( "a" ) }
template R tr := { i := 1, str := "a" ifpresent }
template R tr2 := { i := 1, str := ? }
template R trc := cr; // HQ46602

// Note: this tests the new omit behavior and requires the -M compiler option to be set off!
testcase MTTSM00015947() runs on templateRec_mycomp
{
  if (not match(cr, tRrec1)) { setverdict(fail); }
  if (match(cr, tRrec2)) { setverdict(fail); }
  if ( match(cr, tRrec3)) { setverdict(fail); }
  if (ispresent(tr.str)) { setverdict(fail); }
  if (ispresent(trc.str)) { setverdict(fail); }
  if (not ispresent(tr2.str)) { setverdict(fail); }
  setverdict(pass);
}

testcase MTTSM00015947_dyn() runs on templateRec_mycomp
{
  var R vl_cr := cr;
  var template R vt_tRrec1 := tRrec1;
  var template R vt_tRrec2 := tRrec2;
  var template R vt_tRrec3 := tRrec3;
  var template R vt_tr := tr;
  var template R vt_tr2 := tr2;
  var template R vt_trc := trc;
  if (not match(vl_cr, vt_tRrec1)) { setverdict(fail); }
  if (match(vl_cr, vt_tRrec2)) { setverdict(fail); }
  if ( match(vl_cr, vt_tRrec3)) { setverdict(fail); }
  if (ispresent(vt_tr.str)) { setverdict(fail); }
  if (ispresent(vt_trc.str)) { setverdict(fail); }
  if (not ispresent(tr2.str)) { setverdict(fail); }
  setverdict(pass);
}

import from TtemplateRecAsn all
template AmbiguousAnyRec t_AAR := { ''O }
const AmbiguousAnyRec c_AAR := { ''O }
testcase tc_HM39698() runs on templateRec_mycomp
{
  var template AmbiguousAnyRec vt_AAR := { ''O }
  var AmbiguousAnyRec v_AAR := { ''O }
  log(t_AAR)
  log(c_AAR)
  log(vt_AAR)
  log(v_AAR)
  // It's good, if we reach this point...
  setverdict(pass)
}

testcase tc_valueof_governor_segfault() runs on templateRec_mycomp
{
  var templateRec_myrec mr := valueof({f1 := 1, f2 := 2.0})
  setverdict(pass)
}

// Parametrized template reference without `()'.
template R tmr(in integer i := 1) := { i := i, str := omit }
testcase tc_HO49372() runs on templateRec_mycomp
{
  log(tmr)
  setverdict(pass)
}

type record MyRecord 
{ 
    integer int, 
    boolean deleted 
} 
testcase tc_HO69658() runs on templateRec_mycomp
{
var template MyRecord vl_myrecord; 
vl_myrecord.int := 0; 

var template MyRecord vl_myrecordAgain := vl_myrecord; 
vl_myrecordAgain.deleted := false; 

log("Now assignment finish");
log("Print record:",vl_myrecordAgain);
// It's good, if we reach this point...
if (log2str(vl_myrecordAgain)=="{ int := 0, deleted := false }") {setverdict(pass)}else{setverdict(fail)}
}

type record MyRec2{
  ROC roc optional,
  ROI roi optional,
  MyUnion1 u optional, 
  MyRecord1 r optional
}

type record of charstring ROC;
type record of integer  ROI;
type record MyRecord1 {
  integer       i optional,
  float         x optional,
  charstring    c
}

type union MyUnion1 {
  ROC roc,
  integer i,
  ROI roi,
  MyRecord1 r
}

  type union MyUnion_OneOption {
    integer i
  }

  type record MyRec4 {
    MyUnion_OneOption u,
    integer i
  }

testcase tc_record_withJoker1() runs on templateRec_mycomp {
  var template MyRec2 vtl_rec2_j;
  if(isbound(vtl_rec2_j)) {setverdict(fail)}else {setverdict(pass)};
  vtl_rec2_j:={
    roc:=*
  }
  if(isbound(vtl_rec2_j)) {setverdict(pass)}else {setverdict(fail)};
  if(isbound(vtl_rec2_j.roc)) {setverdict(pass)}else {setverdict(fail)};
  if(isbound(vtl_rec2_j.roc[0])) {setverdict(fail)}else {setverdict(pass)};
}
testcase tc_record_withJoker2() runs on templateRec_mycomp {
  var template MyRec2 vtl_rec2_j; 
  vtl_rec2_j:={
    roc:={ ?,? }
  }
  if(isbound(vtl_rec2_j)) {setverdict(pass)}else {setverdict(fail)};
  if(isbound(vtl_rec2_j.roc)) {setverdict(pass)}else {setverdict(fail)};
  if(isbound(vtl_rec2_j.roc[0])){setverdict(pass)}else {setverdict(fail)};
  if(isbound(vtl_rec2_j.roc[1])){setverdict(pass)}else {setverdict(fail)};
  if(isbound(vtl_rec2_j.roc[10])){setverdict(fail)}else {setverdict(pass)};
  if(isbound(vtl_rec2_j.roi)){setverdict(fail)}else {setverdict(pass)};
  if(isbound(vtl_rec2_j.u)){setverdict(fail)}else {setverdict(pass)};
  if(isbound(vtl_rec2_j.r)){setverdict(fail)}else {setverdict(pass)};
}

testcase tc_record_withJoker3() runs on templateRec_mycomp {
  var template MyRec2 vtl_rec2_j; 
  vtl_rec2_j:={
    u := *
  }
  if(isbound(vtl_rec2_j)) {setverdict(pass)}else {setverdict(fail)};
  if(isbound(vtl_rec2_j.roc)){setverdict(fail)}else {setverdict(pass)};
  if(isbound(vtl_rec2_j.roi)){setverdict(fail)}else {setverdict(pass)};
  if(isbound(vtl_rec2_j.u)){setverdict(pass)}else {setverdict(fail)};
  if(isbound(vtl_rec2_j.u.i)){setverdict(fail)}else {setverdict(pass)};
}

testcase tc_record_withJoker4() runs on templateRec_mycomp {
  var template MyRec2 vtl_rec2_j; 
  vtl_rec2_j:={
    roc:=omit,
    u:={i:=?}
  }
  if(isbound(vtl_rec2_j)) {setverdict(pass)}else {setverdict(fail)};
  if(isbound(vtl_rec2_j.roc)){setverdict(pass)}else {setverdict(fail)};
  if(isbound(vtl_rec2_j.roi)){setverdict(fail)}else {setverdict(pass)};
  if(isbound(vtl_rec2_j.u)){setverdict(pass)}else {setverdict(fail)};
  if(isbound(vtl_rec2_j.u.i)){setverdict(pass)}else {setverdict(fail)};
}

testcase tc_record_withJoker5() runs on templateRec_mycomp {
  var template MyRec2 vtl_rec2_j; 
  vtl_rec2_j:={
    r:= ?
  }
  if(isbound(vtl_rec2_j)) {setverdict(pass)}else {setverdict(fail)};
  if(isbound(vtl_rec2_j.roc)){setverdict(fail)}else {setverdict(pass)};
  if(isbound(vtl_rec2_j.roi)){setverdict(fail)}else {setverdict(pass)};
  if(isbound(vtl_rec2_j.u)){setverdict(fail)}else {setverdict(pass)};
  if(isbound(vtl_rec2_j.u.i)){setverdict(fail)}else {setverdict(pass)};
  if(isbound(vtl_rec2_j.r)) {setverdict(pass)}else {setverdict(fail)};
  if(isbound(vtl_rec2_j.r.i)) {setverdict(pass)}else {setverdict(fail)};
  if(isbound(vtl_rec2_j.r.x)) {setverdict(pass)}else {setverdict(fail)};
  if(isbound(vtl_rec2_j.r.c)) {setverdict(pass)}else {setverdict(fail)};
}

testcase tc_record_withJoker6() runs on templateRec_mycomp {
  var template MyRec2 vtl_rec2_j; 
  vtl_rec2_j:={
    r:= *
  }
  if(isbound(vtl_rec2_j)) {setverdict(pass)}else {setverdict(fail)};
  if(isbound(vtl_rec2_j.roc)){setverdict(fail)}else {setverdict(pass)};
  if(isbound(vtl_rec2_j.roi)){setverdict(fail)}else {setverdict(pass)};
  if(isbound(vtl_rec2_j.u)){setverdict(fail)}else {setverdict(pass)};
  if(isbound(vtl_rec2_j.u.i)){setverdict(fail)}else {setverdict(pass)};
  if(isbound(vtl_rec2_j.r)) {setverdict(pass)}else {setverdict(fail)};
  if(isbound(vtl_rec2_j.r.i)) {setverdict(fail)}else {setverdict(pass)};
  if(isbound(vtl_rec2_j.r.x)) {setverdict(fail)}else {setverdict(pass)};
  if(isbound(vtl_rec2_j.r.c)) {setverdict(fail)}else {setverdict(pass)};
}

group g_TR_HO72812 {
  type record MyRecord_HO72812
  {
    record {
      boolean innerField1 optional,
      integer innerField2 optional
    } field1 optional,
    integer field2
  }
  testcase tc_record_TR_HO72813() runs on templateRec_mycomp {
    var MyRecord_HO72812 vl_MyRecord := { field1 := {}, field2 := 5 };  
    if(isbound(vl_MyRecord)) {setverdict(pass)} else {setverdict(fail)}
    if(isbound(vl_MyRecord.field1)) {setverdict(fail)} else {setverdict(pass)}
    if(isbound(vl_MyRecord.field2)) {setverdict(pass)} else {setverdict(fail)}
    vl_MyRecord.field1 := omit
    if(isbound(vl_MyRecord.field1)) {setverdict(pass)} else {setverdict(fail)} 
    if(isbound(vl_MyRecord.field1.innerField1)) {setverdict(fail)} else {setverdict(pass)}
    if(isbound(vl_MyRecord.field1.innerField1)) {setverdict(fail)} else {setverdict(pass)} 
    if(ispresent(vl_MyRecord.field1)) {setverdict(fail)} else {setverdict(pass)} 
    
    vl_MyRecord := { field1 := {innerField1:=true, innerField2:=1 } }
    if(isbound(vl_MyRecord.field1)) {setverdict(pass)} else {setverdict(fail)}
    if(isbound(vl_MyRecord.field1.innerField1)) {setverdict(pass)} else {setverdict(fail)}
    if(isbound(vl_MyRecord.field1.innerField2)) {setverdict(pass)} else {setverdict(fail)}
  }
      testcase tc_record_TR_HO72813_ip() runs on templateRec_mycomp {
      var MyRecord_HO72812 vl_MyRecord := { field1 := {}, field2 := 5 }; 
      if(ispresent(vl_MyRecord)) {setverdict(pass)} else {setverdict(fail)}
      if(ispresent(vl_MyRecord.field1)) {setverdict(fail)} else {setverdict(pass)}  //according to ethgry
      if(ispresent(vl_MyRecord.field2)) {setverdict(pass)} else {setverdict(fail)}  
    }

    testcase tc_record_TR_HO72813_innerFields() runs on templateRec_mycomp {
      var MyRecord_HO72812 vl_MyRecord := { field1 := {}, field2 := 5 }; 
      if(ispresent(vl_MyRecord.field1.innerField1)) {setverdict(fail)} else {setverdict(pass)}
      if(ispresent(vl_MyRecord.field1.innerField2)) {setverdict(fail)} else {setverdict(pass)}
    }

    testcase tc_record_TR_HO72813_partlyInitialized() runs on templateRec_mycomp {
      var MyRecord_HO72812 vl_MyRecord := { field1 := {innerField1:=true}, field2 := 5 };
      if(ispresent(vl_MyRecord.field1)) {setverdict(pass)} else {setverdict(fail)} ;
      if(ispresent(vl_MyRecord.field1.innerField1)) {setverdict(pass)} else {setverdict(fail)};
      if(ispresent(vl_MyRecord.field1.innerField2)) {setverdict(fail)} else {setverdict(pass)} ; //DTE???
    }

    testcase tc_record_TR_HO72813_omit() runs on templateRec_mycomp {
      var MyRecord_HO72812 vl_MyRecord := { field1 := {innerField1:=true}, field2 := 5 }    
      vl_MyRecord.field1 := omit;
      if(ispresent(vl_MyRecord.field1)) {setverdict(fail)} else {setverdict(pass)}     
      if(ispresent(vl_MyRecord.field1.innerField1)) {setverdict(fail)} else {setverdict(pass)};
      if(ispresent(vl_MyRecord.field1.innerField2)) {setverdict(fail)} else {setverdict(pass)} ; //DTE???
    }
}

  testcase tc_record_mandatoryField_WithWildcard() runs on templateRec_mycomp {
    var template MyRec4 vtl_rec:=?
    if(ispresent(vtl_rec.u)){setverdict(pass)}else {setverdict(fail)};
    if(ispresent(vtl_rec.i)){setverdict(pass)}else {setverdict(fail)};
  }

  testcase tc_record_withWildCard1() runs on templateRec_mycomp {
    var template MyRec2 vtl_rec2;
    vtl_rec2:={
      roc:=*
    }
    if(ispresent(vtl_rec2)) {setverdict(pass)}else {setverdict(fail)};
  }
  testcase tc_record_withWildCard1A() runs on templateRec_mycomp {
    var template MyRec2 vtl_rec2;
    vtl_rec2:={
      roc:=*
    }  
    if(ispresent(vtl_rec2.roc)) {setverdict(fail)}else {setverdict(pass)};
  }

  testcase tc_record_withWildCard1AA() runs on templateRec_mycomp {
    var template MyRec2 vtl_rec2;
    vtl_rec2:={
      roc:=?
    }  
    if(ispresent(vtl_rec2.roc)) {setverdict(pass)}else {setverdict(fail)};
  }

  testcase tc_record_withWildCard1B() runs on templateRec_mycomp {
    var template MyRec2 vtl_rec2;
    vtl_rec2:={
      roc:=*
    }    
    if(ispresent(vtl_rec2.roc[0])) {setverdict(fail)}else {setverdict(pass)};
  }

  testcase tc_record_withWildCard2() runs on templateRec_mycomp {
    var template MyRec2 vtl_rec2; 
    vtl_rec2:={
      roc:={ ?,? }
    }
    if(ispresent(vtl_rec2)) {setverdict(pass)}else {setverdict(fail)};
    if(ispresent(vtl_rec2.roc)) {setverdict(pass)}else {setverdict(fail)};
    if(ispresent(vtl_rec2.roc[0])){setverdict(pass)}else {setverdict(fail)};
    if(ispresent(vtl_rec2.roc[1])){setverdict(pass)}else {setverdict(fail)};
    if(ispresent(vtl_rec2.roc[10])){setverdict(fail)}else {setverdict(pass)};
  }

  //unbound
  testcase tc_record_withWildCard2A() runs on templateRec_mycomp {
    var template MyRec2 vtl_rec2; 
    vtl_rec2:={
      roc:={ ?,? }
    }  
    if(ispresent(vtl_rec2.roi)){setverdict(fail)}else {setverdict(pass)};
  }
  testcase tc_record_withWildCard2B() runs on templateRec_mycomp {
    var template MyRec2 vtl_rec2; 
    vtl_rec2:={
      roc:={ ?,? }
    }  
    if(ispresent(vtl_rec2.u)){setverdict(fail)}else {setverdict(pass)};
  }
  testcase tc_record_withWildCard2C() runs on templateRec_mycomp {
    var template MyRec2 vtl_rec2; 
    vtl_rec2:={
      roc:={ ?,? }
    }    
    if(ispresent(vtl_rec2.r)){setverdict(fail)}else {setverdict(pass)};
  }

  testcase tc_record_withWildCard3() runs on templateRec_mycomp {
    var template MyRec2 vtl_rec2; 
    vtl_rec2:={
      u := *
    }
    if(ispresent(vtl_rec2)) {setverdict(pass)}else {setverdict(fail)};
  }

  testcase tc_record_withWildCard3A() runs on templateRec_mycomp {
    var template MyRec2 vtl_rec2; 
    vtl_rec2:={
      u := *
    }
    if(ispresent(vtl_rec2.roc)){setverdict(fail)}else {setverdict(pass)};
  }

  testcase tc_record_withWildCard3B() runs on templateRec_mycomp {
    var template MyRec2 vtl_rec2; 
    vtl_rec2:={
      u := *
    }
    if(ispresent(vtl_rec2.roi)){setverdict(fail)}else {setverdict(pass)};
  }

  testcase tc_record_withWildCard3C() runs on templateRec_mycomp {
    var template MyRec2 vtl_rec2; 
    vtl_rec2:={
      u := *
    }
    if(ispresent(vtl_rec2.u)){setverdict(fail)}else{setverdict(pass)};
  }

  testcase tc_record_withWildCard3D() runs on templateRec_mycomp {
    var template MyRec2 vtl_rec2; 
    vtl_rec2:={
      u := ?
    }
    if(ispresent(vtl_rec2.u)){setverdict(pass)}else{setverdict(fail)};
  }

  testcase tc_record_withWildCard4() runs on templateRec_mycomp {
    var template MyRec2 vtl_rec2; 
    vtl_rec2:={
      roc:=omit,
      u:={i:=?}
    }
    if(ispresent(vtl_rec2)) {setverdict(pass)}else {setverdict(fail)};
    if(ispresent(vtl_rec2.roc)){setverdict(fail)}else {setverdict(pass)};
  }

  testcase tc_record_withWildCard4A() runs on templateRec_mycomp {
    var template MyRec2 vtl_rec2; 
    vtl_rec2:={
      roc:=omit,
      u:={i:=?}
    }  
    if(ispresent(vtl_rec2.roi)){setverdict(fail)}else {setverdict(pass)};
  }

  testcase tc_record_withWildCard4B() runs on templateRec_mycomp {
    var template MyRec2 vtl_rec2; 
    vtl_rec2:={
      roc:=omit,
      u:={i:=?}
    }  
    if(ispresent(vtl_rec2.u)){setverdict(pass)}else {setverdict(fail)};
    if(ispresent(vtl_rec2.u.i)){setverdict(pass)}else {setverdict(fail)};
  }

  testcase tc_record_withWildCard5() runs on templateRec_mycomp {
    var template MyRec2 vtl_rec2; 
    vtl_rec2:={
      r:= ?
    }
    if(ispresent(vtl_rec2)) {setverdict(pass)}else {setverdict(fail)};
    if(ispresent(vtl_rec2.roc)){setverdict(fail)}else {setverdict(pass)};
    if(ispresent(vtl_rec2.roi)){setverdict(fail)}else {setverdict(pass)};
    if(ispresent(vtl_rec2.u)){setverdict(fail)}else {setverdict(pass)};
    if(ispresent(vtl_rec2.u.i)){setverdict(fail)}else {setverdict(pass)};
  }

  testcase tc_record_withWildCard5A() runs on templateRec_mycomp {
    var template MyRec2 vtl_rec2; 
    vtl_rec2:={
      r:= ?
    }
    if(ispresent(vtl_rec2.r)) {setverdict(pass)}else {setverdict(fail)};
  }

  testcase tc_record_withWildCard5B_optional() runs on templateRec_mycomp {
    var template MyRec2 vtl_rec2; 
    vtl_rec2:={
      r:= ?
    }
    if(ispresent(vtl_rec2.r.i)) {setverdict(fail)}else {setverdict(pass)};
    if(ispresent(vtl_rec2.r.x)) {setverdict(fail)}else {setverdict(pass)};
  }

  testcase tc_record_withWildCard5B_mandatory() runs on templateRec_mycomp {
    var template MyRec2 vtl_rec2; 
    vtl_rec2:={
      r:= ?
    }
    if(ispresent(vtl_rec2.r.c)) {setverdict(pass)}else {setverdict(fail)};
  }

  testcase tc_record_withWildCard6() runs on templateRec_mycomp {
    var template MyRec2 vtl_rec2; 
    vtl_rec2:={
      r:= *
    }
    if(ispresent(vtl_rec2)) {setverdict(pass)}else {setverdict(fail)};
    if(ispresent(vtl_rec2.roc)){setverdict(fail)}else {setverdict(pass)};
    if(ispresent(vtl_rec2.roi)){setverdict(fail)}else {setverdict(pass)};
    if(ispresent(vtl_rec2.u)){setverdict(fail)}else {setverdict(pass)};
    if(ispresent(vtl_rec2.u.i)){setverdict(fail)}else {setverdict(pass)};
  }

  testcase tc_record_withWildCard6A() runs on templateRec_mycomp {
    var template MyRec2 vtl_rec2; 
    vtl_rec2:={
      r:= *
    }  
    if(ispresent(vtl_rec2.r)) {setverdict(fail)}else {setverdict(pass)};
    if(ispresent(vtl_rec2.r.i)) {setverdict(fail)}else {setverdict(pass)};
    if(ispresent(vtl_rec2.r.x)) {setverdict(fail)}else {setverdict(pass)};
    if(ispresent(vtl_rec2.r.c)) {setverdict(fail)}else {setverdict(pass)};
  }


type record Rec {
  integer num,
  charstring str optional
} 
 
function f_identical_fields(Rec p_par) return boolean {
  return ispresent(p_par.str) and p_par.str == int2str(p_par.num);
}

template Rec t_str_is_present := { num := ?, str := ? };

template Rec t_conjunction := conjunct(t_str_is_present, @dynamic f_identical_fields);

template Rec t_implication := t_str_is_present implies @dynamic f_identical_fields;

template Rec t_dynamic(template integer pt_num, template charstring pt_str) := @dynamic {
  return match(value.num, pt_num) and match(value.str, pt_str);
}

testcase tc_record_conjunction() runs on templateRec_mycomp {
  var Rec v1 := { 16, "16" }, v2 := { 6, "a" };
  if (not match(v1, t_conjunction)) {
    setverdict(fail, match(v1, t_conjunction));
  }
  if (match(v2, t_conjunction)) {
    setverdict(fail, match(v2, t_conjunction));
  }
  setverdict(pass);
}

testcase tc_record_implication() runs on templateRec_mycomp {
  var Rec v1 := { -2, omit }, v2 := { 71, "x" }, v3 := { -12, "-12" };
  if (not match(v1, t_implication)) {
    setverdict(fail, match(v1, t_implication));
  }
  if (match(v2, t_implication)) {
    setverdict(fail, match(v2, t_implication));
  }
  if (not match(v3, t_implication)) {
    setverdict(fail, match(v3, t_implication));
  }
  setverdict(pass);
}

testcase tc_record_dynamic() runs on templateRec_mycomp {
  var Rec v1 := { 37, "abxc" }, v2 := { 16, "def" };
  var template integer vt_num := (0..100);
  var template charstring vt_str := pattern "*x*";
  if (not match(v1, t_dynamic(vt_num, vt_str))) {
    setverdict(fail, match(v1, t_dynamic(vt_num, vt_str)));
  }
  if (match(v2, t_dynamic(vt_num, vt_str))) {
    setverdict(fail, match(v2, t_dynamic(vt_num, vt_str)));
  }
  setverdict(pass);
}
  
control {
 execute(pasu());
 execute(templateRecSpec());
 execute(templateRecList());
 execute(templateRecComp());
 execute(templateRecOmit());
 execute(templateRecAny());
 execute(templateRecAnyorNone());
 execute(templateRecIfpresent());
 execute(MTTSM00015947());
 execute(MTTSM00015947_dyn());
 execute(tc_HM39698());
 execute(tc_valueof_governor_segfault());
 execute(tc_HO49372());
 execute(tc_HO69658());
 
 execute(tc_record_withJoker1());
 execute(tc_record_withJoker2());
 execute(tc_record_withJoker3());
 execute(tc_record_withJoker4());
 execute(tc_record_withJoker5());
 execute(tc_record_withJoker6());
 execute(tc_record_TR_HO72813());
 execute(tc_record_withWildCard1());
 execute(tc_record_withWildCard1A()); //pass
 execute(tc_record_withWildCard1AA());
 execute(tc_record_withWildCard1B());  
 execute(tc_record_withWildCard2());
 execute(tc_record_withWildCard2A());//pass (unbound)
 execute(tc_record_withWildCard2B());//pass (unbound)
 execute(tc_record_withWildCard2C());//pass (unbound)
 execute(tc_record_withWildCard3());
 execute(tc_record_withWildCard3A());//pass (unbound)
 execute(tc_record_withWildCard3B());//pass (unbound)
 execute(tc_record_withWildCard3C());//pass (*)
 execute(tc_record_withWildCard3D());//pass
 execute(tc_record_withWildCard4());//pass
 execute(tc_record_withWildCard4A());
 execute(tc_record_withWildCard4B()); 
 execute(tc_record_withWildCard5());//pass
 execute(tc_record_withWildCard5A());//pass
 execute(tc_record_withWildCard5A());//pass
 execute(tc_record_withWildCard5B_optional());//pass
 execute(tc_record_withWildCard5B_mandatory());//pass
 execute(tc_record_withWildCard6());//pass
 execute(tc_record_withWildCard6A());
 execute(tc_record_TR_HO72813_ip());
 execute(tc_record_TR_HO72813_innerFields());
 execute(tc_record_TR_HO72813_partlyInitialized());
 execute(tc_record_TR_HO72813_omit());
 execute(tc_record_conjunction());
 execute(tc_record_implication());
 execute(tc_record_dynamic());
}
}
