tp_timeconstraint.cpp
Go to the documentation of this file.
1/* tp_timecontraint.cpp -- model of timeconstraints in timed automata */
2
3
4/* Timeplugin for FAU Discrete Event Systems Library (libfaudes)
5
6 Copyright (C) 2006 B Schlein
7 Copyright (C) 2007 Thomas Moor
8 Exclusive copyright is granted to Klaus Schmidt
9
10*/
11
12
13
14#include "tp_timeconstraint.h"
15
16namespace faudes {
17
18
19/********************************************************************
20
21 Implementation of ClockSet
22
23********************************************************************/
24
25
26// std faudes type (cannot do New() with macro)
27FAUDES_TYPE_IMPLEMENTATION_COPY(Void,ClockSet,NameSet)
28FAUDES_TYPE_IMPLEMENTATION_CAST(Void,ClockSet,NameSet)
29FAUDES_TYPE_IMPLEMENTATION_ASSIGN(Void,ClockSet,NameSet)
30FAUDES_TYPE_IMPLEMENTATION_EQUAL(Void,ClockSet,NameSet)
31
32// ClockSet(void);
34 // overwrite default static symboltable
35 mpSymbolTable=GlobalClockSymbolTablep();
36 NameSet::Name("Clocks");
37 FD_DC("ClockSet("<<this<<")::ClockSet() with csymtab "<< SymbolTablep());
38}
39
40// ClockSet(clockset)
41ClockSet::ClockSet(const ClockSet& rOtherSet) : NameSet(rOtherSet) {
42 FD_DC("ClockSet(" << this << ")::ClockSet(rOtherSet " << &rOtherSet << ")");
43}
44
45// ClockSet(file);
46ClockSet::ClockSet(const std::string& rFilename, const std::string& rLabel) : NameSet() {
47 // overwrite default static symboltable
49 NameSet::Name("Clocks");
50 // read file
51 NameSet::Read(rFilename,rLabel);
52}
53
54// Clockset::New()
55ClockSet* ClockSet::New(void) const {
56 ClockSet* res = new ClockSet();
58 return res;
59}
60
61// DoAssign()
62void ClockSet::DoAssign(const ClockSet& rSourceSet) {
63 // call base
64 NameSet::DoAssign(rSourceSet);
65}
66
67// DoEqual()
68bool ClockSet::DoEqual(const ClockSet& rOtherSet) const {
69 // call base
70 return NameSet::DoEqual(rOtherSet);
71}
72
73
74
75// ClockSet::GlobalClockSymbolTablep
76// (initialize on first use pattern)
78 static SymbolTable fls;
79 return &fls;
80}
81
82
83
84
85
86
87/********************************************************************
88
89 Implementation of ElemConstraint
90
91********************************************************************/
92
93
94// helper (conversion from operatorname to string
96 switch(op){
97 case LessThan: return "LT";
98 case GreaterThan: return "GT";
99 case LessEqual: return "LE";
100 case GreaterEqual: return "GE";
101 }
102 return "Inalid";
103}
104
105
106// Constructor
110
111// Constructor
112ElemConstraint::ElemConstraint(Idx clockindex, Operator op, const Time::Type timeconst) {
113 Set(clockindex,op,timeconst);
114}
115
116
117// Set(clockindex, op, timeconst)
118void ElemConstraint::Set(Idx clockindex, Operator op, const Time::Type timeconst) {
119 mClockIndex = clockindex;
120 mCompOperator = op;
121 mTimeConstant = timeconst;
122}
123
124// Clock(clockindex)
126 mClockIndex=clockindex;
127 return mClockIndex;
128}
129
130// Clock()
132 return mClockIndex;
133}
134
135// CompOperator(newOp)
139
140
141// CompOperator()
145
146
147// TimeConstant(newTimeConst)
149 mTimeConstant = newTimeConst;
150}
151
152// TimeConstant()
156
157// Str() const
158std::string ElemConstraint::Str(void) const {
159 std::stringstream resstream;
160 resstream << "(" << mClockIndex << " "
161 << OperatorName(mCompOperator) << " " << mTimeConstant << ")";
162 std::string result = resstream.str();
163 return result;
164}
165
166// operator==
167bool ElemConstraint::operator== (const ElemConstraint & otherClockConstraint) const {
168 return ( mClockIndex == otherClockConstraint.mClockIndex
169 && mCompOperator == otherClockConstraint.mCompOperator
170 && mTimeConstant == otherClockConstraint.mTimeConstant );
171}
172
173// operator!=
174bool ElemConstraint::operator!= (const ElemConstraint & otherClockConstraint) const {
175 return !(operator==(otherClockConstraint));
176}
177
178// operator <
179bool ElemConstraint::operator < (const ElemConstraint& otherElemConstraint) const {
180 if (mClockIndex < otherElemConstraint.mClockIndex) return true;
181 if (mClockIndex > otherElemConstraint.mClockIndex) return false;
182 if (mCompOperator < otherElemConstraint.mCompOperator) return true;
183 if (mCompOperator > otherElemConstraint.mCompOperator) return false;
184 if (mTimeConstant < otherElemConstraint.mTimeConstant) return true;
185 return false;
186}
187
188
189/********************************************************************
190
191 Implementation of TimeConstraint
192
193********************************************************************/
194
195
196
197// empty constructor
199 FD_DC("TimeConstraint(" << this << ")::TimeConstraint()");
201 mName="TimeConstraint";
202}
203
204// read file constructor
205TimeConstraint::TimeConstraint(const std::string& rFilename, const std::string& rLabel) {
206 FD_DC("TimeConstraint(" << this << ")::TimeConstraint(" << rFilename << ")");
208 Read(rFilename, rLabel);
209}
210
211// constructor
212TimeConstraint::TimeConstraint(const TimeConstraint& rOtherTimeConstraint) {
213 FD_DC("TimeConstraint(" << this << ")::TimeConstraint(other)");
214 mName=rOtherTimeConstraint.mName;
215 mpClockSymbolTable= rOtherTimeConstraint.mpClockSymbolTable;
216 mClockConstraints = rOtherTimeConstraint.ClockConstraints();
217}
218
219
220// Destructor
223
224// ClockSymbolTablep()
228
229// ClockSymbolTablep(pSymTab)
231 if(mClockConstraints.empty()) {
232 mpClockSymbolTable=pSymTab;
233 } else {
234 // TODO: implement reindex
235 FD_ERR("TimeConstraint::SymboltTable(pSymTab): "
236 << "set SymbolTable not implemented!!");
237 abort();
238 }
239}
240
241// Empty()
242bool TimeConstraint::Empty(void) const {
243 return mClockConstraints.empty();
244}
245
246// Size of set of ElemConstraints
248 return (Idx)mClockConstraints.size();
249}
250
251// InsClock()
252Idx TimeConstraint::InsClock(const std::string& rClockName) const {
253 return mpClockSymbolTable->InsEntry(rClockName);
254}
255
256// ClockName(clockindex)
257std::string TimeConstraint::ClockName(Idx clockindex) const {
258 return mpClockSymbolTable->Symbol(clockindex);
259}
260
261// ClockIndex(clockname)
262Idx TimeConstraint::ClockIndex(const std::string& rClockName) const {
263 return mpClockSymbolTable->Index(rClockName);
264}
265
266
267// EStr(ElemConstraint) const
268std::string TimeConstraint::EStr(const ElemConstraint& rElemConstraint) const {
269 std::stringstream resstream;
270 resstream << "(" << ClockName(rElemConstraint.Clock()) << "[" << rElemConstraint.Clock()
271 << "] " << ElemConstraint::OperatorName(rElemConstraint.CompOperator()) << " "
272 << rElemConstraint.TimeConstant() << ")";
273 std::string result = resstream.str();
274 return result;
275}
276
277// Insert(rNewConstr)
279 FD_DC("TimeConstraint(" << this << ")::Insert(" << rNewConstr.Str() << ")");
280 if(rNewConstr.Clock()<=0 || ClockName(rNewConstr.Clock())=="") {
281 std::stringstream errstr;
282 errstr << "Invalid ElemConstraint: \"" << rNewConstr.Str();
283 throw Exception("TimeConstraint::Insert", errstr.str(), 55);
284 }
285 return mClockConstraints.insert(rNewConstr).first;
286}
287
288// Insert(clock, op, timeconst)
290 FD_DC("TimeConstraint(" << this << ")::Insert("
291 << clockindex << " " << ElemConstraint::OperatorName(op) << " " << timeconst << ")");
292 ElemConstraint newconstr(clockindex,op,timeconst);
293 return Insert(newconstr);
294}
295
296
297// Insert(clock, op, timeconst)
299 const std::string clockname,
300 Operator op,
301 const Time::Type timeconst)
302{
303 FD_DC("TimeConstraint(" << this << ")::Insert(\""
304 << clockname << "\" " << ElemConstraint::OperatorName(op) << " " << timeconst << ")");
305 Idx clockindex = InsClock(clockname);
306 return Insert(clockindex,op,timeconst);
307}
308
309// Insert(rNewConstraints)
310void TimeConstraint::Insert(const std::list<ElemConstraint>& rNewConstraints) {
311 FD_DC("TimeConstraint(" << this << ")::Insert(const std::list<ElemConstraint>&)");
312 // HELPERS
313 std::list<ElemConstraint>::const_iterator it;
314 // ALGORITHM
315 for(it = rNewConstraints.begin(); it != rNewConstraints.end(); it++)
316 Insert(*it);
317}
318
319
320// Insert(rOtherTimeConstraint)
321void TimeConstraint::Insert(const TimeConstraint& rOtherTimeConstraint) {
322 FD_DC("TimeConstraint(" << this << ")::Insert(" << rOtherTimeConstraint.ToString() << ")");
323 // HELPERS
324 Iterator it;
325 // ALGORITHM
326 if(mpClockSymbolTable != rOtherTimeConstraint.mpClockSymbolTable) {
327 FD_ERR("TimeConstraint::Insert "
328 << "SymbolTable mismatch aka not implemented!!");
329 abort();
330 }
331 for(it = rOtherTimeConstraint.Begin(); it != rOtherTimeConstraint.End(); it++) {
332 Insert(*it);
333 }
334}
335
336// ClockConstraints()
337std::set<ElemConstraint> TimeConstraint::ClockConstraints(void) const {
338 return mClockConstraints;
339}
340
341
342// EraseByClock(clock)
344 FD_DC("TimeConstraint(" << this << ")::EraseByClock(" << clock << ") const");
345 // HELPERS
346 iterator lit,uit;
347
348 // ALGORITHM
351
352 if(lit==mClockConstraints.end())
353 return false;
354
355 mClockConstraints.erase(lit,uit);
356 return true;
357}
358
359
360// Erase(it)
362 FD_DC("TimeConstraint(" << this << ")::Erase(" << it->Str() << ") const");
363 if(it==End()) return it;
364 iterator del= it; //cit
365 it++;
366 mClockConstraints.erase(del);
367 return it;
368}
369
370
371// Erase(rElemConstr)
372bool TimeConstraint::Erase(const ElemConstraint& rElemConstr) {
373 FD_DC("TimeConstraint(" << this << ")::Erase(" << rElemConstr.Str() << ") const");
374 // HELPERS
375 iterator it;
376 // ALGORITHM
377 it = mClockConstraints.find(rElemConstr);
378 if(it == End()) return false;
379 mClockConstraints.erase(it);
380 return true;
381}
382
383// Erase(clock, op, timeconst)
384bool TimeConstraint::Erase(Idx clockindex, Operator op, const Time::Type timeconst) {
385 FD_DC("TimeConstraint(" << this << ")::Erase("
386 << clockindex << " " << ElemConstraint::OperatorName(op) << " " << timeconst << ")");
387 ElemConstraint newconstr(clockindex,op,timeconst);
388 return Erase(newconstr);
389}
390
391
392// Erase(clock, op, timeconst)
393bool TimeConstraint::Erase(const std::string& clockname, Operator op, const Time::Type timeconst)
394{
395 FD_DC("TimeConstraint(" << this << ")::Erase(\""
396 << clockname << "\" " << ElemConstraint::OperatorName(op) << " " << timeconst << ")");
397 Idx clockindex = ClockIndex(clockname);
398 return Erase(clockindex,op,timeconst);
399}
400
401// Exists(rElemConstr)
402bool TimeConstraint::Exists(const ElemConstraint& rElemConstr) const {
403 FD_DC("TimeConstraint(" << this << ")::ExistsElConstr(" << rElemConstr.Str() << ") const");
404 // HELPERS
405 Iterator it;
406 // ALGORITHM
407 it = mClockConstraints.find(rElemConstr);
408 return (it != End()) ;
409}
410
411
412// Deletes all ElemConstraints
414 FD_DC("TimeConstraint(" << this << ")::Clear() const");
415 mClockConstraints.clear();
416}
417
418
419
420// Iterator Begin() const
424
425
426// iterator End() const
430
431// reverse iterator RBegin()
435
436// reverse iterator REnd() const
440
441// iterator Begin(clock) const
445
446// iterator End(clock) const
450
451// returns ClockSet filled with clocks used by ElemConstraints
453 FD_DC("TimeConstraint(" << this << ")::ActiveClocks() const");
454 //Helpers
455 ClockSet result;
457 Iterator it;
458 // Algorithm
459 for(it = Begin(); it != End(); it++)
460 result.Insert(it->Clock());
461 return result;
462}
463
464// valid timeinterval for given clock
465TimeInterval TimeConstraint::Interval(const std::string& clockname) const{
466 Idx clockindex = ClockIndex(clockname);
467 return Interval(clockindex);
468}
469
470// valid timeinterval for given clock
472 FD_DC("TimeConstraint(" << this << ")::Interval(" << clockindex <<") const");
473 TimeInterval res;
474 TimeInterval tint;
475 Iterator it;
476 for(it = Begin(clockindex); it != End(clockindex); it++) {
477 FD_DC("TimeConstraint(" << this << ")::Interval: elemconstraint: " << it->Str());
478 tint.SetFull();
479 if(it->CompOperator() == ElemConstraint::LessThan) {
480 tint.UB(it->TimeConstant());
481 tint.UBincl(false);
482 }
483 if(it->CompOperator() == ElemConstraint::LessEqual) {
484 tint.UB(it->TimeConstant());
485 tint.UBincl(true);
486 }
487 if(it->CompOperator() == ElemConstraint::GreaterThan) {
488 tint.LB(it->TimeConstant());
489 tint.LBincl(false);
490 }
491 if(it->CompOperator() == ElemConstraint::GreaterEqual) {
492 tint.LB(it->TimeConstant());
493 tint.LBincl(true);
494 }
495 FD_DC("TimeConstraint(" << this << ")::Interval: interval: " << tint.Str());
496 res.Intersect(tint);
497 }
498 return res;
499}
500
501
502// set valid timeinterval for given clock
503void TimeConstraint::Interval(const std::string& clockname, const TimeInterval& rInterval) {
504 Idx clockindex = InsClock(clockname);
505 Interval(clockindex,rInterval);
506}
507
508// set valid timeinterval for given clock
509void TimeConstraint::Interval(Idx clockindex, const TimeInterval& rInterval) {
510 FD_DC("TimeConstraint(" << this << ")::Interval(" << clockindex <<", " << rInterval.Str() << ") ");
511 EraseByClock(clockindex);
512 if(rInterval.LBinf()==false) {
513 ElemConstraint newconstraint;
514 newconstraint.Clock(clockindex);
515 if(rInterval.LBincl())
517 else
519 newconstraint.TimeConstant(rInterval.LB());
520 Insert(newconstraint);
521 }
522 if(rInterval.UBinf()==false) {
523 ElemConstraint newconstraint;
524 newconstraint.Clock(clockindex);
525 if(rInterval.UBincl())
527 else
529 newconstraint.TimeConstant(rInterval.UB());
530 Insert(newconstraint);
531 }
532}
533
534
535// Minimize()
537 ClockSet aclocks=ActiveClocks();
538 ClockSet::Iterator cit;
539 for(cit=aclocks.Begin(); cit != aclocks.End(); cit++) {
540 TimeInterval tint=Interval(*cit);
541 Interval(*cit, tint);
542 }
543}
544
545// operator==
546bool TimeConstraint::operator== (const TimeConstraint & rOther) const {
547 ClockSet aclocks=ActiveClocks();
548 aclocks.InsertSet(rOther.ActiveClocks());
549 ClockSet::Iterator cit;
550 for(cit=aclocks.Begin(); cit != aclocks.End(); cit++) {
551 TimeInterval tint=Interval(*cit);
552 if(rOther.Interval(*cit)!=tint) return false;
553 }
554 return true;
555}
556
557// operator!=
558bool TimeConstraint::operator!= (const TimeConstraint & rOther) const {
559 return !(operator==(rOther));
560}
561
562
563// Write()
564void TimeConstraint::Write(void) const {
566 Write(tw);
567}
568
569// Write(rFilename, rLabel, openmode)
570void TimeConstraint::Write(const std::string& rFilename, const std::string& rLabel,
571 std::ios::openmode openmode) const {
572 try {
573 TokenWriter tw(rFilename, openmode);
574 Write(tw, rLabel);
575 }
576 catch (std::ios::failure&) {
577 std::stringstream errstr;
578 errstr << "Exception opening/writing file \"" << rFilename << "\"";
579 throw Exception("TimeConstraint::Write", errstr.str(), 2);
580 }
581}
582
583// Write(tw)
585 Write(tw, Name());
586}
587
588
589// Write(tw, rLabel)
590void TimeConstraint::Write(TokenWriter& tw, const std::string& rLabel) const {
591 Token token;
592 Iterator it;
593 int oldcolumns = tw.Columns();
594 tw.Columns(3);
595 tw.WriteBegin(rLabel);
596 for (it = Begin(); it != End(); ++it) {
597 // 1. clock
598 if(ClockName(it->Clock()) != "") {
599 token.SetString(ClockName(it->Clock()));
600 tw << token;
601 } else {
602 token.SetInteger(it->Clock());
603 tw << token;
604 }
605 // 2. operator
606 token.SetString(ElemConstraint::OperatorName(it->CompOperator()));
607 tw << token;
608 // 3. timeconst
609 token.SetFloat((Float) it->TimeConstant());
610 tw << token;
611 }
612 tw.WriteEnd(rLabel);
613 tw.Columns(oldcolumns);
614}
615
616
617// ToString()
618std::string TimeConstraint::ToString(void) const {
620 Write(tw);
621 return tw.Str();
622}
623
624
625// DWrite()
626void TimeConstraint::DWrite(void) const {
628 DWrite(tw);
629}
630
631// DWrite(tw)
633 Token token;
634 Iterator it;
635 tw.WriteBegin(Name());
636 for (it = Begin(); it != End(); ++it) {
637 tw << EStr(*it);
638 }
639 tw.WriteEnd(Name());
640}
641
642// Read(rFilename, rLabel)
643void TimeConstraint::Read(const std::string& rFilename, const std::string& rLabel) {
644 TokenReader tr(rFilename);
645 Read(tr,rLabel);
646}
647
648// Read(rTr, rLabel)
649void TimeConstraint::Read(TokenReader& rTr, const std::string& rLabel) {
650 Clear();
651 Name(rLabel);
652 rTr.ReadBegin(rLabel);
653
654 std::string clockname;
655 Time::Type timeconst;
657 Token token;
658 while(rTr.Peek(token)) {
659 // 0. check for end
660 if (token.Type() == Token::End) {
661 break;
662 }
663 // 1. read clock
664 rTr >> token;
665 if (token.Type() != Token::String) {
666 std::stringstream errstr;
667 errstr << "Invalid clock" << rTr.FileLine();
668 throw Exception("TimeConstraint::Read", errstr.str(), 56);
669 }
670 clockname=token.StringValue();
671 // 2. read operator
672 rTr >> token;
673 if (token.Type() != Token::String) {
674 std::stringstream errstr;
675 errstr << "Invalid operator" << rTr.FileLine();
676 throw Exception("TimeConstraint::Read", errstr.str(), 56);
677 }
678 if(token.StringValue() == "LE") {
680 } else if(token.StringValue() == "GE") {
682 } else if(token.StringValue() == "LT") {
684 } else if(token.StringValue() == "GT") {
686 } else {
687 std::stringstream errstr;
688 errstr << "Invalid operator value " << rTr.FileLine();
689 throw Exception("TimedTransSet::ReadTimeConstraint", errstr.str(), 56);
690 }
691 // 3. read timeconst
692 rTr >> token;
693 if (!token.IsFloat()) {
694 std::stringstream errstr;
695 errstr << "Invalid timeconstant" << rTr.FileLine();
696 throw Exception("TimeConstraint::Read", errstr.str(), 56);
697 }
698 timeconst=(Time::Type) token.FloatValue();
699 // 4. set constraint
700 Insert(clockname,compop,timeconst);
701 } // while not end
702 rTr.ReadEnd(rLabel);
703}
704
705
706// End Implementation of TimeConstraint
707
708
709
710} // namespace faudes
#define FD_DC(message)
#define FD_ERR(message)
#define FAUDES_TYPE_IMPLEMENTATION_EQUAL(ftype, ctype, cbase)
Definition cfl_types.h:916
#define FAUDES_TYPE_IMPLEMENTATION_COPY(ftype, ctype, cbase)
Definition cfl_types.h:903
#define FAUDES_TYPE_IMPLEMENTATION_CAST(ftype, ctype, cbase)
Definition cfl_types.h:905
#define FAUDES_TYPE_IMPLEMENTATION_ASSIGN(ftype, ctype, cbase)
Definition cfl_types.h:908
virtual void DoAssign(const ClockSet &rSourceSet)
virtual bool DoEqual(const ClockSet &rOtherSet) const
static SymbolTable * GlobalClockSymbolTablep(void)
bool operator<(const ElemConstraint &otherElemConstraint) const
Operator CompOperator(void) const
bool operator==(const ElemConstraint &otherElemConstraint) const
Time::Type TimeConstant(void) const
bool operator!=(const ElemConstraint &otherElemConstraint) const
void Set(Idx clockindex, Operator op, Time::Type timeconst)
std::string Str(void) const
void TimeConstant(Time::Type newTimeConst)
static std::string OperatorName(Operator op)
void CompOperator(Operator newOp)
virtual void InsertSet(const NameSet &rOtherSet)
bool DoEqual(const NameSet &rOtherSet) const
SymbolTable * SymbolTablep(void) const
bool Insert(const Idx &rIndex)
SymbolTable * mpSymbolTable
void DoAssign(const NameSet &rSourceSet)
std::string Symbol(Idx index) const
Idx InsEntry(Idx index, const std::string &rName)
Idx Index(const std::string &rName) const
std::set< ElemConstraint > ClockConstraints(void) const
Idx InsClock(const std::string &rClockName) const
std::set< ElemConstraint >::const_iterator Iterator
Iterator Erase(Iterator it)
std::string ToString(void) const
bool Exists(const ElemConstraint &rElemConstr) const
Iterator End(void) const
std::string ClockName(Idx clockindex) const
std::string EStr(const ElemConstraint &rElemConstr) const
std::set< ElemConstraint > mClockConstraints
void Read(const std::string &rFileName, const std::string &rLabel="TimeConstraint")
RIterator RBegin(void) const
TimeInterval Interval(Idx clockindex) const
bool operator==(const TimeConstraint &rOther) const
bool operator!=(const TimeConstraint &rOther) const
std::set< ElemConstraint >::const_reverse_iterator RIterator
Idx ClockIndex(const std::string &rClockName) const
RIterator REnd(void) const
Iterator Begin(void) const
std::string Name(void) const
std::set< ElemConstraint >::iterator iterator
Iterator Insert(const ElemConstraint &rElemConstr)
ClockSet ActiveClocks(void) const
SymbolTable * ClockSymbolTablep(void) const
void LB(Time::Type time)
bool UBinf(void) const
std::string Str(void) const
void UBincl(bool incl)
void LBincl(bool incl)
void UB(Time::Type time)
bool LBinf(void) const
void Intersect(const TimeInterval &rOtherInterval)
std::string FileLine(void) const
void ReadEnd(const std::string &rLabel)
void ReadBegin(const std::string &rLabel)
bool Peek(Token &token)
std::string Str(void)
void WriteEnd(const std::string &rLabel)
int Columns(void) const
void WriteBegin(const std::string &rLabel)
void SetInteger(const Int number)
@ End
<\label> (end of section)
Definition cfl_token.h:85
@ String
any string, space separated or quoted, must start with a letter
Definition cfl_token.h:86
void SetString(const std::string &rName)
Definition cfl_token.cpp:85
void SetFloat(const faudes::Float number)
TokenType Type(void) const
void Read(const std::string &rFileName, const std::string &rLabel="", const Type *pContext=0)
virtual const std::string & Name(void) const
virtual Type * New(void) const
Definition cfl_types.cpp:54
Iterator End(void) const
Iterator Begin(void) const
uint32_t Idx
double Float

libFAUDES 2.33k --- 2025.09.16 --- c++ api documentaion by doxygen