Skip to content

Commit 4a1e8d3

Browse files
committed
Support 2-argument form of ArrayQ with depth check
ArrayQ[expr, n] now checks if expr is a rectangular array of depth n. E.g. ArrayQ[{{1,2},{3,4}}, 2] returns True. Previously only the 1-argument form was supported.
1 parent d03feb8 commit 4a1e8d3

3 files changed

Lines changed: 37 additions & 3 deletions

File tree

src/evaluator/dispatch/arg_count.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ pub fn get_arg_count_range(name: &str) -> Option<(usize, usize)> {
6565
"ArrayDepth" => Some((1, 1)),
6666
"ArrayFlatten" => Some((1, 1)),
6767
"ArrayPad" => Some((2, 3)),
68-
"ArrayQ" => Some((1, 1)),
68+
"ArrayQ" => Some((1, 3)),
6969
"ArrayResample" => Some((2, 2)),
7070
"ArrayReshape" => Some((2, 3)),
7171
"ArrayRules" => Some((1, 2)),

src/evaluator/dispatch/list_operations.rs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1458,8 +1458,27 @@ pub fn dispatch_list_operations(
14581458
"TensorRank" if args.len() == 1 => {
14591459
return Some(list_helpers_ast::tensor_rank_ast(&args[0]));
14601460
}
1461-
"ArrayQ" if args.len() == 1 => {
1462-
return Some(list_helpers_ast::array_q_ast(&args[0]));
1461+
"ArrayQ" if !args.is_empty() && args.len() <= 3 => {
1462+
let is_array = match list_helpers_ast::array_q_ast(&args[0]) {
1463+
Ok(v) => v,
1464+
Err(e) => return Some(Err(e)),
1465+
};
1466+
if args.len() >= 2 {
1467+
// ArrayQ[expr, n] - check if expr is an array of depth n
1468+
if matches!(&is_array, Expr::Identifier(s) if s == "True")
1469+
&& let Ok(dims) = list_helpers_ast::dimensions_ast(&[args[0].clone()])
1470+
&& let Expr::List(d) = &dims
1471+
&& let Some(n) = expr_to_i128(&args[1])
1472+
{
1473+
return Some(Ok(if d.len() == n as usize {
1474+
Expr::Identifier("True".to_string())
1475+
} else {
1476+
Expr::Identifier("False".to_string())
1477+
}));
1478+
}
1479+
return Some(Ok(is_array));
1480+
}
1481+
return Some(Ok(is_array));
14631482
}
14641483
"VectorQ" if args.len() == 1 => {
14651484
return Some(list_helpers_ast::vector_q_ast(&args[0]));

tests/interpreter_tests/functions.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -882,6 +882,21 @@ mod array_predicates {
882882
assert_eq!(interpret("ArrayQ[{{1, 2}, {3}}]").unwrap(), "False");
883883
}
884884

885+
#[test]
886+
fn array_q_with_depth() {
887+
assert_eq!(interpret("ArrayQ[{{1, 2}, {3, 4}}, 2]").unwrap(), "True");
888+
}
889+
890+
#[test]
891+
fn array_q_with_wrong_depth() {
892+
assert_eq!(interpret("ArrayQ[{{1, 2}, {3, 4}}, 1]").unwrap(), "False");
893+
}
894+
895+
#[test]
896+
fn array_q_vector_depth_1() {
897+
assert_eq!(interpret("ArrayQ[{1, 2, 3}, 1]").unwrap(), "True");
898+
}
899+
885900
#[test]
886901
fn matrix_q_true() {
887902
assert_eq!(interpret("MatrixQ[{{1, 2}, {3, 4}}]").unwrap(), "True");

0 commit comments

Comments
 (0)