//  ISOBSERVABLE  Test for observability.
//  returns 1 if the system is observable, 0 otherwise.
// 定义函数：判断系统是否可观测

fn isobservable(H, pv, pq) {
    // 默认容差
    tol = 1e-5;
    // 是否检查不可观测的原因（0不检查，1检查。由于不支持字符串赋值自变量，故暂不支持检查。）
    check_reason = 0;

    // 获取H矩阵的行列数
    m = size(H, 0);
    n = size(H, 1);

    // 计算H矩阵的秩
    r = rank(H);

    // 判断是否满秩（满秩则可观测）
    if r < min(m, n) {
        TorF = 0;
    } else {
        TorF = 1;
    }

    /*// 如果需要检查不可观测的原因且系统不可观测
    if check_reason && !TorF {
        // 存储零列索引和对应的变量名
        idx_trivialColumns = [];
        varNames = [];

        // 遍历每一列检查是否为零列
        for j in 0..n {
            // 计算列的无穷范数
            col_j = slice(H, [0], j);
            normJ = norm_max(col_j);

            if normJ < tol {
                // 记录零列索引（转换为1基显示）
                idx_trivialColumns = horzcat(idx_trivialColumns, [j + 1]);
                // 获取变量名
                varName = getVarName(j, pv, pq);
                varNames = horzcat(varNames, [varName]);
            }
        }

        // 如果存在零列（变量未被任何测量关联）
        if ~~is_empty(idx_trivialColumns) {
            println("Warning: The following variables are not observable since they are not related with any measurement!");
            println("Variables:");
            println(varNames);
            println("Indices (1-based):");
            println(idx_trivialColumns);
        } else {
            // 检查是否存在线性相关的列
            for j in 0..n {
                // 计算前j+1列的秩（因为RustScript是0基，j从0开始）
                subH = slice(H, [0], [0, j+1]);
                rr = rank(subH);

                // 如果秩小于列数，说明存在线性相关
                if rr < (j + 1) {
                    // 获取当前列
                    colJ = slice(H, [0], j);
                    varJName = getVarName(j, pv, pq);

                    // 检查当前列与前面所有列的线性相关性
                    for k in 0..j {
                        colK = slice(H, [0], k);
                        // 合并两列计算秩
                        combined = horzcat(colK, colJ);
                        if rank(combined) < 2 {
                            varKName = getVarName(k, pv, pq);
                            println("Warning: {}(th) column vector (w.r.t. {}) of H is linearly dependent of {}(th) column vector (w.r.t. {})!",
                                j+1, varJName, k+1, varKName);
                            return TorF;
                        }
                    }
                }
            }
            println("Warning: No specific reason was found for system being not observable.");
        }
    }
    */

    return TorF;
}