《专家系统破解篇 五、IL代码破解》之 FeatherskyExpertSystem

首先提一下。 FeatherskyExpertSystem.DLL是网络上一个不知名的程序。我是用来学习借鉴。所以把它从IL 修改成C#版。然后搞明白方法后,自己又开发自己的版本的。

而且此推理程序1.不是基于数据库,2.前提条件只能2个,结论只能1个。3.多数操作都是在定长的数组中。

并不能解决我要的问题。 不过其借鉴意义和我的搭建和实现思路指导意义功不可没。

连续两天解读,已经搞定。这里发上来,给大家借鉴一下。

原作者如果有意见,请联系我。

在此输入图片描述

下面的代码是最初理解的时候做的注释,不一定正确,新的在我的工作项目中。不再整理了。大家凑活看吧。

规则库实例: if 市电中断 ^ 停电 then 检查市电;

if 市电正常 then ~ 检查市电;

if 逆变器不工作 then 检测电池电压;

if 停电 ^ 逆变器不工作 then 红色指示灯长亮;

if 电源变压器噪声大 then 市电正常;

if 市电正常 ^ 电源变压器噪声大 then 负载过重;

if 负载过重 then 检查变压器的次级并未发现碰线短路、匝间短路、元器件损坏故障;

这里只是把规则库加载部分的代码贴上来, 推理的模块有点长,影响页面美观

<!-- lang: c# -->
   public class ExpertSystem
{

    //字段   a,b,c,d,e,f,g,h,i.
    public List<string> ET_ap = new List<string>();
    public SortedList<string, int> ET_bp = new SortedList<string, int>();

    private int ET_cp;//ET_cp 计数, 当前(规则切割得到)关键字索引 走到的位置。
    private string[] ET_dp;//当前(规则切割得到)关键字 数组。 存放if,~,then,A1等全部字符。

    private d ET_ep = new d();//D类的对象

    private string ET_fp;//分析后的关键字字符串 ---当前
    private string ET_gp;//分析前(规则切割得到)的字符串 ---当前

    //通过ET_cp计数 与 ET_fp ET_gp 做多个方法的共同参数的使用。

    private List<int> ET_hp = new List<int>();//Hp  存入 关键字的在AP的位置。  AP中是关键字,通过BP【‘关键字’】也可以定位到AP中的索引。
    private List<int> ET_ip = new List<int>();//IP  存入对应关键字是否反义。   与Hp 是一一对应的关系。


    #region 定义函数

    /// <summary>
    /// 通过此方法,对end之前的 规则的全部切割字符进行判断 ,非if的关键字,纳入分析。 这样每个关键字都分析到。
    /// </summary>
    public void ET_af()
    {
        int i = 0;
        while (true)//循环全部规则字符。
        {
            i++;
            if (!(this.ET_fp == "if"))
            {

                break;
            }
            else
            {
                this.ET_cf();//非IF 纳入分析。
            }
        }
    }

    /// <summary>
    /// 关键字 与在 DP数组中的位置 存入 BP数组(关键字(条件与结论 非~  关键字:索引)与 AP数组(条件与结论 关键字))。
    /// 形式BP【‘冬天’:8】 AP 【‘冬天’】
    /// 存入,返回 在数组中的索引位置。
    /// 返回8-1。 因为从0开始。 得到真正的 关键字对应BP与AP的索引。
    /// </summary>
    /// <param name="A_0"></param>
    /// <returns></returns>
    private int ET_af(string A_0)
    {

        if (this.ET_bp.ContainsKey(A_0))
        {
            return this.ET_bp[A_0];
        }
        else
        {
            this.ET_bp.Add(A_0, this.ET_ap.Count);
            this.ET_ap.Add(A_0);
            return (this.ET_ap.Count - 1);
        }
    }

    /// <summary>
    /// 非~关键字,执行af ~关键字执行 下一个的af,然后都指向 下一个
    /// 主要是对关键字做this.ET_af(this.ET_gp);调用
    /// </summary>
    /// <param name="A_0"></param>
    /// <param name="A_1"></param>
    public void ET_af(ref int A_0, ref int A_1)
    {
        A_1 = 1;
        int num = 0;
    Label_0002:
        switch (num)
        {
            case 0:
                if (!(this.ET_fp == "~"))
                {
                    A_0 = this.ET_af(this.ET_gp);
                    this.ET_ef();
                    break;
                }
                else
                {
                    num = 1;
                }
                goto Label_0002;

            case 1:
                A_1 = -1;
                this.ET_ef();
                num = 2;
                goto Label_0002;

            case 2:
                A_0 = this.ET_af(this.ET_gp);
                this.ET_ef();
                break;
        }

    }

    /// <summary>
    /// 只执行一次,做规则加载时。 启动规则分析。
    /// </summary>
    public void ET_bf()
    {
        this.ET_ef();//ET_ef()对索引进行走动。
        this.ET_af();//启动 规则关键字分析。 此方法,自动对完成全部索引的分析循环。
    }


    /// <summary>
    /// 对每个关键字都进行循环时调用。 每次都是非IF关键字调用此。
    /// </summary>
    public void ET_cf()
    {

        this.ET_hp.Clear();
        this.ET_ip.Clear();
        this.ET_ef();//站到if关键字 去非if关键字, 索引已经++了。 得到下一条。
        this.ET_df();//做关键字存入与^与下一个关键字存入(调用存入方法)
        this.ET_ef();//下一个。
        int num = 0;
        int num2 = 0;
        this.ET_af(ref num, ref num2);
        this.ET_ef();
        this.ET_ep.d_af(this.ET_hp, this.ET_ip, num, num2);
    }

    /// <summary>
    /// 可以对非^符号关键字
    ///       把所有的非if的关键字存入到 BP与AP中,利用HP与IP记录是否反义与AP中的位置。
    /// ^符号关键字,存入到之后, 再走一步,对下一个关键字进行存入。
    /// </summary>
    public void ET_df()
    {
        int num = 0;
        int num2 = 0;
        this.ET_af(ref num, ref num2);
        this.ET_hp.Add(num);
        this.ET_ip.Add(num2);
        int num3 = 3;
    Label_0002:
        switch (num3)
        {
            case 0:
                if (this.ET_fp == "^")
                {
                    this.ET_ef();
                    this.ET_af(ref num, ref num2);
                    this.ET_hp.Add(num);
                    this.ET_ip.Add(num2);
                    num3 = 1;
                }
                else
                {
                    num3 = 2;
                }
                goto Label_0002;

            case 1:
            case 3:
                num3 = 0;
                goto Label_0002;

            case 2:
                return;
        }
    }

    public void ET_ef()
    {

        if (this.ET_dp[this.ET_cp] != null)
        {
            this.ET_fp = f.f_af(this.ET_dp[this.ET_cp]);
            this.ET_gp = this.ET_dp[this.ET_cp];
            this.ET_cp++;
            return;
        }
        else
        {
            return;
        }

    }

    #endregion  /// <summary>
    /// 导入规则库
    /// </summary>
    /// <param name="file"></param>
    public void LoadRule(string file)
    {
        string str = "";
        StreamReader reader = new StreamReader(file, Encoding.Default);
        string[] strArray = null;
        string str2 = string.Empty;
        char[] chArray = new char[]{' '};
        string[] strArray2 = null;
        int num = 0;
        int num2 = 0;
        int num3 = 6;

    Label_0002:
        switch (num3)
        {
            case 0:
                if (num < strArray2.Length)
                {
                    str2 = strArray2[num];
                    num3 = 2;
                }
                else
                {
                    num3 = 8;
                }
                goto Label_0002;

            case 1:
                this.ET_dp[this.ET_cp++] = str2;
                num3 = 4;
                goto Label_0002;

            case 2:
                if (str2.Length <= 0)
                {
                    num++;
                    num3 = 5;
                }
                else
                {
                    num3 = 1;

                }
                goto Label_0002;

            case 3:
            case 5:
                num3 = 0;
                goto Label_0002;
            case 4:
                num++;
                num3 = 5;
                goto Label_0002;
            case 6:
                try
                {
                    str = reader.ReadToEnd();
                    reader.Close();
                    //strArray = str.Replace("\r\n", " ").Replace("^~", " ~ ").Replace("^", " ^ ").Replace("if", " if ").Replace("then", " then ").Replace(";", " ; ").Split(chArray);
                    strArray = str.Replace("\r\n", " ").Split(chArray);

                    this.ET_dp = new string[0x1388];
                    strArray2 = strArray;
                    num3 = 3;
                    goto Label_0002;
                }
                catch(Exception ext)
                {
                    return;
                }

            case 7:
                return;

            case 8:
                this.ET_dp[this.ET_cp] = "end";
                this.ET_cp = 0;
                this.ET_bf();
                num3 = 7;
                goto Label_0002;
        }
    }
}

本人声明:沐海(http://my.oschina.net/mahaisong) 以上文章是经过本人设计实践和阅读其他文档得出。如果需要探讨或指教可以留言!欢迎交流!

转载于:https://my.oschina.net/mahaisong/blog/139224

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值