How to create a new Fact

If you are defining facts to include as part of an event, an event’s interval is specified by the source-to-model ETL parsers. The specification of a Fact (type) is independent of the specification of the time interval that a fact (value) occurs.

Adding a new Fact

Once you have created your Fact.dhall files, you may submit a merge request and ask that a member of dev team assist with the remaining tasks.
  1. Add a new directory for your fact in fact-models/src/Facts. Use CamelCase for the fact’s name.

  2. In this new directory, create a file called Fact.dhall in which to define the new fact, as described in the Anatomy of Fact.dhall.

  3. To build the fact’s artifacts, run the following command from the project’s root directory (changing <MyFact> to the name of the new fact):

    cabal run fact-models:exe:fact -- build --fact=NameOfFact

    For more about this application, see Using the fact Application.

    The --dry-run flag directs the output to stdout instead of writing files.

    This command creates the files derived from Fact.dhall, namely:

    • Fact-examples.json: The facts from the examples (deduplicated) in JSON format

    • Fact-example.json: The fact from the head example. Used to present example JSON in the documentation site.

    • Fact.dhallType: The Type field from Fact.dhall used to display the type in the documentation site.

    • Fact: A frozen version of Fact.dhall, which an be used to check the integrity of facts, as in dhall freeze --check.

  4. Add entries for the new fact in:

    • fact-models/src/Facts/package.dhall

    • fact-models/src/package.dhall in the fact-srcs object

    • docs/modules/models/pages/facts.adoc

Anatomy of a Fact.dhall file

A Fact.dhall consists of 4 key elements:

  1. a description

  2. a Type

  3. a corresponding predicate Type

  4. examples

Each of these elements are further described below, using the claim fact as an example.

This documentation does not use AsciiDoctor’s callouts. It should, but at the time of this writing, Dhall’s linter removes the end of line of comments.

Description

The description should describe how the fact should be used.

{-|
{- tag::description[] -}

= Claim

The claim fact is used to capture claim information
about an event.
This would most commonly be used in insurance claim data.

{- end::description[] -}
-}

Description text must be written:

  • in AsciiDoc syntax

  • within the Dhall comment header and enclosed by {- tag::description[] -} and {- end::description[] -},

  • include an AsciiDoc level 0 section with the fact’s name:

    = Some name

Type

A fact’s type specifies what data a fact may contain. Fact types may either be a record or a union type.

let Claim =
      { id : Text
      , claim_type : Optional Text
      , index : Optional Integer
      , procedure : Optional Text
      }

The Claim fact defined above is a record type with 4 fields, only one of which is required: id.

View example json for Claim fact
{ "id": "abcd" }
{ "id": "abcd", "claim_type": "some_type", "index": 1 }

Facts can be composed of other facts. The ClaimsFacts type, for example, includes the claim field which contains a Claim fact:

let claim = ../Claim/Fact.dhall
      { claim : claim.Type
      , cost : Optional cost.Type
      , provider : Optional provider.Type
      , service : Optional service.Type
      }

let combineClaimCost =

The ServiceLocation fact is an example of union type, in this case simply enumerating the possible locations:

let ServiceLocation = < Inpatient | Outpatient >

The TNValue fact in an example of union type which contains values. This fact specifies that a value of its type must either be a TextValue containing Text or a NumberValue containing a number.

let TNValue = < NumberValue : Double | TextValue : Text >

The Dhall types are used to automatically generate Haskell types, so the types need to conform to Haskell requirements. Specifically,

  • The word type cannot be used as a record key.

  • Names of union type variants must start with a capital letter. For example, this will successfully generate Haskell code:

    < Foo : Text | Bar >

    while this will not:

    < Foo : Text | bar >

PredCons Type

Every fact type has a corresponding predicate constructor (PredCons) type. This type specifies how predicates of the fact type are defined based on the predicate logic.

The Claim fact, for example, specifies that predicates may only be defined on the claim_type field:

let exampleFact1
Future versions of the fact-models packages may automatically derive the predicate constructor shape(s). For now, it must be defined by the developer.

Examples

Each fact file must contain examples of values of the fact, predicate constructors of the fact, and the value (True or False) of what the predicate should return for a given fact. See the complete fact an example.

    = { id = "foo"
      , claim_type = None Text
      , index = Some +7
      , procedure = None Text
      }

let exampleFact2
The fact-models utilities contains Dhall functions for combining facts from other facts. See the functions in fact-models/src/utils/example_utils.dhall.
At least one example is required; more examples are highly encouraged.

Complete fact

The result of compiling a Fact.dhall file is required to be a particular shape. The Dhall function in fact-models/src/utils/Fact.dhall takes the Type, predicate constructor Type, and examples to create a value of the required shape. The following is an outline of how a Fact.dhall might be structured, minus the description.

let Fact = ../../utils/Fact.dhall

let MyType = <...>

let MyTypePredCons = <...>

let exampleFact1 = <...>

let exampleFact2 = <...>

let examplePredCons1 = <...>

let examplePredCons2 = <...>

in Fact
    MyType
    MyTypePredCons
    { shouldbe = True, notion = examplePredCons1, fact = exampleFact1 }
    [{ shouldbe = True, notion = examplePredCons2, fact = exampleFact2 }]

The following shows a complete example of a working Fact.dhall file.

{-|
{- tag::description[] -}

= Claim

The claim fact is used to capture claim information
about an event.
This would most commonly be used in insurance claim data.

{- end::description[] -}
-}
let Fact = ../../utils/Fact.dhall

let Claim =
      { id : Text
      , claim_type : Optional Text
      , index : Optional Integer
      , procedure : Optional Text
      }

let exampleFact1
    : Claim
    = { id = "foo"
      , claim_type = None Text
      , index = Some +7
      , procedure = None Text
      }

let exampleFact2
    : Claim
    = { id = "foo"
      , claim_type = Some "notbar"
      , index = Some +7
      , procedure = None Text
      }



in  Fact
      Claim
      exampleFact1
      [ exampleFact2 ]