1
use rand::Rng;
2
use rand::prelude::IteratorRandom;
3

            
4
use crate::DataExpr;
5
use crate::DataExprBinaryOp;
6
use crate::IdDecl;
7
use crate::Sort;
8
use crate::SortExpression;
9

            
10
/// Generates a random boolean data expression from the given variable list.
11
2364
pub fn random_boolean_data_expression<R: Rng>(rng: &mut R, variables: &[IdDecl]) -> DataExpr {
12
2364
    let integers: Vec<&IdDecl> = variables
13
2364
        .iter()
14
3028
        .filter(|v| matches!(&v.sort, SortExpression::Simple(s) if matches!(s, Sort::Int | Sort::Nat | Sort::Pos)))
15
2364
        .collect();
16
2364
    let booleans: Vec<&IdDecl> = variables
17
2364
        .iter()
18
3028
        .filter(|v| matches!(&v.sort, SortExpression::Simple(Sort::Bool)))
19
2364
        .collect();
20

            
21
2364
    let mut candidates: Vec<DataExpr> = booleans.iter().map(|v| DataExpr::Id(v.identifier.clone())).collect();
22

            
23
2364
    for m in &integers {
24
977
        let mv = DataExpr::Id(m.identifier.clone());
25
977
        candidates.push(DataExpr::Binary {
26
977
            op: DataExprBinaryOp::GreaterThan,
27
977
            lhs: Box::new(mv.clone()),
28
977
            rhs: Box::new(DataExpr::Number("0".to_string())),
29
977
        });
30
977
        candidates.push(DataExpr::Binary {
31
977
            op: DataExprBinaryOp::GreaterThan,
32
977
            lhs: Box::new(mv.clone()),
33
977
            rhs: Box::new(DataExpr::Number("1".to_string())),
34
977
        });
35
977
        candidates.push(DataExpr::Binary {
36
977
            op: DataExprBinaryOp::LessThan,
37
977
            lhs: Box::new(mv.clone()),
38
977
            rhs: Box::new(DataExpr::Number("2".to_string())),
39
977
        });
40
977
        candidates.push(DataExpr::Binary {
41
977
            op: DataExprBinaryOp::LessThan,
42
977
            lhs: Box::new(mv.clone()),
43
977
            rhs: Box::new(DataExpr::Number("3".to_string())),
44
977
        });
45
1533
        for n in &integers {
46
1533
            candidates.push(DataExpr::Binary {
47
1533
                op: DataExprBinaryOp::Equal,
48
1533
                lhs: Box::new(mv.clone()),
49
1533
                rhs: Box::new(DataExpr::Id(n.identifier.clone())),
50
1533
            });
51
1533
        }
52
    }
53

            
54
2364
    candidates.push(DataExpr::Bool(true));
55
2364
    candidates.push(DataExpr::Bool(false));
56

            
57
2364
    candidates.into_iter().choose(rng).unwrap()
58
2364
}
59

            
60
/// Generates a random integer data expression from the given variable list.
61
327
pub fn random_integer_data_expression<R: Rng>(rng: &mut R, variables: &[IdDecl]) -> DataExpr {
62
327
    let integers: Vec<&IdDecl> = variables
63
327
        .iter()
64
442
        .filter(|v| matches!(&v.sort, SortExpression::Simple(s) if matches!(s, Sort::Int | Sort::Nat | Sort::Pos)))
65
327
        .collect();
66

            
67
327
    let extras = [DataExpr::Number("1".to_string()), DataExpr::Number("2".to_string())];
68
327
    let rhs_operands: Vec<DataExpr> = integers
69
327
        .iter()
70
327
        .map(|v| DataExpr::Id(v.identifier.clone()))
71
327
        .chain(extras)
72
327
        .collect();
73

            
74
327
    let mut candidates: Vec<DataExpr> = integers.iter().map(|v| DataExpr::Id(v.identifier.clone())).collect();
75

            
76
327
    for m in &integers {
77
313
        let mv = DataExpr::Id(m.identifier.clone());
78
1153
        for n in &rhs_operands {
79
1153
            candidates.push(DataExpr::Binary {
80
1153
                op: DataExprBinaryOp::Add,
81
1153
                lhs: Box::new(mv.clone()),
82
1153
                rhs: Box::new(n.clone()),
83
1153
            });
84
1153
            candidates.push(DataExpr::Binary {
85
1153
                op: DataExprBinaryOp::Subtract,
86
1153
                lhs: Box::new(mv.clone()),
87
1153
                rhs: Box::new(n.clone()),
88
1153
            });
89
1153
        }
90
    }
91

            
92
327
    candidates.push(DataExpr::Number("0".to_string()));
93
327
    candidates.push(DataExpr::Number("1".to_string()));
94

            
95
327
    candidates.into_iter().choose(rng).unwrap()
96
327
}