def domainForObject(obj, ignoredProperties): """Construct a Domain for the given Scenic Object""" domains = {} for prop in obj.properties: if prop in ignoredProperties: continue value = getattr(obj, prop) if prop in normalizedProperties: value = coerce(value, normalizedProperties[prop]) # TODO improve this system... (need to get better type info in Scenic) if prop in specialDomainProperties and needsSampling(value): dom = specialDomainProperties[prop] else: dom = domainForValue(value) if dom is None: ty = underlyingType(value) print(f'WARNING: skipping property "{prop}" of unknown type {ty}') else: domains[prop] = dom # add type as additional property value = type(obj).__name__ dom = domainForValue(value) assert dom is not None assert 'type' not in domains domains['type'] = dom return Struct(domains)
def leftSpecHelper(syntax, pos, dist, axis, toComponents, makeOffset): extras = set() if canCoerce(dist, float): dx, dy = toComponents(coerce(dist, float)) elif canCoerce(dist, Vector): dx, dy = coerce(dist, Vector) else: raise RuntimeParseError(f'"{syntax} X by D" with D not a number or vector') if isinstance(pos, OrientedPoint): # TODO too strict? val = lambda self: pos.relativize(makeOffset(self, dx, dy)) new = DelayedArgument({axis}, val) extras.add('heading') else: pos = toVector(pos, f'specifier "{syntax} X" with X not a vector') val = lambda self: pos.offsetRotated(self.heading, makeOffset(self, dx, dy)) new = DelayedArgument({axis, 'heading'}, val) return Specifier('position', new, optionals=extras)
def pointForValue(dom, scenicValue): """Convert a sampled Scenic value to a point in the corresponding Domain""" if isinstance(dom, Constant): value = convertToVerifaiType(scenicValue, strict=False) assert value == dom.value return value elif isinstance(dom, Categorical): value = convertToVerifaiType(scenicValue, strict=False) assert value in dom.values return value elif dom == scalarDomain: if not isinstance(scenicValue, (float, int)): raise RuntimeError( f'could not coerce Scenic value {scenicValue} to scalar') return coerce(scenicValue, float) elif dom == vectorDomain: return tuple(coerce(scenicValue, Vector)) elif dom == colorDomain: assert isinstance(scenicValue, (tuple, list)) assert len(scenicValue) == 3 return scenicValue else: raise RuntimeError( f'Scenic value {scenicValue} has unexpected domain {dom}')
def convertToVerifaiType(value, strict=True): """Attempt to convert a Scenic value to a type known to Verifai""" ty = underlyingType(value) if ty is float or ty is int: return float(value) elif canCoerceType(ty, Vector): return tuple(coerce(value, Vector)) elif ty is GTACarModel: return value elif ty is WebotsCarModel: return value elif ty is CarColor: return value elif strict: # Unknown type, so give up if we're being strict raise RuntimeError( f'attempted to convert Scenic value {value} of unknown type {ty}') else: return value
def convertToVerifaiType(value, strict=True): """Attempt to convert a Scenic value to a type known to VerifAI""" ty = underlyingType(value) if ty is float or ty is int: return float(value) elif ty is list or ty is tuple: return tuple(convertToVerifaiType(e, strict=strict) for e in value) elif issubclass(ty, dict) and not needsSampling(value): return frozendict(value) elif ty is GTACarModel: return value elif ty is WebotsCarModel: return value elif ty is Color: return value elif canCoerceType(ty, Vector): return tuple(coerce(value, Vector)) elif strict: # Unknown type, so give up if we're being strict raise RuntimeError( f'attempted to convert Scenic value {value} of unknown type {ty}') else: return value