Keep Moving Forward

Tuesday, December 1, 2015

Kết nối Prolog với C# trên Visual Studio

1:52 PM Posted by Cáp Hữu Quân 9 comments
Prolog là một ngôn ngữ mạnh mẽ chuyên phục vụ cho Trí Tuệ Nhân Tạo và Xử Lý Ngôn Ngữ Tự Nhiên. Đôi lúc, chúng ta cũng phải kết hợp Prolog với các ngôn ngữ khác để tăng sự trực quan cho ứng dụng. Bài viết này sẽ đề cập đến việc kết nối C# vào Prolog để lấy kết quả trả về từ Prolog.

Vào chuyên môn luôn nào :)
Các yêu cầu để hỗ trợ kết nối:
1. Prolog phiên bản 32 bits 6.6.5
2. SwiPlCs: Thư viện kết nối C# và Prolog phiên bản 1.1.60605.0
3. Visual Studio bản 2008 trở lên.

2 phần mềm Prolog 32 bits 6.6.5 và SwiPlCs tương ứng có thể tải tại đây
Visual Studio thì các bạn tự cài nhé :)

Lưu ý: Vì thư viện SwiPlCs ngưng phát triển nên nó chỉ hỗ trợ phiên bản Prolog tương ứng là Prolog 32bits 6.6.5. Vậy nên, những ai đang chạy phiên bản Prolog khác thì phải gỡ và cài đúng bản 32 bits 6.6.5 thì mới kết nối được.

Sau khi chuẩn bị xong, ta sẽ đi qua bước kết nối.
Trong phần này, tôi sẽ demo để truy vấn 1 file prolog có nội dung như sau:


s-->np,vp.
np-->nn,pp.
np-->nnp.
np-->nn.
np-->nn,nn.
vp-->rb,vb,pp.
vp-->vb,pp.
vp-->rb,vb,np.
vp-->vb,vp.
vp-->vb,np.
pp-->in,nnp.
pp-->in,nn.
pp-->in,np.

nn-->[gia,đình].
nn-->[tỉnh].
nn-->[nhà].
nn-->[ngành].
nn-->[công,nghệ,thông,tin].
nn-->[thành,phố].
in-->[của].
in-->[ở].
nnp-->[nam].
vb-->[sống].
vb-->[học].
vb-->[về].
vb-->[thích].

rb-->[đang].
rb-->[thường].

Trước tiên, tạo 1 project Windows Form trên C# với giao diện như sau:

Form có tên là Demo_Prolog và lớp chính mang tên Demo_Prolog.cs. Hai button LoadQuery dùng để mở file prolog và truy vấn sau khi đã gõ lệnh truy vấn. Sau đó ta Build project bằng cách chọn Build -> Build Solution hoặc nhấn tổ hợp phím tắt Ctrl + Shift + B.
Sau khi build thành công project, ta có thêm thư mục Debug trong thư mục bin của project.


Lúc này, ta copy toàn bộ file trong thư mục SwiPlCs_1.1.60605.0 vào thư mục Debug nêu ở trên của Project.
Tiếp theo là bước quan trọng nhất. Ta sẽ thêm thư viện SwiPlCs vào project bằng cách từ giao diện project của Visual Studio chọn chuột phải vào References --> Add references.... Sau đó chọn Browse... rồi trỏ tới thư mục Debug của project và thêm 2 file SwiPlCs.dllnunit.framework.dll vào References

Sau khi thêm thư viện, sẽ tới phần code.
Ta tạo 1 class Connect_Prolog.cs để load file và kết nối với C#. Code như sau



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SbsSW.SwiPlCs;
using System.Text.RegularExpressions;
using NUnit.Framework;


namespace Connect_Prolog
{
    class ConnectProlog
    {
        //Load prolog file from hard disk
        public void Load_file(string s)
        {
            s = s.Replace("\\", "//");
            s = "consult('" + s + "')";
            string query = s.Replace("\\", "//");
            //string[] p = { "-q", "-f", query };
            //PlEngine.Initialize(p);
            try
            {
                PlQuery q = new PlQuery(query);
                Assert.IsTrue(q.NextSolution());
            }
            catch (SbsSW.SwiPlCs.Exceptions.PlException e)
            {
                System.Windows.Forms.MessageBox.Show(e.ToString(), "Error");
            }
        }

        // Prosessing a query
        public string Query(string s)
        {
            s.Trim();
            Regex r = new Regex(@"[A-Z_][a-zA-Z_]*");
            MatchCollection matches = r.Matches(s);
            string result = "";
            try
            {
                PlQuery q = new PlQuery(s);
                bool HasSolution = false;
                foreach (PlQueryVariables v in q.SolutionVariables)
                {
                    HasSolution = true;
                    foreach (Match match in matches)
                    {
                        result += v[match.ToString()].ToString() + " ; ";
                    }
                }
                if (matches.Count == 0)
                    return HasSolution ? "true" : "false";
                return result;
            }
            catch (SbsSW.SwiPlCs.Exceptions.PlException ex)
            {
                return "Error query: " + ex.Message;
            }
        }
    }
}

Tiếp theo trong file Demo_Prolog.cs có nội dung như sau:



using System;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
using SbsSW.SwiPlCs;
using NUnit.Framework;
using Connect_Prolog;

namespace Demo_Prolog
{
    public partial class Demo_Prolog : Form
    {
        Connect_Prolog.ConnectProlog connect;
        public Demo_Prolog()
        {
            connect = new ConnectProlog();
            InitializeComponent();
        }

        private void btn_Load_Click(object sender, System.EventArgs e)
        {
            OpenFileDialog op = new OpenFileDialog();
            op.Filter = "Prolog file|*.pl";
            op.ShowDialog();
            String FilePath = op.FileName;
            connect.Load_file(FilePath);
            MessageBox.Show("Load file success !");
            this.btn_Query.Enabled = true;
        }

        private void btn_Query_Click(object sender, EventArgs e)
        {
            if (this.txt_Query.Text != null)
            {
                String s = connect.Query(this.txt_Query.Text);
                this.txt_Result.Text = s;
            }
            else
            {
                MessageBox.Show("Please enter query !");
            }
        }
    }
}

Phần quan trọng nhất là điều chỉnh môi trường trong file Program.cs. Nội dung file Program.cs như sau:



using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using SbsSW.SwiPlCs;
using NUnit.Framework;

namespace Demo_Prolog
{
    static class Program
    {
        /// 

        /// The main entry point for the application.
        /// 

        [STAThread]
        static void Main()
        {
            Environment.SetEnvironmentVariable("SWI_HOME_DIR", @"C:\Program Files (x86)\swipl");
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            if (!PlEngine.IsInitialized)
            {
                String[] empty_param = { "" };
                PlEngine.Initialize(empty_param);
                Application.Run(new Demo_Prolog());
                PlEngine.PlCleanup();
            }
        }
    }
}
Lưu ý: Environment.SetEnvironmentVariable("SWI_HOME_DIR", @"C:\Program Files (x86)\swipl"); dùng để set môi trường cho việc kết nối bằng cách trỏ tới thư mục cài Prolog. Phải điền đúng đường dẫn vào thư mục cài đặt Prolog tùy thuộc vào hệ máy (32 hoặc 64 bits).

Xong rồi, giờ hãy chạy demo để xem kết quả.
Câu khi truy vấn ta cho kết quả như sau:

Hi vọng bài viết có thể giúp đỡ được các bạn. Chúc các bạn thành công !

9 comments:

  1. Bạn ơi cho mình bên trên bạn làm xuất ra dạng true/false. Vậy xuất ra dạng cây cú pháp thì sao? Cám ơn bạn!

    ReplyDelete
    Replies
    1. Chào bạn, ở trên mình chỉ Demo cách kết nối và trả về kết quả cho đoạn chương trình Prolog.
      Vì đoạn chương trình Prolog ở trên chỉ trả về True/False nên kết quả xuất ra ở form C# đương nhiên sẽ là True hoặc False.
      Nếu bạn muốn xuất cây cú pháp thì phải tùy thuộc vào chương trình của bạn trả về như thế nào nữa. Cái này bạn tự xử lý nhé.
      Chúc bạn thành công!

      Delete
    2. Kết Nối Prolog Với C Trên Visual Studio ~ Cáp Hữu Quân'S Blog >>>>> Download Now

      >>>>> Download Full

      Kết Nối Prolog Với C Trên Visual Studio ~ Cáp Hữu Quân'S Blog >>>>> Download LINK

      >>>>> Download Now

      Kết Nối Prolog Với C Trên Visual Studio ~ Cáp Hữu Quân'S Blog >>>>> Download Full

      >>>>> Download LINK Pj

      Delete
  2. Chòa bạn, sao của mình bị lỗi này nè bạn
    "Connect_Prolog.ConnectProlog connect;"
    Nhờ bạn hỗ trợ
    Xin cám ơn bạn nhé

    ReplyDelete
    Replies
    1. Chào bạn, theo mình thấy thì đây là dòng code chứ không phải lỗi.
      Nếu có lỗi bạn có thể copy mã lỗi và ảnh chụp lại không?
      Bạn hãy chắc rằng trên máy chỉ cài duy nhất 1 bản Prolog và thư viện kết nối ở link này: https://drive.google.com/file/d/0BxW8WySRlblWOUprQmZtbldPek0/view?usp=sharing
      Nếu máy bạn chạy khác bản Prolog với link trên thì không thể kết nối với C# được.

      Cảm ơn bạn!

      Delete
    2. This comment has been removed by the author.

      Delete
    3. This comment has been removed by the author.

      Delete
  3. Error query: '$c_call_prolog'/0: Undefined procedure: likes/2 lúc chạy ctr mình nó show ra lại cho mình lỗi này. Bạn có biết nó bị vấn đề nào không nhỉ? mình kiểm tra thấy PlQuery q = new PlQuery(s); nó trả về giá trị của q.SolutionVariables là rỗng

    ReplyDelete
  4. Kết Nối Prolog Với C Trên Visual Studio ~ Cáp Hữu Quân'S Blog >>>>> Download Now

    >>>>> Download Full

    Kết Nối Prolog Với C Trên Visual Studio ~ Cáp Hữu Quân'S Blog >>>>> Download LINK

    >>>>> Download Now

    Kết Nối Prolog Với C Trên Visual Studio ~ Cáp Hữu Quân'S Blog >>>>> Download Full

    >>>>> Download LINK nP

    ReplyDelete