1
use merc_utilities::test_logger;
2
use test_case::test_case;
3

            
4
use merc_aterm::ATerm;
5
use merc_data::DataExpression;
6
use merc_data::to_untyped_data_expression;
7
use merc_rec_tests::load_rec_from_strings;
8
use merc_sabre::InnermostRewriter;
9
use merc_sabre::NaiveRewriter;
10
use merc_sabre::RewriteEngine;
11
use merc_sabre::RewriteSpecification;
12
use merc_sabre::SabreRewriter;
13

            
14
/// A local function to share the rec_test functionality.
15
26
fn rec_test(rec_files: Vec<&str>, expected_result: &str) {
16
26
    test_logger();
17

            
18
26
    let (spec, terms): (RewriteSpecification, Vec<DataExpression>) = {
19
26
        let (syntax_spec, syntax_terms) = load_rec_from_strings(&rec_files).unwrap();
20
26
        let result = syntax_spec.to_rewrite_spec();
21
        (
22
26
            result,
23
26
            syntax_terms
24
26
                .iter()
25
42
                .map(|t| to_untyped_data_expression(t.clone(), None))
26
26
                .collect(),
27
        )
28
    };
29

            
30
    // Test Sabre rewriter
31
26
    let mut sa = SabreRewriter::new(&spec);
32
26
    let mut inner = InnermostRewriter::new(&spec);
33

            
34
26
    let mut expected = expected_result.split('\n');
35

            
36
42
    for term in &terms {
37
42
        let expected_term = ATerm::from_string(expected.next().unwrap()).unwrap();
38
42
        let expected_result = to_untyped_data_expression(expected_term, None);
39

            
40
42
        let result = inner.rewrite(term);
41
42
        assert_eq!(
42
            result,
43
42
            expected_result.clone(),
44
            "The inner rewrite result doesn't match the expected result",
45
        );
46

            
47
42
        let result = sa.rewrite(term);
48
42
        assert_eq!(
49
            result, expected_result,
50
            "The sabre rewrite result doesn't match the expected result"
51
        );
52
    }
53
26
}
54

            
55
#[cfg_attr(miri, ignore)]
56
#[test_case(vec![include_str!("../../../examples/REC/rec/benchexpr10.rec"), include_str!("../../../examples/REC/rec/asfsdfbenchmark.rec")], include_str!("snapshot/result_benchexpr10.txt") ; "benchexpr10")]
57
#[test_case(vec![include_str!("../../../examples/REC/rec/benchsym10.rec"), include_str!("../../../examples/REC/rec/asfsdfbenchmark.rec")], include_str!("snapshot/result_benchsym10.txt") ; "benchsym10")]
58
#[test_case(vec![include_str!("../../../examples/REC/rec/bubblesort10.rec"), include_str!("../../../examples/REC/rec/bubblesort.rec")], include_str!("snapshot/result_bubblesort10.txt") ; "bubblesort10")]
59
#[test_case(vec![include_str!("../../../examples/REC/rec/bubblesort20.rec"), include_str!("../../../examples/REC/rec/bubblesort.rec")], include_str!("snapshot/result_bubblesort20.txt") ; "bubblesort20")]
60
#[test_case(vec![include_str!("../../../examples/REC/rec/calls.rec")], include_str!("snapshot/result_calls.txt") ; "calls")]
61
#[test_case(vec![include_str!("../../../examples/REC/rec/check1.rec")], include_str!("snapshot/result_check1.txt") ; "check1")]
62
#[test_case(vec![include_str!("../../../examples/REC/rec/check2.rec")], include_str!("snapshot/result_check2.txt") ; "check2")]
63
#[test_case(vec![include_str!("../../../examples/REC/rec/confluence.rec")], include_str!("snapshot/result_confluence.txt") ; "confluence")]
64
#[test_case(vec![include_str!("../../../examples/REC/rec/factorial5.rec"), include_str!("../../../examples/REC/rec/factorial.rec")], include_str!("snapshot/result_factorial5.txt") ; "factorial5")]
65
#[test_case(vec![include_str!("../../../examples/REC/rec/fibonacci05.rec"), include_str!("../../../examples/REC/rec/fibonacci.rec")], include_str!("snapshot/result_fibonacci05.txt") ; "fibonacci05")]
66
#[test_case(vec![include_str!("../../../examples/REC/rec/garbagecollection.rec")], include_str!("snapshot/result_garbagecollection.txt") ; "garbagecollection")]
67
#[test_case(vec![include_str!("../../../examples/REC/rec/hanoi4.rec"), include_str!("../../../examples/REC/rec/hanoi.rec")], include_str!("snapshot/result_hanoi4.txt") ; "hanoi4")]
68
#[test_case(vec![include_str!("../../../examples/REC/rec/logic3.rec")], include_str!("snapshot/result_logic3.txt") ; "logic3")]
69
#[test_case(vec![include_str!("../../../examples/REC/rec/merge.rec")], include_str!("snapshot/result_merge.txt") ; "merge")]
70
#[test_case(vec![include_str!("../../../examples/REC/rec/mergesort10.rec"), include_str!("../../../examples/REC/rec/mergesort.rec")], include_str!("snapshot/result_mergesort10.txt") ; "mergesort10")]
71
#[test_case(vec![include_str!("../../../examples/REC/rec/missionaries2.rec"), include_str!("../../../examples/REC/rec/missionaries.rec")], include_str!("snapshot/result_missionaries2.txt") ; "missionaries2")]
72
#[test_case(vec![include_str!("../../../examples/REC/rec/missionaries3.rec"), include_str!("../../../examples/REC/rec/missionaries.rec")], include_str!("snapshot/result_missionaries3.txt") ; "missionaries3")]
73
#[test_case(vec![include_str!("../../../examples/REC/rec/quicksort10.rec"), include_str!("../../../examples/REC/rec/quicksort.rec")], include_str!("snapshot/result_quicksort10.txt") ; "quicksort10")]
74
#[test_case(vec![include_str!("../../../examples/REC/rec/revelt.rec")], include_str!("snapshot/result_revelt.txt") ; "revelt")]
75
#[test_case(vec![include_str!("../../../examples/REC/rec/searchinconditions.rec")], include_str!("snapshot/result_searchinconditions.txt") ; "searchinconditions")]
76
#[test_case(vec![include_str!("../../../examples/REC/rec/sieve20.rec"), include_str!("../../../examples/REC/rec/sieve.rec")], include_str!("snapshot/result_sieve20.txt") ; "sieve20")]
77
#[test_case(vec![include_str!("../../../examples/REC/rec/sieve100.rec"), include_str!("../../../examples/REC/rec/sieve.rec")], include_str!("snapshot/result_sieve100.txt") ; "sieve100")]
78
#[test_case(vec![include_str!("../../../examples/REC/rec/soundnessofparallelengines.rec")], include_str!("snapshot/result_soundnessofparallelengines.txt") ; "soundnessofparallelengines")]
79
#[test_case(vec![include_str!("../../../examples/REC/rec/tak18.rec"), include_str!("../../../examples/REC/rec/tak.rec")], include_str!("snapshot/result_tak18.txt") ; "tak18")]
80
#[test_case(vec![include_str!("../../../examples/REC/rec/tautologyhard.rec")], include_str!("snapshot/result_tautologyhard.txt") ; "tautologyhard")]
81
#[test_case(vec![include_str!("../../../examples/REC/rec/tricky.rec")], include_str!("snapshot/result_tricky.txt") ; "tricky")]
82
26
fn test_rec_specification(rec_files: Vec<&str>, expected_result: &str) {
83
26
    rec_test(rec_files, expected_result);
84
26
}
85

            
86
#[cfg_attr(miri, ignore)]
87
#[test_case(vec![include_str!("../../../examples/REC/rec/check1.rec")], include_str!("snapshot/result_check1.txt") ; "check1")]
88
#[test_case(vec![include_str!("../../../examples/REC/rec/check2.rec")], include_str!("snapshot/result_check2.txt") ; "check2")]
89
#[test_case(vec![include_str!("../../../examples/REC/rec/logic3.rec")], include_str!("snapshot/result_logic3.txt") ; "logic3")]
90
#[test_case(vec![include_str!("../../../examples/REC/rec/searchinconditions.rec")], include_str!("snapshot/result_searchinconditions.txt") ; "searchinconditions")]
91
#[test_case(vec![include_str!("../../../examples/REC/rec/tautologyhard.rec")], include_str!("snapshot/result_tautologyhard.txt") ; "tautologyhard")]
92
5
fn test_rec_specification_naive(rec_files: Vec<&str>, expected_result: &str) {
93
5
    test_logger();
94

            
95
5
    let (spec, terms): (RewriteSpecification, Vec<DataExpression>) = {
96
5
        let (syntax_spec, syntax_terms) = load_rec_from_strings(&rec_files).unwrap();
97
5
        let result = syntax_spec.to_rewrite_spec();
98
        (
99
5
            result,
100
5
            syntax_terms
101
5
                .iter()
102
7
                .map(|t| to_untyped_data_expression(t.clone(), None))
103
5
                .collect(),
104
        )
105
    };
106

            
107
    // Test Sabre rewriter
108
5
    let mut naive = NaiveRewriter::new(&spec);
109

            
110
5
    let mut expected = expected_result.split('\n');
111

            
112
7
    for term in &terms {
113
7
        let expected_term = ATerm::from_string(expected.next().unwrap()).unwrap();
114
7
        let expected_result = to_untyped_data_expression(expected_term, None);
115

            
116
7
        let result = naive.rewrite(term);
117
7
        assert_eq!(
118
            result,
119
7
            expected_result.clone(),
120
            "The naive rewrite result doesn't match the expected result",
121
        );
122
    }
123
5
}
124

            
125
// These tests are too slow without optimisations.
126
#[cfg_attr(miri, ignore)]
127
#[cfg(not(debug_assertions))]
128
#[test_case(vec![include_str!("../../../examples/REC/rec/benchexpr20.rec"), include_str!("../../../examples/REC/rec/asfsdfbenchmark.rec")], include_str!("snapshot/result_benchexpr20.txt") ; "benchexpr20")]
129
#[test_case(vec![include_str!("../../../examples/REC/rec/benchsym20.rec"), include_str!("../../../examples/REC/rec/asfsdfbenchmark.rec")], include_str!("snapshot/result_benchsym20.txt") ; "benchsym20")]
130
#[test_case(vec![include_str!("../../../examples/REC/rec/bubblesort100.rec"), include_str!("../../../examples/REC/rec/bubblesort.rec")], include_str!("snapshot/result_bubblesort100.txt") ; "bubblesort100")]
131
#[test_case(vec![include_str!("../../../examples/REC/rec/empty.rec")], include_str!("snapshot/result_empty.txt") ; "empty")]
132
#[test_case(vec![include_str!("../../../examples/REC/rec/evalexpr.rec")], include_str!("snapshot/result_evalexpr.txt") ; "evalexpr")]
133
#[test_case(vec![include_str!("../../../examples/REC/rec/evaltree.rec")], include_str!("snapshot/result_evaltree.txt") ; "evaltree")]
134
#[test_case(vec![include_str!("../../../examples/REC/rec/factorial6.rec"), include_str!("../../../examples/REC/rec/factorial.rec")], include_str!("snapshot/result_factorial6.txt") ; "factorial6")]
135
#[test_case(vec![include_str!("../../../examples/REC/rec/hanoi8.rec"), include_str!("../../../examples/REC/rec/hanoi.rec")], include_str!("snapshot/result_hanoi8.txt") ; "hanoi8")]
136
#[test_case(vec![include_str!("../../../examples/REC/rec/natlist.rec")], include_str!("snapshot/result_natlist.txt") ; "natlist")]
137
#[test_case(vec![include_str!("../../../examples/REC/rec/oddeven.rec")], include_str!("snapshot/result_oddeven.txt") ; "oddeven")]
138
#[test_case(vec![include_str!("../../../examples/REC/rec/order.rec")], include_str!("snapshot/result_order.txt") ; "order")]
139
#[test_case(vec![include_str!("../../../examples/REC/rec/permutations6.rec"), include_str!("../../../examples/REC/rec/permutations.rec")], include_str!("snapshot/result_permutations6.txt") ; "permutations6")]
140
#[test_case(vec![include_str!("../../../examples/REC/rec/revnat100.rec"), include_str!("../../../examples/REC/rec/revnat.rec")], include_str!("snapshot/result_revnat100.txt") ; "revnat100")]
141
fn test_rec_specification_release(rec_files: Vec<&str>, expected_result: &str) {
142
    rec_test(rec_files, expected_result);
143
}
144

            
145
// These tests use more stack memory than is available on Windows.
146
#[cfg_attr(miri, ignore)]
147
#[cfg(all(unix, not(debug_assertions)))]
148
#[ignore]
149
#[test_case(vec![include_str!("../../../examples/REC/rec/sieve1000.rec"), include_str!("../../../examples/REC/rec/sieve.rec")], include_str!("snapshot/result_sieve1000.txt") ; "sieve1000")]
150
#[test_case(vec![include_str!("../../../examples/REC/rec/revnat1000.rec"), include_str!("../../../examples/REC/rec/revnat.rec")], include_str!("snapshot/result_revnat1000.txt") ; "revnat1000")]
151
#[test_case(vec![include_str!("../../../examples/REC/rec/closure.rec")], include_str!("snapshot/result_closure.txt") ; "closure")]
152
#[test_case(vec![include_str!("../../../examples/REC/rec/dart.rec")], include_str!("snapshot/result_dart.txt") ; "dart")]
153
#[test_case(vec![include_str!("../../../examples/REC/rec/factorial7.rec"), include_str!("../../../examples/REC/rec/factorial.rec")], include_str!("snapshot/result_factorial7.txt") ; "factorial7")]
154
#[test_case(vec![include_str!("../../../examples/REC/rec/factorial8.rec"), include_str!("../../../examples/REC/rec/factorial.rec")], include_str!("snapshot/result_factorial8.txt") ; "factorial8")]
155
// #[test_case(vec![include_str!("../../../examples/REC/rec/factorial9.rec"), include_str!("../../../examples/REC/rec/factorial.rec")], include_str!("snapshot/result_factorial9.txt") ; "factorial9")]
156
#[test_case(vec![include_str!("../../../examples/REC/rec/fibonacci18.rec"), include_str!("../../../examples/REC/rec/fibonacci.rec")], include_str!("snapshot/result_fibonacci18.txt") ; "fibonacci18")]
157
#[test_case(vec![include_str!("../../../examples/REC/rec/fibonacci19.rec"), include_str!("../../../examples/REC/rec/fibonacci.rec")], include_str!("snapshot/result_fibonacci19.txt") ; "fibonacci19")]
158
#[test_case(vec![include_str!("../../../examples/REC/rec/fibonacci20.rec"), include_str!("../../../examples/REC/rec/fibonacci.rec")], include_str!("snapshot/result_fibonacci20.txt") ; "fibonacci20")]
159
#[test_case(vec![include_str!("../../../examples/REC/rec/fibonacci21.rec"), include_str!("../../../examples/REC/rec/fibonacci.rec")], include_str!("snapshot/result_fibonacci21.txt") ; "fibonacci21")]
160
#[test_case(vec![include_str!("../../../examples/REC/rec/hanoi12.rec"), include_str!("../../../examples/REC/rec/hanoi.rec")], include_str!("snapshot/result_hanoi12.txt") ; "hanoi12")]
161
#[test_case(vec![include_str!("../../../examples/REC/rec/permutations7.rec"), include_str!("../../../examples/REC/rec/permutations.rec")], include_str!("snapshot/result_permutations7.txt") ; "permutations7")]
162
fn test_rec_specification_largestack(rec_files: Vec<&str>, expected_result: &str) {
163
    rec_test(rec_files, expected_result);
164
}
165

            
166
// // These REC tests have META data that is not supported by the current implementation.
167
// #[test_case(vec![include_str!("../../../examples/REC/rec/add8.rec")], include_str!("snapshot/result_add8.txt") ; "add8")]
168
// #[test_case(vec![include_str!("../../../examples/REC/rec/add16.rec")], include_str!("snapshot/result_add16.txt") ; "add16")]
169
// #[test_case(vec![include_str!("../../../examples/REC/rec/add32.rec")], include_str!("snapshot/result_add32.txt") ; "add32")]
170
// #[test_case(vec![include_str!("../../../examples/REC/rec/mul8.rec")], include_str!("snapshot/result_mul8.txt") ; "mul8")]
171
// #[test_case(vec![include_str!("../../../examples/REC/rec/mul16.rec")], include_str!("snapshot/result_mul16.txt") ; "mul16")]
172
// #[test_case(vec![include_str!("../../../examples/REC/rec/mul32.rec")], include_str!("snapshot/result_mul32.txt") ; "mul32")]
173
// #[test_case(vec![include_str!("../../../examples/REC/rec/omul8.rec")], include_str!("snapshot/result_omul8.txt") ; "omul8")]
174
// #[test_case(vec![include_str!("../../../examples/REC/rec/omul32.rec")], include_str!("snapshot/result_omul32.txt") ; "omul32")]
175
// #[test_case(vec![include_str!("../../../examples/REC/rec/intnat.rec")], include_str!("snapshot/result_intnat.txt") ; "intnat")]