Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 26 additions & 3 deletions src/frontend/Semantic_check.ml
Original file line number Diff line number Diff line change
Expand Up @@ -290,9 +290,32 @@ let semantic_check_fn_normal ~is_cond_dist ~loc id es =
| Some _ ->
(* Check that Funaps are actually functions *)
Semantic_error.returning_fn_expected_nonfn_found loc id.name |> error
| None ->
Semantic_error.returning_fn_expected_undeclaredident_found loc id.name
|> error)
| None -> (
match List.rev (String.split id.name ~on:'_') with
| suffix :: tl
when List.mem Utils.cumulative_distribution_suffices_w_rng suffix
~equal:String.equal ->
let prefix = String.concat ~sep:"_" (List.rev tl) in
let known_families =
List.map
~f:(fun (_, y, _, _) -> y)
Stan_math_signatures.distributions
in
let is_known_family s =
List.mem known_families s ~equal:String.equal
in
if is_known_family prefix then
Semantic_error.returning_fn_expected_undeclared_dist_suffix_found
loc (prefix, suffix)
|> error
else
Semantic_error.returning_fn_expected_undeclaredident_found loc
id.name
|> error
| _ ->
Semantic_error.returning_fn_expected_undeclaredident_found loc
id.name
|> error ))

(* Stan-Math function application *)
let semantic_check_fn_stan_math ~is_cond_dist ~loc id es =
Expand Down
14 changes: 14 additions & 0 deletions src/middle/Semantic_error.ml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ module TypeError = struct
| ReturningFnExpectedNonReturningFound of string
| ReturningFnExpectedNonFnFound of string
| ReturningFnExpectedUndeclaredIdentFound of string
| ReturningFnExpectedUndeclaredDistSuffixFound of string * string
| NonReturningFnExpectedReturningFound of string
| NonReturningFnExpectedNonFnFound of string
| NonReturningFnExpectedUndeclaredIdentFound of string
Expand Down Expand Up @@ -168,6 +169,13 @@ module TypeError = struct
"A returning function was expected but an undeclared identifier \
'%s' was supplied."
fn_name
| ReturningFnExpectedUndeclaredDistSuffixFound (prefix, suffix) ->
Fmt.pf ppf
"A function was expected but an unknown identifier %s was recieved. \
This appears to be part of the %s family of distributions, for \
which the %s suffix in not implemented."
(String.concat ~sep:"_" [prefix; suffix])
prefix suffix
| NonReturningFnExpectedUndeclaredIdentFound fn_name ->
Fmt.pf ppf
"A non-returning function was expected but an undeclared identifier \
Expand Down Expand Up @@ -496,6 +504,12 @@ let returning_fn_expected_nonfn_found loc name =
let returning_fn_expected_undeclaredident_found loc name =
TypeError (loc, TypeError.ReturningFnExpectedUndeclaredIdentFound name)

let returning_fn_expected_undeclared_dist_suffix_found loc (prefix, suffix) =
TypeError
( loc
, TypeError.ReturningFnExpectedUndeclaredDistSuffixFound (prefix, suffix)
)

let nonreturning_fn_expected_returning_found loc name =
TypeError (loc, TypeError.NonReturningFnExpectedReturningFound name)

Expand Down
3 changes: 3 additions & 0 deletions src/middle/Semantic_error.mli
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ val returning_fn_expected_nonfn_found : Location_span.t -> string -> t
val returning_fn_expected_undeclaredident_found :
Location_span.t -> string -> t

val returning_fn_expected_undeclared_dist_suffix_found :
Location_span.t -> string * string -> t

val illtyped_reduce_sum :
Location_span.t
-> string
Expand Down
5 changes: 5 additions & 0 deletions src/middle/Utils.ml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ let conditioning_suffices =
["_lpdf"; "_lupdf"; "_lupmf"; "_lpmf"; "_cdf"; "_lcdf"; "_lccdf"]

let conditioning_suffices_w_log = conditioning_suffices @ ["_log"]
let cumulative_distribution_suffices = ["cdf"; "lcdf"; "lccdf"]

let cumulative_distribution_suffices_w_rng =
cumulative_distribution_suffices @ ["rng"]

let is_user_ident = Fn.non (String.is_suffix ~suffix:"__")

let unnormalized_suffix = function
Expand Down
1 change: 1 addition & 0 deletions test/integration/bad/missing_dist_suffix/dune
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
(include ../dune)
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
data {
}
model {
target += von_mises_cdf(1|0,1);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
data {
}
model {
target += von_mises_lcdf(1|0,1);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
data {
}
model {
target += von_mises_lccdf(1|0,1);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
data {
}
model {
target += von_mises_notasuffix(1|0,1);
}
44 changes: 44 additions & 0 deletions test/integration/bad/missing_dist_suffix/stanc.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
$ ../../../../../install/default/bin/stanc non_existing_distribution_suffix1.stan
Semantic error in 'non_existing_distribution_suffix1.stan', line 4, column 14 to column 34:
-------------------------------------------------
2: }
3: model {
4: target += von_mises_cdf(1|0,1);
^
5: }
-------------------------------------------------

A function was expected but an unknown identifier von_mises_cdf was recieved. This appears to be part of the von_mises family of distributions, for which the cdf suffix in not implemented.
$ ../../../../../install/default/bin/stanc non_existing_distribution_suffix2.stan
Semantic error in 'non_existing_distribution_suffix2.stan', line 4, column 14 to column 35:
-------------------------------------------------
2: }
3: model {
4: target += von_mises_lcdf(1|0,1);
^
5: }
-------------------------------------------------

A function was expected but an unknown identifier von_mises_lcdf was recieved. This appears to be part of the von_mises family of distributions, for which the lcdf suffix in not implemented.
$ ../../../../../install/default/bin/stanc non_existing_distribution_suffix3.stan
Semantic error in 'non_existing_distribution_suffix3.stan', line 4, column 14 to column 36:
-------------------------------------------------
2: }
3: model {
4: target += von_mises_lccdf(1|0,1);
^
5: }
-------------------------------------------------

A function was expected but an unknown identifier von_mises_lccdf was recieved. This appears to be part of the von_mises family of distributions, for which the lccdf suffix in not implemented.
$ ../../../../../install/default/bin/stanc non_existing_distribution_suffix4.stan
Semantic error in 'non_existing_distribution_suffix4.stan', line 4, column 14 to column 41:
-------------------------------------------------
2: }
3: model {
4: target += von_mises_notasuffix(1|0,1);
^
5: }
-------------------------------------------------

Only functions with names ending in _lpdf, _lupdf, _lpmf, _lupmf, _cdf, _lcdf, _lccdf can make use of conditional notation.