Validate an odin model. This function is closer to odin_parse_ than odin_parse because it does not do any quoting of the code. It is primarily intended for use within other applications.

odin_validate(x, type = NULL, options = NULL)

Arguments

x

An expression, character vector or filename with the odin code

type

An optional string indicating the the type of input - must be one of expression, file or text if provided. This skips the type detection code used by odin and makes validating user input easier.

options

odin options; see odin_options. The primary options that affect the parse stage are validate and pretty.

Details

odin_validate will always return a list with the same elements:

success

A boolean, TRUE if validation was successful

result

The intermediate representation, as returned by odin_parse_, if the validation was successful, otherwise NULL

error

An error object if the validation was unsuccessful, otherwise NULL. This may be a classed odin error, in which case it will contain source location information - see the examples for details.

messages

A list of messages, if the validation returned any. At present this is only non-fatal information about unused variables.

Author

Rich FitzJohn

Examples


# A successful validation:
odin::odin_validate(c("deriv(x) <- 1", "initial(x) <- 1"))
#> $success
#> [1] TRUE
#> 
#> $result
#> {"version":"1.5.10","config":{"base":"odin","include":null,"custom":null},"meta":{"internal":"internal","user":"user","state":"state","result":"dstatedt","output":"output","time":"t","initial_time":"initial_t"},"features":{"continuous":true,"discrete":false,"mixed":false,"has_array":false,"has_output":false,"has_user":false,"has_delay":false,"has_interpolate":false,"has_stochastic":false,"has_data":false,"has_compare":false,"has_include":false,"has_debug":false,"has_derivative":false,"initial_time_dependent":false},"data":{"elements":[{"name":"initial_x","location":"internal","storage_type":"double","rank":0,"dimnames":null,"stage":"constant"},{"name":"x","location":"variable","storage_type":"double","rank":0,"dimnames":null,"stage":"time"}],"variable":{"length":1,"contents":[{"name":"x","offset":0,"initial":"initial_x"}]},"output":{"length":0,"contents":[]}},"equations":[{"name":"deriv_x","type":"expression_scalar","source":[1],"depends":null,"lhs":"x","rhs":{"value":1}},{"name":"initial_x","type":"expression_scalar","source":[2],"depends":null,"lhs":"initial_x","rhs":{"value":1}}],"debug":[],"components":{"create":{"variables":[],"equations":["initial_x"]},"user":{"variables":[],"equations":[]},"initial":{"variables":[],"equations":[]},"rhs":{"variables":[],"equations":["deriv_x"]},"update_stochastic":{"variables":[],"equations":[]},"output":{"variables":[],"equations":[]},"compare":{"variables":[],"equations":[]}},"user":[],"interpolate":{"min":[],"max":[],"critical":[]},"source":["deriv(x) <- 1","initial(x) <- 1"]} 
#> 
#> $error
#> NULL
#> 
#> $messages
#> list()
#> 

# A complete failure:
odin::odin_validate("")
#> $success
#> [1] FALSE
#> 
#> $result
#> NULL
#> 
#> $error
#> <simpleError in odin_preprocess_detect(x, type): '' looks like a filename, but file does not exist>
#> 
#> $messages
#> list()
#> 

# A more interesting failure
code <- c("deriv(x) <- a", "initial(x) <- 1")
res <- odin::odin_validate(code)
res
#> $success
#> [1] FALSE
#> 
#> $result
#> NULL
#> 
#> $error
#> <odin_error: Unknown variable a
#> 	deriv(x) <- a # (line 1)>
#> 
#> $messages
#> list()
#> 

# The object 'res$error' is an 'odin_error' object:
res$error
#> <odin_error: Unknown variable a
#> 	deriv(x) <- a # (line 1)>

# It contains information that might be used to display to a
# user information about the error:
unclass(res$error)
#> $message
#> [1] "Unknown variable a\n\tderiv(x) <- a # (line 1)"
#> 
#> $msg
#> [1] "Unknown variable a"
#> 
#> $line
#> [1] 1
#> 
#> $expr
#> [1] "deriv(x) <- a"
#> 
#> $type
#> [1] "error"
#> 

# Notes are raised in a similar way:
code <- c("deriv(x) <- 1", "initial(x) <- 1", "a <- 1")
res <- odin::odin_validate(code)
res$messages[[1]]
#> $message
#> [1] "Unused equation: a\n\ta <- 1 # (line 3)"
#> 
#> $msg
#> [1] "Unused equation: a"
#> 
#> $line
#> [1] 3
#> 
#> $expr
#> [1] "a <- 1"
#> 
#> $type
#> [1] "message"
#>