# Appendix I - FHIRPath Translation - Clinical Quality Language Specification v2.0.0-ballot

* [**Table of Contents**](toc.md)
* [**CQL Specification**](index.md)
* **Appendix I - FHIRPath Translation**

## Appendix I - FHIRPath Translation

| | |
| :--- | :--- |
| *Page standards status:*[Normative](http://hl7.org/fhir/R4/versions.html#std-process) | [Maturity Level](http://hl7.org/fhir/versions.html#maturity): N |

This appendix provides detailed mappings for each FHIRPath function in terms of the ELM output produced.

In addition to the function mappings below, the $index accessor can be used within the FHIRPath iteration functions (i.e. FHIRPath functions that take an **expression** as an argument) to access the 0-based index of the current iteration.

### .aggregate()

```
X.aggregate(<iteration>, <init>) === Aggregate(<iteration>, <init>)

```

In addition, the $total accumulator can be used within the iteration and init expressions to access the current value of the accumulator.

### .abs()

```
X.abs() === Abs(X)

```

### .all()

```
X.all(<condition>) === AllTrue(X $this let a: <condition> where a return a)

```

### .allFalse()

```
X.allFalse() === AllTrue(X A return not A)

```

### .allTrue()

```
X.allTrue() === AllTrue(X)

```

### .anyFalse()

```
X.anyFalse() === AnyTrue(X A return not A)

```

### .anyTrue()

```
X.anyTrue() === AnyTrue(X)

```

### .as()

```
X.as(T) === X as T

```

Note that the type argument T is expected to be a literal string and must resolve to the name of a type.

### .ceiling()

```
X.ceiling() === Ceiling(X)

```

### .children()

```
.children(X) === Children(X)

```

### .combine()

```
X.combine(Y) === Flatten(\{ X, Y })

```

### .conformsTo()

```
X.conformsTo(Y) === FHIRSupport.ConformsTo(Y)

```

Note that this mapping relies on an external library, FHIRSupport to provide conformance validation checking.

### .contains()

```
X.contains(Y) === PositionOf(Y, X) >= 0

```

### .convertsToBoolean()

```
X.convertsToBoolean() === ConvertsToBoolean(X)

```

### .convertsToDate()

```
X.convertsToDate() === ConvertsToDate(X)

```

### .convertsToDateTime()

```
X.convertsToDateTime() === ConvertsToDateTime(X)

```

### .convertsToDecimal()

```
X.convertsToDecimal() === ConvertsToDecimal(X)

```

### .convertsToInteger()

```
X.convertsToInteger() === ConvertsToInteger(X)

```

### .convertsToQuantity()

```
X.convertsToQuantity() === ConvertsToQuantity(X)

```

### .convertsToTime()

```
X.convertsToTime() === ConvertsToTime(X)

```

### .count()

```
X.count() === Count(X)

```

### .dateOf()

```
X.dateOf() === date from X

```

### .dayOf()

```
X.dayOf() === day from X

```

### .decode()

```
X.decode(format) === Decode(X, format)

```

### .defineVariable()

Because the defineVariable function is introducing a named alias, all subsequent fluent function invocations must be evaluated within the query.

In addition, the name argument must be compile-time evaluable.

```
X.defineVariable(name) === { input: X } alias let name: alias.X return X
X.defineVariable(name, expression) === X alias let name: expression

```

### .descendants()

```
.descendants(X) === Descendants(X)

```

### .distinct()

```
X.distinct() === distinct X

```

### .empty()

```
X.empty() === not exists X

```

### .encode()

```
X.encode(format) === Encode(X, format)

```

### .endsWith()

```
X.endsWith(Y) === EndsWith(X, Y)

```

### .escape()

```
X.escape(target) === Escape(X, target)

```

### .exclude()

```
X.exclude(Y) === X except Y

```

### .exists()

```
X.exists() === exists X

X.exists(<condition>) === exists (X $this where <condition>)

```

### .exp()

```
X.exp() === Exp(X)

```

### .first()

```
X.first() === First(X)

```

### .floor()

```
X.floor() === Floor(X)

```

### .hasValue()

```
X.hasValue() === X is not null

```

### .highBoundary()

```
X.highBoundary(precision) === HighBoundary(X, precision)

```

### .hourOf()

```
X.hourOf() === hour from X

```

### .iif()

```
iif(X, Y) === if X then Y else null

iif(X, Y, Z) === if X then Y else Z

```

### .indexOf()

```
X.indexOf(Y) === PositionOf(Y, X) // Note carefully the order of arguments here, it’s the opposite of IndexOf

```

### .intersect()

```
X.intersect(Y) === X intersect Y

```

### .is()

```
X.is(T) === X is T

```

Note that the argument T is expected to be a literal string and must resolve to the name of a type.

### .isDistinct()

```
X.isDistinct() === Count(X) = Count(distinct X)

```

### .join()

```
X.join(separator) === Combine(X, separator)

```

### .last()

```
X.last() === Last(X)

```

### .lastIndexOf()

```
X.lastIndexOf(Y) === LastPositionOf(Y, X) // Note carefully the order of arguments here, it’s the opposite of lastIndexOf.

```

### .length()

```
X.length() === Length(X)

```

### .ln()

```
X.ln() === Ln(X)

```

### .log()

```
X.log(B) === Log(X, B)

```

### .lowBoundary()

```
X.lowBoundary(precision) === LowBoundary(X, precision)

```

### .lower()

```
X.lower() === Lower(X)

```

### .matches()

```
X.matches(Y) === Matches(X, Y)

```

### .matchesFull()

```
X.matchesFull(Y) === Matches(X, '^' + Y + '$')

```

### .memberOf()

```
X.memberOf(Y) === InValueSet(X, Y) // where Y is required to be a ValueSetRef

```

### .millisecondOf()

```
X.millisecondOf() === millisecond from X

```

### .minuteOf()

```
X.minuteOf() === minute from X

```

### .monthOf()

```
X.monthOf() === month from X

```

### .ofType()

```
X.ofType(T) === X $this where $this is T return $this as T

```

Note that the argument T is required to be a literal string, and is interpreted as the name of a type. For non-named-types, type specifier syntax applies.

### .not()

```
X.not() === not X

```

### .now()

```
now() === Now()

```

### .power()

```
X.power(Y) === Power(X, Y)

```

### .precision()

```
X.precision() === Precision(X)

```

### .repeat()

```
X.repeat(<element>) === Repeat(X, <element>)

```

The type of X.repeat() is inferred as the type of:

```
X.select(<element>).select(<element>)

```

### .replace()

```
X.replace(Y, Z) === Replace(X, Y, Z)

```

### .replaceMatches()

```
X.replaceMatches(Y, Z) === ReplaceMatches(X, Y, Z)

```

### .round()

```
X.round() === Round(X)
X.round(Y) === Round(X, Y)

```

### .secondOf()

```
X.secondOf() === second from X

```

### .select()

If the result type of is not list-valued:

```
X.select(<element>) === X $this let a: <element> where a is not null return a

```

If the result type of is list-valued:

```
X.select(<element>) === Flatten(X $this let a: <element> where a is not null return a)

```

### .single()

```
X.single() === singleton from X

```

### .skip()

```
X.skip(Y) === Slice(X, Y, null)

```

### .split()

```
X.split(separator) === Split(X, separator)

```

### .sqrt()

```
X.sqrt() === Power(X, 0.5)

```

### .startsWith()

```
X.startsWith(Y) === StartsWith(X, Y)

```

### .subsetOf()

```
X.subsetOf(Y) === X included in Y

```

### .substring()

```
X.substring(Y) === SubString(X, Y)

X.substring(Y, Z) === SubString(X, Y, Z)

```

### .subsumes()

```
X.subsumes(Y) === Subsumes(X, Y)

```

### .subsumedBy()

```
X.subsumedBy(Y) === SubsumedBy(X, Y)

```

### .supersetOf()

```
X.supersetOf(Y) === X includes Y

```

### .tail()

```
X.tail() === Slice(X, 1, null)

```

### .take()

```
X.take(Y) === Slice(X, 0, Coalesce(Y, 0))

```

### .timeOf()

```
X.timeOf() === time from X

```

### .timeOfDay()

```
timeOfDay() === TimeOfDay()

```

### .timezoneOffsetOf()

```
X.timezoneOffsetOf() === timezoneoffset from X

```

### .toBoolean()

```
X.toBoolean() === ToBoolean(X)

```

### .toChars()

```
X.toChars() === ToChars(X)

```

### .toDate()

```
X.toDate() === ToDate(X)

```

### .toDateTime()

```
X.toDateTime() === ToDateTime(X)

```

### .today()

```
today() === Today()

```

### .toDecimal()

```
X.toDecimal() === ToDecimal(X)

```

### .toInteger()

```
X.toInteger() === ToInteger(X)

```

### .toQuantity()

```
X.toQuantity() === ToQuantity(X)

```

### .toString()

```
X.toString() === ToString(X)

```

### .toTime()

```
X.toTime() === ToTime(X)

```

### .trace()

```
X.trace(Y) === Message(X, true, Y, 'Trace', ToString(X)))

```

### .trim()

```
X.trim() === Trim(X)

```

### .truncate()

```
X.truncate() === Truncate(X)

```

### .unescape()

```
X.unescape(target) === Unescape(X, target)

```

### .union() and |

```
X.union(Y) === X union Y
X | Y === X union Y

```

### .upper()

```
X.upper() === Upper(X)

```

### .where()

```
X.where(<condition>) === X $this where <condition>

```

### .yearOf()

```
X.yearOf() === year from X

```

