#1115 Xeto - explicit vs implicit specs?

James Gessel Wed 1 May

Are specs intended to be explicit or implicit?

This is first a question, and then depending on the answer may turn into a proposal. I'd like to understand the current intentions first.

I'm just beginning to work with xeto, so I appreciate your patience if these are dumb questions :D

Explicit Workflow

My idea of an explicit workflow is the following:

-Define specs in a lib
-Build equips/points
-Assign each equip/point a specific and permanent spec 
-Equips/points auto-inherit spec attributes (TAGS AND POINTS)

The user essentially says this equip should match this spec. This approach has numerous advantages:

  • specs are more easily assignable and digestible than tag combinations
  • you can validate against the given spec, even if tags are changed or ommitted on the equip/point
  • you can auto-inherit any changes made to the spec

This is great. However, I have a major concern with this approach. It requires explicit specs for every single unique combination of AHU extensions. Even if there are only 10 extensions, that evaluates to over 1,000 unique specs to handle each combination. If those have to be pre-defined in a lib to be usable, its a non starter.

Implicit Workflow

By contrast, an implicit workflow looks like:

-Define specs 
-Build equips/points
-Equips/points auto-inherit attributes (EXCEPT tags, since they are manually defined)

Now instead of telling, the user is asking what specs does this equip fit? so they can validate other (non-tag) attributes. Simply adding a tag will auto-inherit new specs and attributes. No need for 1,000 unique specs.

This way, you can

  • still validate (at least using the newly fitted specs)
  • quickly add components to equips and validate newly required additions
  • avoid having to create every single unique combination of specs in a predefined lib

Ideally

Ideally (and I think this is the case), xeto will allow for both implicit and explicit approaches. I think having tools for both makes sense - even if you have to choose between them. I can think of a few ways to accomplish this:

  • Allowing "local" specs outside of a lib. If the explicit spec tag could handle a list of specs (and could compile attributes without duplications) that would work well
  • Having some sort of validationMethod "choice" to use explicit specs vs auto-inherit based on tagging.

Brian Frank Thu 2 May

Hi James,

I probably didn't follow your questions 100%, but from a broad perspective the answer is yes Xeto will support both implicit and explicit validation.

Explicitly you can annotate an entity with the "spec" tag which is a Ref with the spec's qualified name. This informs the system that the entity is expected to conform to that spec. This is nominal typing of the entity. In the Haxall implementation, you can use the fitsExplain() function with a null spec and it will validate the input dicts against their spec tag (validate them against what they say they are).

Implicitly you can use structural typing to validate against any spec. Or you can run queries to see what specs your entities fit. So there is a lot of flexibility in how you use those features to build up validation routines.

James Gessel Wed 22 May

Brian,

Thanks for the response. After playing with it a bit more, we came across a need that I think is both reasonable and crucial.

Say I have a brand new ahu equip and I want to generate a required points list. Per the implicit workfow mentioned above, this AHU is NOT given an explicit spec, rather I want to craft the expected points list based on its tags.

When I use fitsMatchAll(), it only matches specs that are exact matches (both tags and required points). So if an equip has no points, it doesn't fit any of the specs.

If we had a tagsOnly flag for all the fits() functions, that would be a great solution. We can come up with a workaround, but I think this would be a useful feature that would be widely used.

James Gessel Wed 22 May

Additionally, a specsToPoints() function would be amazing :D

specsToPoints: takes a list of specs and returns a flattened list of points (with an indicator for required or optional)

//example use 
expectedPoints: read(equip).fitsMatchAll().specsToPoints() 

Brian Frank Wed 22 May

If we had a tagsOnly flag for all the fits() functions, that would be a great solution. We can come up with a workaround, but I think this would be a useful feature that would be widely used.

Ok, this might be good direction. But I think I would start by defining your specs using inheritance to handle that easily. For example you could just have one spec for the tags, then another spec that adds in the points. Then you can easily query both ways by name. But I guess if that becomes awkward we could add in more options to the functions.

Additionally, a specsToPoints() function would be amazing :D

A convenience function might be nice. But you can already get the point list pretty easily a couple different ways

specSlots(G36ReheatVav)->points.specSlots.vals

spec("ashrae.g36::G36ReheatVav.points").specSlots.vals

James Gessel Wed 22 May

one spec for the tags, then another spec that adds in the points

I'd really like to avoid this for a few reasons, first since it would significantly increase the amount of specs we'd have to create. So I'd certainly prefer the tagsOnly flag option :D

A convenience function might be nice. But you can already get the point list pretty easily a couple different ways

We created our convenience function exactly like this! I just think it'll be used widely enough its worth making.

Thanks for considering!

Dylan Bardin Sun 7 Jul

Hey Brain,

Has a decision been made regarding the "tagsOnly" opt for the fits() funcs? And might it come in 3.1.11? Just wondering as we continue to build out our functionality around Xeto and the Xeto specs themselves.

Thanks!

Dylan

Brian Frank Tue 9 Jul

Recently I'm thinking that the "tags only" behavior should be the default, and fitting the graph of entities is an option. That would be more consistent with the instantiate function that works that way:

// evaluates to dict {equip, vav, hotWaterHeating, ...}
instantiate(G36ReheatVav)

// evaluates to dict[] of vav + points from constrained query
instantiate(G36ReheatVav, {graph})

If we follow that model for fits and fitsExplain would like this:

// fit tags only, and not points
readAll(vav).fitsExplain(G36ReheatVav)

// fit tags and points
readAll(vav).fitsExplain(G36ReheatVav, {graph})

Brian Frank Fri 12 Jul

I made the change to default fits/fitsExplain to "tag only" mode. Then you can pass the {graph} option to validate queries for required points, etc.

This changeset will be included in release 3.1.11

Dylan Bardin Fri 19 Jul

Woohoo! Thanks Brian!

Login or Signup to reply.