Connect Prolog with C# on Visual Studio

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.

Hai phần mềm Prolog 32 bits 6.6.5SwiPlCs 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 !

Written on February 3, 2016