See the documentation for the target language syntax and semantics.
The shape analyzer determines which paths are "shape-safe", and the value analyzer checks if each path can indeed yield the provided output value. The shape analysis uses a non-deterministic Damas-Milner type inference, since the target language is not statically typed. The value analysis utilizes the Z3 theorem prover to prune branches as early as possible, as well as to unify with the output value.
To run, execute
./_build/default/bin/main.exe -all test.l
after dune build
.
When the flag -all
is omitted, only shape analysis is done.
# lang 1
# (0, 0) 1
# (1, 1) 0
let h []
let a h.1
let b h.2
if (a + b)
if (a + b) (a + a + 1) b
if (a + b) b (a + a + 1)
should output
Shape & value analyzer. tests/test_7.l (L1)
Sample: ((0, 0), 1)
[let x = [([0 : β3], [0 : β4]) : β2] in [let h = [[] : β6] in [let a = [[h : β9].1 : β8] in [let b = [[h : β12].2 : β11] in [if [[a : β15] + [b : β16] : β14] [if [[a : β19] + [b : β20] : β18] [[[a : β23] + [a : β24] : β22] + [1 : β25] : β21] [b : β26] : β17] [if [[a : β29] + [b : β30] : β28] [b : β31] [[[a : β34] + [a : β35] : β33] + [1 : β36] : β32] : β27] : β13] : β10] : β7] : β5] : β1]
| []: (ΞΉ, ΞΉ), O: ΞΉ, Trace: let . = (.) in (let . = (.) in (let . = (.) in (if (. + .) β 0 if (. + .) β 0 . + . + .))); β1-β2-β3-β4-β5-β6-β7-β8-β9-β10-β11-β12-β13-β14-β15-β16-β17-β18-β19-β20-β21-β22-β23-β24-β25
| Eval: 1 + 2[2]
[let x = [([0 : β3], [0 : β4]) : β2] in [let h = [[] : β6] in [let a = [[h : β9].1 : β8] in [let b = [[h : β12].2 : β11] in [if [[a : β15] + [b : β16] : β14] [if [[a : β19] + [b : β20] : β18] [[[a : β23] + [a : β24] : β22] + [1 : β25] : β21] [b : β26] : β17] [if [[a : β29] + [b : β30] : β28] [b : β31] [[[a : β34] + [a : β35] : β33] + [1 : β36] : β32] : β27] : β13] : β10] : β7] : β5] : β1]
| []: (ΞΉ, ΞΉ), O: ΞΉ, Trace: let . = (.) in (let . = (.) in (let . = (.) in (if (. + .) β 0 if (. + .) = 0 .))); β1-β2-β3-β4-β5-β6-β7-β8-β9-β10-β11-β12-β13-β14-β15-β16-β17-β18-β19-β20-β26
| Falsy value found when guide_path expected a truthy value
[let x = [([0 : β3], [0 : β4]) : β2] in [let h = [[] : β6] in [let a = [[h : β9].1 : β8] in [let b = [[h : β12].2 : β11] in [if [[a : β15] + [b : β16] : β14] [if [[a : β19] + [b : β20] : β18] [[[a : β23] + [a : β24] : β22] + [1 : β25] : β21] [b : β26] : β17] [if [[a : β29] + [b : β30] : β28] [b : β31] [[[a : β34] + [a : β35] : β33] + [1 : β36] : β32] : β27] : β13] : β10] : β7] : β5] : β1]
| []: (ΞΉ, ΞΉ), O: ΞΉ, Trace: let . = (.) in (let . = (.) in (let . = (.) in (if (. + .) = 0 if (. + .) β 0 .))); β1-β2-β3-β4-β5-β6-β7-β8-β9-β10-β11-β12-β13-β14-β15-β16-β27-β28-β29-β30-β31
| Falsy value found when guide_path expected a truthy value
[let x = [([0 : β3], [0 : β4]) : β2] in [let h = [[] : β6] in [let a = [[h : β9].1 : β8] in [let b = [[h : β12].2 : β11] in [if [[a : β15] + [b : β16] : β14] [if [[a : β19] + [b : β20] : β18] [[[a : β23] + [a : β24] : β22] + [1 : β25] : β21] [b : β26] : β17] [if [[a : β29] + [b : β30] : β28] [b : β31] [[[a : β34] + [a : β35] : β33] + [1 : β36] : β32] : β27] : β13] : β10] : β7] : β5] : β1]
| []: (ΞΉ, ΞΉ), O: ΞΉ, Trace: let . = (.) in (let . = (.) in (let . = (.) in (if (. + .) = 0 if (. + .) = 0 . + . + .))); β1-β2-β3-β4-β5-β6-β7-β8-β9-β10-β11-β12-β13-β14-β15-β16-β27-β28-β29-β30-β32-β33-β34-β35-β36
| Eval: 1 + 2[2]
Sample: ((1, 1), 0)
[let x = [([1 : β3], [1 : β4]) : β2] in [let h = [[] : β6] in [let a = [[h : β9].1 : β8] in [let b = [[h : β12].2 : β11] in [if [[a : β15] + [b : β16] : β14] [if [[a : β19] + [b : β20] : β18] [[[a : β23] + [a : β24] : β22] + [1 : β25] : β21] [b : β26] : β17] [if [[a : β29] + [b : β30] : β28] [b : β31] [[[a : β34] + [a : β35] : β33] + [1 : β36] : β32] : β27] : β13] : β10] : β7] : β5] : β1]
| []: (ΞΉ, ΞΉ), O: ΞΉ, Trace: let . = (.) in (let . = (.) in (let . = (.) in (if (. + .) β 0 if (. + .) β 0 . + . + .))); β1-β2-β3-β4-β5-β6-β7-β8-β9-β10-β11-β12-β13-β14-β15-β16-β17-β18-β19-β20-β21-β22-β23-β24-β25
| Eval: 1 + 2[2] failed to unify with the output
[let x = [([1 : β3], [1 : β4]) : β2] in [let h = [[] : β6] in [let a = [[h : β9].1 : β8] in [let b = [[h : β12].2 : β11] in [if [[a : β15] + [b : β16] : β14] [if [[a : β19] + [b : β20] : β18] [[[a : β23] + [a : β24] : β22] + [1 : β25] : β21] [b : β26] : β17] [if [[a : β29] + [b : β30] : β28] [b : β31] [[[a : β34] + [a : β35] : β33] + [1 : β36] : β32] : β27] : β13] : β10] : β7] : β5] : β1]
| []: (ΞΉ, ΞΉ), O: ΞΉ, Trace: let . = (.) in (let . = (.) in (let . = (.) in (if (. + .) β 0 if (. + .) = 0 .))); β1-β2-β3-β4-β5-β6-β7-β8-β9-β10-β11-β12-β13-β14-β15-β16-β17-β18-β19-β20-β26
| Falsy value found when guide_path expected a truthy value
[let x = [([1 : β3], [1 : β4]) : β2] in [let h = [[] : β6] in [let a = [[h : β9].1 : β8] in [let b = [[h : β12].2 : β11] in [if [[a : β15] + [b : β16] : β14] [if [[a : β19] + [b : β20] : β18] [[[a : β23] + [a : β24] : β22] + [1 : β25] : β21] [b : β26] : β17] [if [[a : β29] + [b : β30] : β28] [b : β31] [[[a : β34] + [a : β35] : β33] + [1 : β36] : β32] : β27] : β13] : β10] : β7] : β5] : β1]
| []: (ΞΉ, ΞΉ), O: ΞΉ, Trace: let . = (.) in (let . = (.) in (let . = (.) in (if (. + .) = 0 if (. + .) β 0 .))); β1-β2-β3-β4-β5-β6-β7-β8-β9-β10-β11-β12-β13-β14-β15-β16-β27-β28-β29-β30-β31
| Falsy value found when guide_path expected a truthy value
[let x = [([1 : β3], [1 : β4]) : β2] in [let h = [[] : β6] in [let a = [[h : β9].1 : β8] in [let b = [[h : β12].2 : β11] in [if [[a : β15] + [b : β16] : β14] [if [[a : β19] + [b : β20] : β18] [[[a : β23] + [a : β24] : β22] + [1 : β25] : β21] [b : β26] : β17] [if [[a : β29] + [b : β30] : β28] [b : β31] [[[a : β34] + [a : β35] : β33] + [1 : β36] : β32] : β27] : β13] : β10] : β7] : β5] : β1]
| []: (ΞΉ, ΞΉ), O: ΞΉ, Trace: let . = (.) in (let . = (.) in (let . = (.) in (if (. + .) = 0 if (. + .) = 0 . + . + .))); β1-β2-β3-β4-β5-β6-β7-β8-β9-β10-β11-β12-β13-β14-β15-β16-β27-β28-β29-β30-β32-β33-β34-β35-β36
| Eval: 1 + 2[2] failed to unify with the output