def valid_path_to_next_field_condition( self, message: Message, field: Field, field_type: Type ) -> Sequence[Expr]: return [ If( [ ( l.condition, And( Equal( Call("Predecessor", [Name("Ctx"), Name(l.target.affixed_name)],), Name(field.affixed_name), ), Call("Valid_Next", [Name("Ctx"), Name(l.target.affixed_name)]) if l.target != FINAL else TRUE, ), ) ] ).simplified( { **{ Variable(field.name): Call("Convert", [Name("Value")]) if isinstance(field_type, Enumeration) and field_type.always_valid else Name("Value") }, **self.public_substitution(message), } ) for l in message.outgoing(field) if l.target != FINAL ]
def valid_path_to_next_field_condition( message: model.Message, field: model.Field, prefix: str ) -> Sequence[Expr]: return [ If( [ ( l.condition.substituted(substitution(message, public=True, prefix=prefix)) .simplified() .ada_expr(), And( Equal( Call( "Predecessor", [Variable("Ctx"), Variable(l.target.affixed_name)], ), Variable(field.affixed_name), ), Call( "Valid_Next", [Variable("Ctx"), Variable(l.target.affixed_name)], ) if l.target != model.FINAL else TRUE, ), ) ] ) for l in message.outgoing(field) if l.target != model.FINAL ]
def valid_message_condition(message: Message, field: Field = INITIAL, structural: bool = False) -> Expr: if not message.outgoing(field): return TRUE return Or(*[ l.condition if l.target == FINAL else AndThen( Call( "Structural_Valid" if structural and isinstance( message.types[l.target], Composite) else "Valid", [Variable("Ctx" ), Variable(l.target.affixed_name)], ), l.condition, valid_message_condition(message, l.target, structural), ) for l in message.outgoing(field) ])
def has_size_dependent_condition(message: model.Message, field: model.Field = None) -> bool: field_sizes = {expr.Size(f.name) for f in message.fields} links = message.outgoing(field) if field else message.structure return any( size in field_sizes for link in links for size in link.condition.findall(lambda x: isinstance(x, expr.Size)) )
def has_aggregate_dependent_condition(message: model.Message, field: model.Field = None) -> bool: links = message.outgoing(field) if field else message.structure fields = [field] if field else message.fields return any( r for l in links for r in l.condition.findall(lambda x: isinstance(x, (expr.Equal, expr.NotEqual))) if isinstance(r, (expr.Equal, expr.NotEqual)) and r.findall(lambda x: isinstance(x, expr.Aggregate)) and any( r.left == expr.Variable(f.identifier) or r.right == expr.Variable(f.identifier) for f in fields ) )
def has_value_dependent_condition(message: model.Message, field: model.Field = None) -> bool: links = message.outgoing(field) if field else message.structure fields = [field] if field else message.fields return any( r for l in links for r in l.condition.findall(lambda x: isinstance(x, expr.Relation)) if isinstance(r, expr.Relation) and not r.findall(lambda x: isinstance(x, expr.Aggregate)) and r.findall( lambda x: isinstance(x, expr.Variable) and any(x.identifier == f.identifier for f in fields) ) )
def message_structure_invariant( message: Message, prefix: str, link: Link = None, embedded: bool = False ) -> Expr: def prefixed(name: str) -> Expr: return Selected(Variable("Ctx"), name) if not embedded else Variable(name) if not link: return message_structure_invariant(message, prefix, message.outgoing(INITIAL)[0], embedded) source = link.source target = link.target if target is FINAL: return TRUE field_type = message.types[target] condition = link.condition.substituted(substitution(message, embedded)).simplified() length = ( Size(prefix * full_base_type_name(field_type)) if isinstance(field_type, Scalar) else link.length.substituted( substitution(message, embedded, target_type=const.TYPES_BIT_LENGTH) ).simplified() ) first = ( prefixed("First") if source == INITIAL else link.first.substituted(substitution(message, embedded)) .substituted( mapping={ UNDEFINED: Add( Selected(Indexed(prefixed("Cursors"), Variable(source.affixed_name)), "Last"), Number(1), ) } ) .simplified() ) return If( [ ( AndThen( Call( "Structural_Valid", [Indexed(prefixed("Cursors"), Variable(target.affixed_name))], ), condition, ), AndThen( Equal( Add( Sub( Selected( Indexed(prefixed("Cursors"), Variable(target.affixed_name)), "Last", ), Selected( Indexed(prefixed("Cursors"), Variable(target.affixed_name)), "First", ), ), Number(1), ), length, ), Equal( Selected( Indexed(prefixed("Cursors"), Variable(target.affixed_name)), "Predecessor", ), Variable(source.affixed_name), ), Equal( Selected( Indexed(prefixed("Cursors"), Variable(target.affixed_name)), "First" ), first, ), *[ message_structure_invariant(message, prefix, l, embedded) for l in message.outgoing(target) ], ), ) ] ).simplified()
def message_structure_invariant( self, message: Message, link: Link = None, prefix: bool = True ) -> Expr: def prefixed(name: str) -> Expr: return Selected(Name("Ctx"), name) if prefix else Name(name) if not link: return self.message_structure_invariant(message, message.outgoing(INITIAL)[0], prefix) source = link.source target = link.target if target is FINAL: return TRUE field_type = message.types[target] condition = link.condition.simplified(self.substitution(message, prefix)) length = ( Size(base_type_name(field_type)) if isinstance(field_type, Scalar) else link.length.simplified(self.substitution(message, prefix)) ) first = ( Name(prefixed("First")) if source == INITIAL else link.first.simplified( { **self.substitution(message, prefix), **{ UNDEFINED: Add( Selected( Indexed(prefixed("Cursors"), Name(source.affixed_name)), "Last" ), Number(1), ) }, } ) ) return If( [ ( AndThen( Call( "Structural_Valid", [Indexed(prefixed("Cursors"), Name(target.affixed_name))], ), condition, ), AndThen( Equal( Add( Sub( Selected( Indexed(prefixed("Cursors"), Name(target.affixed_name)), "Last", ), Selected( Indexed(prefixed("Cursors"), Name(target.affixed_name)), "First", ), ), Number(1), ), length, ), Equal( Selected( Indexed(prefixed("Cursors"), Name(target.affixed_name)), "Predecessor", ), Name(source.affixed_name), ), Equal( Selected( Indexed(prefixed("Cursors"), Name(target.affixed_name)), "First" ), first, ), *[ self.message_structure_invariant(message, l, prefix) for l in message.outgoing(target) ], ), ) ] ).simplified()
def message_structure_invariant( message: model.Message, prefix: str, link: model.Link = None, embedded: bool = False ) -> Expr: def prefixed(name: str) -> expr.Expr: return expr.Selected(expr.Variable("Ctx"), name) if not embedded else expr.Variable(name) if not link: return message_structure_invariant( message, prefix, message.outgoing(model.INITIAL)[0], embedded ) source = link.source target = link.target if target == model.FINAL: return TRUE field_type = message.types[target] condition = link.condition.substituted(substitution(message, prefix, embedded)).simplified() size = ( field_type.size if isinstance(field_type, model.Scalar) else link.size.substituted( substitution(message, prefix, embedded, target_type=const.TYPES_BIT_LENGTH) ).simplified() ) first = ( prefixed("First") if source == model.INITIAL else link.first.substituted( substitution(message, prefix, embedded, target_type=const.TYPES_BIT_INDEX) ) .substituted( mapping={ expr.UNDEFINED: expr.Add( expr.Selected( expr.Indexed(prefixed("Cursors"), expr.Variable(source.affixed_name)), "Last", ), expr.Number(1), ) } ) .simplified() ) invariant = [ message_structure_invariant(message, prefix, l, embedded) for l in message.outgoing(target) ] return If( [ ( AndThen( Call( "Structural_Valid", [Indexed(prefixed("Cursors").ada_expr(), Variable(target.affixed_name))], ), *([condition.ada_expr()] if condition != expr.TRUE else []), ), AndThen( Equal( Add( Sub( Selected( Indexed( prefixed("Cursors").ada_expr(), Variable(target.affixed_name), ), "Last", ), Selected( Indexed( prefixed("Cursors").ada_expr(), Variable(target.affixed_name), ), "First", ), ), Number(1), ), size.ada_expr(), ), Equal( Selected( Indexed( prefixed("Cursors").ada_expr(), Variable(target.affixed_name), ), "Predecessor", ), Variable(source.affixed_name), ), Equal( Selected( Indexed( prefixed("Cursors").ada_expr(), Variable(target.affixed_name), ), "First", ), first.ada_expr(), ), *[i for i in invariant if i != TRUE], ), ) ] )