Monday, June 29, 2026

Discretionary Power v. Inherent Power

ဥပဒေနယ်ပယ်နဲ့ တရားစီရင်ရေးနယ်ပယ်မှာအလွန်အရေးပါပြီး အမြဲလိုလို တွဲဖက်တွေ့ရှိရတတ်တဲ့ "Discretionary Power" (ကျင့်သုံးပိုင်ခွင့်/ အဆုံးအဖြတ်ပေးပိုင်ခွင့်အာဏာ) နဲ့"Inherent Power" (ကိုယ်ပိုင်ပင်ကိုယ်အရည်အသွေးအရ ရှိရင်းစွဲအာဏာ) တို့ရဲ့ အဓိပ္ပာယ်ဖွင့်ဆိုချက်တွေကို ဖော်ပြပေးပါမယ်။

၁။ Discretionary Power (ကျင့်သုံးပိုင်ခွင့် သို့မဟုတ် အဆုံးအဖြတ်ပေးပိုင်ခွင့်အာဏာ)
===========
Discretionary Power ဆိုတာ၊ ဥပဒေက တရားသူကြီး သို့မဟုတ် စီမံခန့်ခွဲရေးအာဏာပိုင်တစ်ဦးကို ကိစ္စရပ်တစ်ခုအပေါ် တိကျပြတ်သားသော စည်းမျဉ်းတစ်ခုတည်းအတိုင်း လိုက်နာရန် အတင်းအကျပ် မပြဌာန်းဘဲ၊ ဖြစ်ရပ်ရဲ့ အခြေအနေအရပ်ရပ်ကို သုံးသပ်ပြီး မိမိရဲ့ ကိုယ်ပိုင်အမြော်အမြင်၊ တရားမျှတမှုစံနှုန်းတို့အပေါ် အခြေခံကာ လွတ်လပ်စွာ ရွေးချယ်ဆုံးဖြတ်ပိုင်ခွင့် ပေးထားတဲ့ အာဏာကို ဆိုလိုတယ်။ သို့သော် ထိုအာဏာဟာ၊ လုံးဝဥဿုံ လွတ်လပ်ခြင်း (Arbitrary) မဟုတ်ဘဲ ဥပဒေကြောင်းအရ အကြောင်းပြချက် ခိုင်လုံရပါမယ်။
REF: Black's Law Dictionary (11th Edition), Bryan A. Garner, 2019, Thomson Reuters (West Publishing Co.), St. Paul, MN, USA., p.583, "Judicial Discretion"
• အနှစ်ချုပ်: ဥပဒေကြောင်းအရ ပြတ်ပြတ်သားသား ကန့်သတ်မထားတဲ့ ကိစ္စရပ်များတွေမှာ တရားသူကြီးတစ်ဦးအနေဖြင့် မျှတမှု နဲ့ သင့်လျော်မှန်ကန်မှုရှိစေရန် မိမိ၏ ကိုယ်ပိုင်ဆုံးဖြတ်ချက်ဖြင့် ဆောင်ရွက်နိုင်ခွင့် ဟာ (Discretion) ဖြစ်တယ်။
• ဥပမာအားဖြင့် ပြစ်မှုဆိုင်ရာကျင့်ထုံးဥပဒေမှာ အာမခံပေးခြင်းနဲ့စပ်လျဉ်းပြီး "May be released on bail" (အာမခံပေးနိုင်သည်) ဟု သုံးနှုန်းထားခြင်းမျိုး ဖြစ်တယ်။ "May" လို့ သုံးနှုန်းထားခြင်းဟာ တရားရုံးကို "Discretionary Power" ပေးထားခြင်းဖြစ်ပြီး၊ မဖြစ်မနေ ပေးရမည်ဟု ပြဌာန်းတဲ့ "Shall" နဲ့ကွာခြားတယ်။

၂။ Inherent Power (ကိုယ်ပိုင်ပင်ကိုယ်အရည်အသွေးအရ ရှိရင်းစွဲအာဏာ၊ မူလဘူတအာဏာ)
==============
Inherent Power ဆိုတာကို ဥပဒေပြဌာန်းချက်တွေမှာ တိတိပပ အတိအလင်း ရေးသားဖော်ပြမထားပေမဲ့၊ တရားရုံးတစ်ခုရဲ့ ဂုဏ်သိက္ခာကို ထိန်းသိမ်းရန်၊ တရားစီရင်ရေးလုပ်ငန်းစဉ်ကို အလွဲသုံးစားလုပ်ခြင်းမှ ကာကွယ်ရန်နဲ့ အမှုသည်များအတွက် "စစ်မှန်သော တရားမျှတမှု" (Ends of Justice) ဖော်ဆောင်ပေးနိုင်ရန်၊ "တရားရုံးဖြစ်တည်လာမှုနှင့်အတူ ပင်ကိုယ်ကတည်းက ကပ်ပါလာသော အာဏာ" ကို ဆိုလိုတယ်။ ဥပဒေပြဌာန်းချက်မှာ လစ်ဟာနေတဲ့ကြားနယ် (Gap) ဖြစ်နေပြီး၊ အခက်အခဲကြုံရချိန်မှာ ဒီ အာဏာကို သုံးရတယ်။
REF: Mulla: The Code of Civil Procedure (Abridged Edition / 18th Edition), Sir Dinshah Fardunji Mulla (Revised by Soli J. Sorabjee), (2012), LexisNexis Butterworths Wadhwa, Nagpur, India., (Pages 280-284), Section 151 ဖွင့်ဆိုချက်အောက်တွင်ရှု။
o အနှစ်ချုပ်: ဥပဒေပြုလွှတ်တော်ဟာ အနာဂတ်မှာ ဖြစ်လာမဲ့ အခြေအနေအားလုံးကို ကြိုတင်ခန့်မှန်းပြီး ဥပဒေမပြဌာန်းနိုင်ဘူး။ ဒါ့ကြောင့် ဥပဒေမှာ အတိအလင်း မပါရှိပေမဲ့ တရားမျှတမှုအတွက် လိုအပ်ပါက တရားရုံးက ၎င်းရဲ့ ရှိရင်းစွဲအာဏာ၊ မူလဘူတ အာဏာ (Inherent Power) ဆိုတာကို သုံးပိုင်ခွင့်ရှိတယ်။

Saturday, February 21, 2026

Hill-climbing Algorithm for 8-Queens Problem

Stuart Russell နဲ့ Peter Norvig တို့ ရေးသားတဲ့၊ “Artificial Intelligence: A Modern Approach, Fourth Edition” စာအုပ် ရဲ့၊ "CHAPTER 4 SEARCH IN COMPLEX ENVIRONMENTS" အခန်းမှာ ပါတဲ့ "Hill-climbing Algorithm" ကို "8-queens problem" နဲ့ ပေါင်းစပ်ပြီး အပြည့်အစုံ ရှင်းလင်းတင်ပြပေးပါမယ်။

Figure 4.3 (က) ဘုရင်မ ၈-ပါးပြဿနာ။ ဘုရင်မ ၈-ပါးကို စစ်တုရင်ဘုတ်ပေါ်တွင် ဘုရင်မတစ်ပါးနှင့်တစ်ပါး မတိုက်ခိုက်စေရန် ထားပါ။ (ဘုရင်မသည် အတန်း၊ ကော်လံ သို့မဟုတ် ထောင့်ဖြတ် ပေါ်ရှိ မည်သည့် အရာကိုမဆို တိုက်ခိုက်နိုင်ပါသည်။) ပုံတွင် ထောင့်ဖြတ်မျဉ်းတစ်လျှောက်တွင် တစ်ခုနှင့်တစ်ခု တိုက်ခိုက်နေသော စတုတ္ထနှင့် သတ္တမကော်လံရှိ ဘုရင်မနှစ်ပါးမှလွဲ၍ ဤအနေအထားသည် အဖြေတစ်ခု ရလုနီးပါးအဆင့်ဖြစ်သည်။ 

(ခ) heuristic cost estimate [current state အတွက်၊ ကျန်ရှိနေသေးတဲ့ ပဋိပက္ခ conflicts အရေအတွက် ကို တိုင်းတာတဲ့ဖန်ရှင်] h = 17 ပါသော ဘုရင်မ ၈-ပါးအခြေအနေ။ လက်ရှိအခြေအနေ။ စစ်တုရင်ဘုတ်သည် ၎င်း၏ကော်လံအတွင်း ဘုရင်မတစ်ပါးကို ရွှေ့ခြင်းဖြင့် ရရှိနိုင်သော ဆက်ခံသူတိုင်းအတွက် h ၏တန်ဖိုးကို ပြသည်။ h = 12 ဖြင့် အကောင်းဆုံးတွဲဖက်ထားသော ရွေ့လျားမှု ၈-ခုရှိသည်။ hill-climbing algorithm သည် ဤအရာများထဲမှ တစ်ခုကို ရွေးပါမည်။

(နည်းသစ်ဉာဏ်ရည်တုပညာမိတ်ဆက်, စာ-၁၆၀)

ပြီးပြည့်စုံသောအခြေအနေ တည်ဆောက်ခြင်း (Complete-state Formulation)

8-queens ပြဿနာကို ဖြေရှင်းရာမှာ နည်းလမ်းအမျိုးမျိုးရှိပါတယ်။ ဥပမာ - ဘုတ်ပြားအလွတ်ကနေ စပြီး ဘုရင်မ တစ်ပါးချင်းစီကို အဆင့်လိုက် နေရာချသွားတဲ့ နည်းလမ်းရှိသလို၊ ယခု ကျွန်တော်တို့ အသုံးပြုမယ့် Complete-state formulation လိုမျိုး နည်းလမ်းလည်း ရှိပါတယ်။

Complete-state formulation ဆိုတာ အစကတည်းက စစ်တုရင်ဘုတ်ပြားပေါ်မှာ ကော်လံ (Column) တစ်ခုကို ဘုရင်မတစ်ပါးစီနှုန်းနဲ့ ၈ ပါးလုံးကို နေရာချထားလိုက်ခြင်းပါ။ ဆိုလိုတာက အခြေအနေတိုင်းမှာ အဖြေတစ်ခု ဖြစ်လာဖို့ လိုအပ်တဲ့ "အစိတ်အပိုင်းများ အားလုံး (ဘုရင်မ ၈ ပါးလုံး)" ပါရှိနေပြီးသား ဖြစ်ပါတယ်။ ဒါပေမဲ့ ၎င်းတို့ဟာ အချင်းချင်း တိုက်ခိုက်နိုင်တဲ့ (စားနိုင်တဲ့) နေရာတွေမှာ ရှိနေနိုင်တဲ့အတွက် အားလုံးက မှန်ကန်တဲ့ နေရာမှာတော့ ရှိမနေသေးပါဘူး။ ကျွန်တော်တို့ရဲ့ အဓိက ရည်ရွယ်ချက်က အဲဒီ ပဋိပက္ခ (Conflicts) တွေကို တစ်ဆင့်ချင်း လျှော့ချသွားဖို့ပဲ ဖြစ်ပါတယ်။


Heuristic Cost Estimate

Hill-climbing (တောင်တက်ခြင်း) အယ်လဂိုရီသမ်က အကောင်းဆုံး အဖြေကို ရှာဖွေဖို့ Heuristic cost ကို အသုံးပြုပါတယ်။ 8-queens ပြဿနာအတွက် Heuristic ဆိုတာ "လက်ရှိအခြေအနေမှာ အချင်းချင်း တိုက်ခိုက်နေတဲ့ (စားလို့ရနေတဲ့) ဘုရင်မ စုံတွဲအရေအတွက် (Number of attacking pairs)" ကို တွက်ချက်တာပါ။ ပဋိပက္ခ လုံးဝမရှိတဲ့ ပြီးပြည့်စုံတဲ့ အဖြေမှန်ကို ရဖို့ဆိုရင် ဒီ Cost တန်ဖိုးက 0 ဖြစ်သွားရပါမယ်။

Python Code

 
# -*- coding: utf-8 -*-
"""
Created on Sat Feb 21 20:59:50 2026
@author: kks
"""
import random
# ဘုရင်မ ၈ ပါးရဲ့ အခြေအနေကို list တစ်ခုအနေနဲ့ ဖော်ပြပါမယ်။
# ဥပမာ - state = [3, 0, 4, 7, 5, 2, 6, 1] ဆိုပါစို့။
# index (0 မှ 7 အထိ) က ကော်လံ (Column) ကို ကိုယ်စားပြုပြီး၊ 
# ထိုနေရာရှိ တန်ဖိုးက အဲဒီကော်လံမှာရှိတဲ့ ဘုရင်မရဲ့ အတန်း (Row) ကို ကိုယ်စားပြုပါတယ်။
# ဒါဟာ Complete-state formulation ကို ကိုယ်စားပြုတဲ့ အကောင်းဆုံး Data Structure ဖြစ်ပါတယ်။
def calculate_conflicts(state):
    """
    Heuristic cost estimate function ပါ။
    လက်ရှိ board အခြေအနေ (state) မှာ အချင်းချင်း တိုက်ခိုက်နိုင်တဲ့ ဘုရင်မ စုံတွဲ အရေအတွက်ကို တွက်ချက်ပေးပါတယ်။
    """
    conflicts = 0
    n = len(state)
    for i in range(n):
        for j in range(i + 1, n):
            # တိုက်ခိုက်နိုင်ခြေ (၂) မျိုးကို စစ်ဆေးရပါမယ်။
            # ၁။ အတန်း (Row) တူနေသလား စစ်ဆေးခြင်း -> state[i] == state[j]
            # ၂။ ထောင့်ဖြတ် (Diagonal) တူနေသလား စစ်ဆေးခြင်း -> abs(state[i] - state[j]) == abs(i - j)
            # မှတ်ချက် - ကော်လံ (Column) ကတော့ Array ရဲ့ Index မတူတဲ့အတွက် အမြဲတမ်း ကွဲပြားနေပြီးသားပါ။
            if state[i] == state[j] or abs(state[i] - state[j]) == abs(i - j):
                conflicts += 1
    return conflicts
def get_best_neighbor(state):
    """
    လက်ရှိအခြေအနေကနေ သွားနိုင်တဲ့ အိမ်နီးချင်း (Neighbors) ၅၆ ခုထဲက
    conflicts အနည်းဆုံးဖြစ်မယ့် အကောင်းဆုံး အိမ်နီးချင်းကို ရှာဖွေပေးပါတယ်။
    (ကော်လံ ၈ ခုမှာရှိတဲ့ ဘုရင်မတွေကို ကိုယ်ပိုင်ကော်လံအတွင်း အခြား row ၇ ခုဆီ တစ်ပါးချင်း ရွှေ့ကြည့်ခြင်းဖြစ်ပါတယ်၊ ၈ x ၇ = ၅၆)
    """
    best_neighbors = []
    # လက်ရှိ cost ကို အနည်းဆုံး cost အဖြစ် အရင်သတ်မှတ်ထားပါမယ်။
    min_conflicts = calculate_conflicts(state)
    n = len(state)
    for col in range(n):
        for row in range(n):
            if state[col] == row:
                continue # လက်ရှိရှိနေတဲ့နေရာကို ရွှေ့စရာမလိုလို့ ကျော်သွားပါမယ်
            # အိမ်နီးချင်း အခြေအနေသစ် တစ်ခု ဖန်တီးပါမယ်
            neighbor = list(state)
            neighbor[col] = row
            
            # အိမ်နီးချင်းအသစ်ရဲ့ Heuristic cost (conflicts) ကို တွက်ချက်ပါမယ်
            neighbor_conflicts = calculate_conflicts(neighbor)
            if neighbor_conflicts < min_conflicts:
                # ပိုကောင်းတဲ့ အခြေအနေ (conflicts ပိုနည်းတဲ့ အခြေအနေ) ကို တွေ့ရင်
                min_conflicts = neighbor_conflicts
                best_neighbors = [neighbor] # တွေ့ထားသမျှ အကောင်းဆုံး list ကို အသစ်ပြန်စပါမယ်
            elif neighbor_conflicts == min_conflicts:
                # တူညီတဲ့ အကောင်းဆုံး အခြေအနေတွေကို list ထဲ ထပ်ထည့်ပါမယ်
                best_neighbors.append(neighbor)
    # အကောင်းဆုံး အိမ်နီးချင်းတွေထဲက တစ်ခုကို ကျပန်းရွေးချယ်ပါမယ်
    if best_neighbors:
        return random.choice(best_neighbors), min_conflicts
    else:
        return state, min_conflicts # ပိုကောင်းတဲ့ အိမ်နီးချင်း မရှိရင် လက်ရှိကိုပဲ ပြန်ပေးပါမယ်
def hill_climbing(initial_state):
    """
    Steepest-ascent Hill-climbing algorithm ရဲ့ အဓိက အပိုင်းဖြစ်ပါတယ်။
    """
    current_state = initial_state
    current_conflicts = calculate_conflicts(current_state)
    step = 0
    print(f"Step {step}: Initial State = {current_state}, Conflicts = {current_conflicts}")
    while True:
        # အကောင်းဆုံး အိမ်နီးချင်းကို ရှာပါမယ်
        neighbor, neighbor_conflicts = get_best_neighbor(current_state)
        # Hill-climbing ရဲ့ အားနည်းချက် သဘောတရားအရ၊ ပိုကောင်းတဲ့ အိမ်နီးချင်း မရှိတော့ရင် (သို့) 
        # လက်ရှိထက် ပဋိပက္ခ မနည်းတော့ဘူးဆိုရင် တောင်ထိပ် (Local Maxima သို့မဟုတ် Global Maxima) ကို ရောက်ပြီဖြစ်လို့ ဆက်မရှာဘဲ ရပ်ပါမယ်။
        if neighbor_conflicts >= current_conflicts:
            print(f"\nSearch stopped. Reached a peak (cost cannot be decreased further).")
            break
        # အခြေအနေသစ်ကို ပြောင်းလဲပါမယ်
        current_state = neighbor
        current_conflicts = neighbor_conflicts
        step += 1
        print(f"Step {step}: Moved to = {current_state}, Conflicts = {current_conflicts}")
    return current_state, current_conflicts
# ပရိုဂရမ် စတင်ခြင်း
if __name__ == "__main__":
    # Complete-state formulation အရ ဘုရင်မ ၈ ပါးကို ကျပန်း နေရာချပါမယ်
    # (ကော်လံတစ်ခုစီအတွက် row 0 ကနေ 7 အထိ ကျပန်းရွေးချယ်ပါမယ်)
    initial_board = [random.randint(0, 7) for _ in range(8)]
    
    print("--- Hill-Climbing Algorithm for 8-Queens ---")
    final_state, final_cost = hill_climbing(initial_board)
    
    print("\n--- Final Result ---")
    print(f"Final State: {final_state}")
    print(f"Remaining Conflicts: {final_cost}")
    
    if final_cost == 0:
        print("Success! A complete solution without any conflicts was found.")
    else:
        print("Failed to find a perfect solution. Got stuck in a Local Maximum.")
        print("(မှတ်ချက် - ရိုးရှင်းသော Hill-climbing သည် တောင်ကုန်းငယ်များ (Local Maxima) တွင် ပိတ်မိလေ့ရှိပါသည်။ ၎င်းသည် ဤ Algorithm ရဲ့ သဘာဝ အားနည်းချက်ဖြစ်ပါသည်။)")


ပရိုဂရမ် အနှစ်ချုပ်

ဒီပရိုဂရမ်က၊ ဘုရင်မ ၈ ပါးကို ကျပန်းချထားခြင်းမှ စတင်ပြီး၊ တစ်ဆင့်ချင်းစီမှာ၊ အချင်းချင်းတိုက်ခိုက်မှု (Conflicts) အနည်းဆုံးဖြစ်စေမဲ့ အိမ်နီးချင်းအခြေအနေဆီသို့ ရွှေ့လျားသွားပါတယ်။ တိုက်ခိုက်မှု လုံးဝမရှိတော့သည့် အခြေအနေ (သို့မဟုတ်) ထပ်မံ၍ လျှော့ချ၍ မရနိုင်တော့သည့် အခြေအနေ (Local Maxima) သို့ရောက်သောအခါ ရပ်တန့်သွားမှာဖြစ်ပါတယ်။

နောက် ပို့စ်မှာ Hill-Climbing ရဲ့ အဓိကပြဿနာဖြစ်တဲ့ "Local Maxima မှာ ပိတ်မိတတ်ခြင်း" ကို ဖြေရှင်းပေးနိုင်တဲ့ "Random-restart hill-climbing" အကြောင်းကိုဆက်လက်တင်ပြပေးပါမယ်။

Sunday, February 8, 2026

Inductive Logic Programming (ILP)

REF:

AIMA 4th Edition

Chapter 20 Knowledge in Learning

20.5 Inductive Logic Programming

p-758

                                 Inductive Logic Programming (ILP) ဟူသည် စက်သင်ယူမှု (Machine Learning) နှင့် လောဂျစ်ပရိုဂရမ်ရေးသားခြင်း (Logic Programming) တို့ကို ပေါင်းစပ်ထားသော ပညာရပ်တစ်ခု ဖြစ်ပါတယ်။ ၎င်းသည် "နမူနာများမှတစ်ဆင့် ယေဘုယျကျသော စည်းမျဉ်းများကို လောဂျစ်နည်းကျ ဖော်ထုတ်ခြင်း" ဟု အဓိပ္ပာယ်ရတယ်။ အောက်မှာ ILP ရဲ့ လက်တွေ့လုပ်ဆောင်ပုံကို အတိုချုပ်ပြီး အဆင့်ဆင့် ရှင်းလင်းတင်ပြပေးလိုက်ပါတယ်။


ILP လက်တွေ့လုပ်ဆောင်ပုံ (Step-by-Step)

ILP စနစ်တစ်ခု အလုပ်လုပ်ရန်အတွက် အဓိက အစိတ်အပိုင်း () ခု လိုအပ်ပါတယ်။

  1. နောက်ခံဗဟုသုတ (Background Knowledge - BK) ကျွန်ုပ်တို့ ကြိုတင်သိရှိထားပြီးသား အချက်အလက်များ။
  2. အပြုသဘောဆောင်သော နမူနာများ (Positive Examples – E+ ) မှန်ကန်ကြောင်း ကျွန်ုပ်တို့ သိရှိသော အချက်များ။
  3. အနုတ်လက္ခဏာဆောင်သော နမူနာများ (Negative Examples -E-) မမှန်ကန်ကြောင်း (သို့မဟုတ်) မဖြစ်နိုင်ကြောင်း ကျွန်ုပ်တို့ သိရှိသော အချက်များ။

ပန်းတိုင်: E+ အားလုံးကို ရှင်းပြနိုင်ပြီး E- တစ်ခုမှ မပါဝင်သော လောဂျစ်စည်းမျဉ်း (Hypothesis - H) ကို ရှာဖွေရန်။

ဥပမာ - "ဘိုးဘွား" (Grandparent) တော်စပ်မှုကို သင်ယူခြင်း

အဆင့် () - အချက်အလက်များ ထည့်သွင်းခြင်း (Inputs)

  • BK: parent(maung_maung, zaw_zaw), parent(zaw_zaw, hla_hla) (မောင်မောင်သည် ဇော်ဇော်၏ အဖေ၊ ဇော်ဇော်သည် လှလှ၏ အဖေ)
  • E+: grandparent(maung_maung, hla_hla) (မောင်မောင်သည် လှလှ၏ ဘိုးဘွားဖြစ်သည် - မှန်)
  • E-: grandparent(hla_hla, maung_maung) (လှလှသည် မောင်မောင်၏ ဘိုးဘွားဖြစ်သည် - မှား)

အဆင့် () - ယူဆချက်ကို စတင်ရှာဖွေခြင်း (Hypothesis Construction)

ILP သည် အောက်ပါအတိုင်း စည်းမျဉ်းများကို စမ်းသပ်ပါမည် -

  • ယူဆချက် : grandparent(X, Y) :- parent(X, Y). (X သည် Y မိဘဖြစ်လျှင် ဘိုးဘွားဖြစ်သည်)
    • ရလဒ်: E+ ကို မရှင်းပြနိုင်ပါ။ (မောင်မောင်သည် လှလှ၏ မိဘမဟုတ်ပါ)
  • ယူဆချက် : grandparent(X, Y) :- parent(X, Z), parent(Z, Y). (X သည် Z မိဘဖြစ်ပြီး၊ ထို Z သည် Y မိဘဖြစ်လျှင် X သည် Y ဘိုးဘွားဖြစ်သည်)
    • ရလဒ်: E+ ကို ရှင်းပြနိုင်သည် (မောင်မောင်ဇော်ဇော်လှလှ) E- ကိုလည်း ရှောင်လွှဲနိုင်ပါတယ်။

အဆင့် () - ယေဘုယျပြုခြင်း (Generalization)

ရှာဖွေတွေ့ရှိထားသော စည်းမျဉ်းကို အခြားဒေတာအသစ်များတွင် အသုံးပြုနိုင်ရန် အတည်ပြုလိုက်ပါတယ်။ ဤနည်းဖြင့် ILP သည် 'Grandparent' ဆိုသော အဓိပ္ပာယ်ကို ဒေတာများမှတစ်ဆင့် ကိုယ်တိုင် သင်ယူသွားခြင်း ဖြစ်ပါတယ်။


လက်တွေ့လုပ်ဆောင်နိုင်သော Python ပရိုဂရမ်

လက်တွေ့မှာ ILP ကို Prolog ဘာသာစကားနဲ့ အရေးအများဆုံး ဖြစ်ပေမဲ့, Python တွင် Kanren သို့မဟုတ် SymPy တို့ကဲ့သို့သော Logic library များ ရှိပါတယ်။ ဒီနေရာမှာ ILP ရဲ့ သဘောသဘာဝကို နားလည်စေဖို့ Simple Rule Learner ပုံစံမျိုးကို Python ဖြင့် ဖန်တီးပြပါမယ်။ 

ဒီပရိုဂရမ်က ပေးထားသော မိဘတော်စပ်မှု (Parent) ဒေတာများမှ ဘိုးဘွားတော်စပ်မှု (Grandparent) စည်းမျဉ်းကို အလိုအလျောက် ရှာဖွေပေးပါမယ်။

 

Python
# Simple ILP-style Rule Learner in Python
 
class SimpleILP:
    def __init__(self, background_knowledge, pos_examples, neg_examples):
        self.bk = background_knowledge
        self.pos = pos_examples
        self.neg = neg_examples
 
    def test_rule(self, rule_func):
        # အပြုသဘောဆောင်သော နမူနာအားလုံး မှန်ရမည်
        for p in self.pos:
            if not rule_func(p[0], p[1], self.bk):
                return False
        # အနုတ်လက္ခဏာဆောင်သော နမူနာအားလုံး မှားရမည်
        for n in self.neg:
            if rule_func(n[0], n[1], self.bk):
                return False
        return True
 
# နောက်ခံဗဟုသုတ (Parent Relationship)
# parent(parent_name, child_name)
bk_data = [
    ('Maung Maung', 'Zaw Zaw'),
    ('Zaw Zaw', 'Hla Hla'),
    ('Aung Aung', 'Kyaw Kyaw'),
    ('Kyaw Kyaw', 'Mya Mya')
]
 
# သင်ယူရမည့် နမူနာများ (Positive & Negative)
pos_examples = [('Maung Maung', 'Hla Hla'), ('Aung Aung', 'Mya Mya')]
neg_examples = [('Hla Hla', 'Maung Maung'), ('Zaw Zaw', 'Maung Maung')]
 
# စမ်းသပ်မည့် ယူဆချက်များ (Hypotheses)
def hypothesis_1(X, Y, bk):
    # Rule: grandparent(X, Y) :- parent(X, Y)
    return (X, Y) in bk
 
def hypothesis_2(X, Y, bk):
    # Rule: grandparent(X, Y) :- parent(X, Z), parent(Z, Y)
    for parent, child in bk:
        if parent == X:
            Z = child
            if (Z, Y) in bk:
                return True
    return False
 
# ILP Engine စတင်လည်ပတ်ခြင်း
learner = SimpleILP(bk_data, pos_examples, neg_examples)
 
print("--- ILP Learning Process ---")
for i, hyp in enumerate([hypothesis_1, hypothesis_2], 1):
    result = learner.test_rule(hyp)
    status = "Passed " if result else "Failed "
    print(f"Testing Hypothesis {i}: {status}")
    if result:
        print(f"Found Correct Rule: grandparent(X, Y) :- parent(X, Z), parent(Z, Y)")

 ရှင်းလင်းချက်:

  1. BK Data မိသားစု ဆက်နွယ်မှုများကို Tuple အဖြစ် သိမ်းထားပါတယ်။
  2. SimpleILP Class ၎င်းသည် ပေးထားသော Rule တစ်ခုသည် Positive examples များကို အကုန်လက်ခံပြီး Negative များကို ငြင်းပယ်ခြင်း ရှိမရှိ စစ်ဆေးပေးသည့် "Evaluator" ဖြစ်တယ်။
  3. Hypothesis 1 ၎င်းသည် "မိဘဖြစ်လျှင် ဘိုးဘွားဖြစ်သည်" ဟု ယူဆသောကြောင့် စစ်ဆေးမှု ကျရှုံးပါတယ်။
  4. Hypothesis 2 ၎င်းသည် "မိဘ၏ မိဘ" (Grandparent) ဖြစ်သည်ကို စစ်ဆေးနိုင်သောကြောင့် စစ်ဆေးမှု အောင်မြင်သွားပါတယ်။

လက်တွေ့အသုံးချမှု

အစစ်အမှန် ILP စနစ်များ (ဥပမာ - Aleph, Metagol) သည် ဤထက်မက ရှုပ်ထွေးသော စည်းမျဉ်းများကို ဒေတာ သန်းပေါင်းများစွာထဲမှ ရှာဖွေနိုင်ပါတယ်။ ၎င်းတို့ကို ဇီဝဗေဒဆိုင်ရာ မော်လီကျူးများ တည်ဆောက်ပုံ လေ့လာခြင်း (Drug discovery) နှင့် သဘာဝဘာသာစကား နားလည်ခြင်း (NLP) တို့တွင် အသုံးချကြပါတယ်။

Thursday, January 29, 2026

အေအိုင် နှင့် ပညာမျိုးကန်းမည့်အန္တရာယ်

ပညာသင်ကြားရေးနယ်ပယ်တွင် ဆရာများသည် မိမိ၏ ကိုယ်ပိုင် ဉာဏ်ပညာ အတွေ့အကြုံကို အသုံးမပြုပဲ၊ အေအိုင် ကိုအသုံးပြု၍ ဘာသာပြန်ခြင်း၊ မေးခွန်းများ ဖန်တီးခြင်း၊ word puzzle များ ဖန်တီးခြင်း၊ အေအိုင် လုပ်ဆောင်ပေးသောအရာများကို မိမိကိုယ်ပိုင် ဉာဏ်ရည်အစစ်အမှန်ဖြင့် မှန်မမှန် စစ်ဆေးခြင်း၊ အတည်ပြုခြင်း၊ ပြင်ဆင်ခြင်း ဖြည့်စွက်ခြင်းတို့ မလုပ်ပဲ ၎င်းအရာများ မေးခွန်းများဖြင့် ကျောင်းသားတို့အား သင်ကြားလျက်ရှိကြသည်။ ထိုကဲ့သို့ ပညာသင်ကြားရေးနယ်ပယ်တွင် ဆရာများအနေဖြင့် အေအိုင် (AI) ကို အစစ်အမှန် ဉာဏ်ရည် (Human Intelligence) ဖြင့် ထိန်းကျောင်းခြင်း မပြုဘဲ အလွယ်တကူ အသုံးပြုနေခြင်းသည် ရေတိုတွင် အဆင်ပြေစေသော်လည်း၊ ကျောင်းသားများ၏ အနာဂတ်အတွက် အလွန်စိုးရိမ်ဖွယ်ရာကောင်းသော ရိုက်ခတ်မှုများ ရှိလာနိုင်ပါသည်။

ဤပြဿနာကို ရှုထောင့်အသီးသီးမှ ဝေဖန်သုံးသပ်တင်ပြပါမည်။

၁။ ပညာရေး ရှုထောင့် (Educational Perspective)
သင်ကြားမှု အရည်အသွေး ကျဆင်းခြင်း
ပညာရေး၏ အနှစ်သာရမှာ အချက်အလက်များကို ပေးပို့ရုံမျှမကဘဲ ဝေဖန်ပိုင်းခြားနိုင်သော စိတ်ကူးစိတ်သန်း (Critical Thinking) ကို ပျိုးထောင်ပေးရန် ဖြစ်သည်။

မှားယွင်းသော ဗဟုသုတများ ပျံ့နှံ့ခြင်း
 AI သည် တစ်ခါတစ်ရံ "Hallucination" ဟုခေါ်သော ယုတ္တိတန်သယောင်နှင့် မှားယွင်းသော အချက်အလက်များကို ထုတ်ပေးတတ်သည်။ ဆရာက စစ်ဆေးခြင်းမပြုဘဲ သင်ကြားပါက ကျောင်းသားများသည် အမှားများကို အမှန်ဟု မှတ်ယူသွားနိုင်ပြီး အခြေခံပညာရေး အုတ်မြစ် ပျက်စီးစေပါသည်။

သင်ရိုးညွှန်းတမ်းနှင့် အံဝင်ခွင်ကျမဖြစ်ခြင်း
AI သည် ယေဘုယျကျသော အဖြေများကိုသာ ပေးနိုင်သည်။ ကျောင်းသားတစ်ဦးချင်းစီ၏ လိုအပ်ချက်၊ ဒေသန္တရအခြေအနေနှင့် သင်ခန်းစာ၏ ရည်ရွယ်ချက် (Learning Objectives) တို့ကို ဆရာ၏ ကိုယ်ပိုင်ဉာဏ်ဖြင့် ပေါင်းစပ်ခြင်းမရှိပါက သင်ကြားမှုသည် အနှစ်မဲ့သော စက်ရုပ်ဆန်သည့် လုပ်ငန်းစဉ် ဖြစ်သွားပါလိမ့်မည်။

၂။ လူမှုရေး ရှုထောင့် (Social Perspective)
ဆရာနှင့် တပည့် ဆက်ဆံရေး ယိုယွင်းခြင်း
ဆရာဟူသည် ကျောင်းသားများအတွက် စံပြပုဂ္ဂိုလ် (Role Model) ဖြစ်သည်။

ယုံကြည်မှု ကင်းမဲ့လာခြင်း
ဆရာကိုယ်တိုင်က AI ထုတ်ပေးသမျှကို စဉ်းစားဆင်ခြင်ခြင်းမရှိဘဲ ခိုင်းစေနေသည်ကို ကျောင်းသားများ သိရှိသွားပါက ဆရာအပေါ်ထားရှိသော လေးစားမှုနှင့် ယုံကြည်မှု ကျဆင်းသွားပါမည်။ "ဆရာတောင် မစဉ်းစားဘဲ AI ခိုင်းနေတာပဲ၊ ငါတို့ကော ဘာလို့ ကြိုးစားနေရမှာလဲ" ဆိုသည့် အတွေးမျိုး ဝင်လာနိုင်ပါသည်။

စံနမူနာအမှား ပေးမိခြင်း
ဤလုပ်ရပ်သည် "ဖြတ်လမ်းနည်းဖြင့် အောင်မြင်မှုရှာခြင်း" နှင့် "တာဝန်ယူမှု ကင်းမဲ့ခြင်း" ကို လူမှုကျင့်ဝတ်တစ်ခုသဖွယ် ကျောင်းသားများထံ လက်ဆင့်ကမ်းပေးလိုက်သကဲ့သို့ ဖြစ်နေပါသည်။

၃။ စိတ်ပညာ ရှုထောင့် (Psychological Perspective)
 မှတ်ဉာဏ်နှင့် စဉ်းစားနိုင်စွမ်း အားနည်းလာခြင်း
ပညာသင်ကြားခြင်းသည် ဦးနှောက်ကို လေ့ကျင့်ခန်းပေးခြင်း ဖြစ်သည်။

သိမြင်မှုဆိုင်ရာ ပျင်းရိခြင်း (Cognitive Laziness)
ဆရာကိုယ်တိုင်က AI ကိုသာ မှီခိုနေပါက ကျောင်းသားများသည်လည်း အခက်အခဲတစ်ခုကို ရင်ဆိုင်ဖြေရှင်းလိုစိတ် မရှိတော့ဘဲ လွယ်ကူသော နည်းလမ်းကိုသာ အမြဲရှာဖွေတတ်သည့် စိတ်ဓာတ် (Dependency Syndrome) ကိန်းအောင်းသွားနိုင်ပါသည်။

တီထွင်ဖန်တီးနိုင်စွမ်း သေဆုံးခြင်း
AI ထုတ်ပေးသော ဘောင်အတွင်း၌သာ လည်ပတ်နေခြင်းကြောင့် ကျောင်းသားများ၏ ထူးခြားဆန်းသစ်သော အတွေးအခေါ်များနှင့် စိတ်ကူးစိတ်သန်းများကို ဖော်ထုတ်ပေးနိုင်သည့် "မေးခွန်းကောင်း" များ၊ "စိန်ခေါ်မှုများ" ပျောက်ကွယ်သွားနိုင်ပါသည်။

၄။ အတွေးအခေါ် ရှုထောင့် (Philosophical Perspective)
 လူသားဆန်မှုနှင့် ဉာဏ်ပညာ ပျောက်ဆုံးခြင်း
အတွေးအခေါ်ပညာရှင် R.G. Collingwood ကဲ့သို့သော ပုဂ္ဂိုလ်များ၏ အယူအဆအရ "ပညာ" ဆိုသည်မှာ မိမိကိုယ်တိုင် ပြန်လည်တွေးတော ဆင်ခြင်ခြင်း (Reflection) မှ ရရှိလာခြင်း ဖြစ်သည်။

ဉာဏ်ပညာ ကန်းမည့်အန္တရာယ်
ဆရာသည် AI ပေးသော data များကို မိမိ၏ အသိဉာဏ် (Wisdom) နှင့် ပေါင်းစပ်ခြင်း မပြုတော့လျှင် ပညာသင်ကြားရေးသည် "အသိပညာ ရှာမှီးခြင်း" မဟုတ်တော့ဘဲ "အချက်အလက်များကို ကူးချခြင်း" (Data Processing) မျှသာ ဖြစ်သွားပါမည်။

ကိုယ်ပိုင်ပြဋ္ဌာန်းခွင့် (Autonomy) ပျောက်ဆုံးခြင်း
 လူသား၏ အဓိက စွမ်းအားမှာ "ရွေးချယ်ခြင်း" နှင့် "ဆုံးဖြတ်ခြင်း" ဖြစ်သည်။ ထိုစွမ်းအားကို စက်ကိရိယာထံ ပုံအပ်လိုက်ခြင်းသည် လူသားတို့၏ ကိုယ်ပိုင်ဉာဏ်ရည်ကို အသုံးမချတော့ဘဲ မိမိကိုယ်တိုင် ကျွန်ပြုခံရခြင်းတစ်မျိုးပင် ဖြစ်ပါသည်။

နိဂုံးချုပ် ဝေဖန်ချက်
AI သည် ဆရာတစ်ဦးအတွက် အလွန်ကောင်းမွန်သော "လက်ထောက်" (Assistant) ဖြစ်နိုင်သော်လည်း၊ "အစားထိုး" (Replacement) မဖြစ်သင့်ပါ။ ဆရာတစ်ဦးသည် AI က ထုတ်ပေးသော အရာများကို စစ်ထုတ်ခြင်း (Filter)၊ ပြင်ဆင်ခြင်း (Refine) နှင့် လူသားဆန်သော မေတ္တာ၊ အတွေ့အကြုံများဖြင့် ဖြည့်စွက်ခြင်း (Human Touch) တို့ကို မပျက်မကွက် ပြုလုပ်ရပါမည်။ ထိုသို့မဟုတ်ပါက နောင်အနာဂတ်တွင် ကျွန်ုပ်တို့၏ လူ့အဖွဲ့အစည်းသည် စဉ်းစားဆင်ခြင်ဉာဏ် ကင်းမဲ့ပြီး စက်ရုပ်များ ခိုင်းစေသမျှကိုသာ လုပ်ဆောင်တတ်သည့် "ဉာဏ်ပညာမဲ့ မျိုးဆက်သစ်များ" နှင့် ရင်ဆိုင်ရပါလိမ့်မည်။

Zebra Puzzle as CSP

နည်းသစ်ဉာဏ်ရည်တုပညာမိတ်ဆက်၊ အခန်း (၅)၊ ကန့်သတ်ချက်ပြေလည်စေရသော ပြဿနာများ၊ လေ့ကျင့်ခန်းများ (မေးခွန်း နှင့် အဖြေများ)၊ ပုစ္ဆာ အမှတ် ၅.၃၊ စာ-၂၆၀ ကိုကြည့်ပါ။ 

ဤပရိုဂရမ်အလုပ်လုပ်နိုင်စေရန် python-constraint package လိုအပ်ပါသည်။

Windows 11 ပေါ်ရှိ Spyder IDE တွင် python-constraint package ကို install လုပ်ရန် အလွယ်ကူဆုံး နည်းလမ်း။

နည်းလမ်း (၁) - Spyder အတွင်းမှ တိုက်ရိုက် Install ပြုလုပ်နည်း (အလွယ်ဆုံးနည်းလမ်း)

Spyder ဖွင့်ထားရင်းနဲ့ ပရိုဂရမ်အပြင်ထွက်စရာမလိုဘဲ Console ကနေ တိုက်ရိုက်သွင်းနိုင်ပါတယ်။

  1. Spyder ကို ဖွင့်ပါ။

  2. မျက်နှာပြင်ရဲ့ ညာဘက်အောက်ထောင့်နားမှာရှိတဲ့ IPython Console (အမည်းရောင် သို့မဟုတ် အဖြူရောင် စာရိုက်ကွက်) ကို ကြည့်ပါ။

  3. ထို Console တွင် အောက်ပါ Command ကို ရိုက်ထည့်ပြီး Enter ခေါက်ပါ။ (ရှေ့ဆုံးက ! သင်္ကေတ ပါရပါမယ်)

    !pip install python-constraint
    
  4. ကွန်ပျူတာက Internet ချိတ်ထားရင် download ဆွဲပြီး install လုပ်သွားပါလိမ့်မယ်။ Successfully installed python-constraint... ဆိုပြီး စာပေါ်လာရင် ရပါပြီ။


နည်းလမ်း (၂) - Anaconda Prompt မှတဆင့် Install ပြုလုပ်နည်း (ပိုမိုသေချာသောနည်းလမ်း)

ပထမနည်းလမ်းနဲ့ အဆင်မပြေရင် (သို့မဟုတ်) Error တက်နေရင် ဒီနည်းလမ်းကို သုံးပါ။

  1. ကွန်ပျူတာရဲ့ Start Menu (Windows Key) ကို နှိပ်ပါ။

  2. Search box မှာ "Anaconda Prompt" လို့ ရိုက်ရှာပြီး ဖွင့်လိုက်ပါ။ (အမည်းရောင် box ပေါ်လာပါမယ်)။

  3. အဲဒီ Box ထဲမှာ အောက်ပါစာကို ရိုက်ထည့်ပြီး Enter ခေါက်ပါ။

    pip install python-constraint
  4. Install လုပ်ပြီးသွားရင် Box ကို ပိတ်လိုက်ပြီး Spyder ကို ပြန်ဖွင့် (Restart) လိုက်ပါ။




Install ဖြစ်မဖြစ် စမ်းသပ်ခြင်း

Install လုပ်ပြီးသွားရင် သေချာမသေချာ စစ်ဆေးဖို့အတွက် Spyder မှာ အောက်ပါ ကုဒ်တိုလေးကို ရိုက်ပြီး Run ကြည့်လိုက်ပါ။

Python
import constraint
print("Installation Successful!")

Error မတက်ဘဲ "Installation Successful!" လို့ ပေါ်လာရင်တော့ python-constraint ကို စတင်အသုံးပြုပြီး မြင်းကျားပဟေဠိကို ဖြေရှင်းနိုင်ပါပြီ။


from constraint import *
def solve_zebra_puzzle():
    # ၁။ Knowledge Base အဖြစ် Problem ကို စတင်တည်ဆောက်ခြင်း
    problem = Problem()
    # ၂။ Variables (ကိန်းရှင်များ) သတ်မှတ်ခြင်း
    # အိမ်နံပါတ် ၁ မှ ၅ ထိ (Domain)
    houses = [1, 2, 3, 4, 5]
    # အရည်အသွေးများ (Attributes)
    nationalities = ["English", "Spaniard", "Irish", "Nigerian", "Japanese"]
    colors = ["Red", "Green", "Ivory", "Yellow", "Blue"]
    drinks = ["Coffee", "Tea", "Milk", "Orange Juice", "Water"]
    pets = ["Dog", "Snails", "Fox", "Horse", "Zebra"]
    sports = ["Cricket", "Go", "Judo", "Poker", "Polo"] # မူရင်းပဟေဠိ၏ ဆေးလိပ်အစား အားကစားဖြင့် အစားထိုးထားသည်
    all_variables = nationalities + colors + drinks + pets + sports
    # Variable တစ်ခုစီသည် အိမ်နံပါတ် ၁ မှ ၅ အတွင်းသာ ရှိရမည်
    problem.addVariables(all_variables, houses)
    # ၃။ Constraints (ကန့်သတ်ချက်များ) ထည့်သွင်းခြင်း
    
    # အိမ်တစ်အိမ်စီတွင် အရောင်၊ လူမျိုး၊ အချိုရည်၊ တိရစ္ဆာန်၊ အားကစား တစ်မျိုးစီသာ ရှိရမည် (AllDifferent)
    problem.addConstraint(AllDifferentConstraint(), nationalities)
    problem.addConstraint(AllDifferentConstraint(), colors)
    problem.addConstraint(AllDifferentConstraint(), drinks)
    problem.addConstraint(AllDifferentConstraint(), pets)
    problem.addConstraint(AllDifferentConstraint(), sports)
    # ပေးထားသော အချက်အလက်များ (Facts) ကို ထည့်သွင်းခြင်း
    # ၁။ အင်္ဂလိပ်လူမျိုးသည် အနီရောင်အိမ်တွင် နေထိုင်သည်။
    problem.addConstraint(lambda eng, red: eng == red, ("English", "Red"))
    # ၂။ စပိန်လူမျိုးသည် ခွေးတစ်ကောင် ပိုင်ဆိုင်သည်။
    problem.addConstraint(lambda span, dog: span == dog, ("Spaniard", "Dog"))
    # ၃။ အစိမ်းရောင်အိမ်ရှိ လူသည် ကော်ဖီ သောက်သည်။
    problem.addConstraint(lambda green, coffee: green == coffee, ("Green", "Coffee"))
    # ၄။ အိုင်းရစ်လူမျိုးသည် လက်ဖက်ရည် သောက်သည်။
    problem.addConstraint(lambda irish, tea: irish == tea, ("Irish", "Tea"))
    # ၅။ အစိမ်းရောင်အိမ်သည် ဆင်စွယ်ရောင်အိမ်၏ ညာဘက်တွင် တည်ရှိသည်။ (Green = Ivory + 1)
    problem.addConstraint(lambda green, ivory: green == ivory + 1, ("Green", "Ivory"))
    # ၆။ ဂိုး-GO ကစားသမားသည် ခရုများ ပိုင်ဆိုင်သည်။
    problem.addConstraint(lambda go, snails: go == snails, ("Go", "Snails"))
    # ၇။ အဝါရောင်အိမ်ရှိ လူသည် ကရစ်ကက် ကစားသည်။
    problem.addConstraint(lambda yellow, cricket: yellow == cricket, ("Yellow", "Cricket"))
    # ၈။ အလယ်အိမ် (တတိယအိမ်) တွင် နေထိုင်သူသည် နွားနို့ သောက်သည်။
    problem.addConstraint(lambda milk: milk == 3, ("Milk",))
    # ၉။ နိုင်ဂျီးရီးယားလူမျိုးသည် ပထမအိမ် (အိမ်နံပါတ် ၁) တွင် နေထိုင်သည်။
    problem.addConstraint(lambda nigerian: nigerian == 1, ("Nigerian",))
    # ၁၀။ ဂျူဒိုကစားသမားသည် မြေခွေးပိုင်ဆိုင်သူ၏ အိမ်ဘေးကပ်လျက် နေထိုင်သည်။ (Next to means abs(a-b) == 1)
    problem.addConstraint(lambda judo, fox: abs(judo - fox) == 1, ("Judo", "Fox"))
    # ၁၁။ ကရစ်ကတ်ကစားသမားသည် မြင်းပိုင်ဆိုင်သူ၏ အိမ်ဘေးကပ်လျက်တွင် နေထိုင်သည်။
    problem.addConstraint(lambda cricket, horse: abs(cricket - horse) == 1, ("Cricket", "Horse"))
    # ၁၂။ ပိုကာကစားသမားသည် လိမ္မော်ရည် သောက်သည်။
    problem.addConstraint(lambda poker, oj: poker == oj, ("Poker", "Orange Juice"))
    # ၁၃။ ဂျပန်လူမျိုးသည် ပိုလို ကစားသည်။
    problem.addConstraint(lambda japanese, polo: japanese == polo, ("Japanese", "Polo"))
    # ၁၄။ နိုင်ဂျီးရီးယားလူမျိုးသည် အပြာရောင်အိမ်၏ အိမ်ဘေးကပ်လျက်တွင် နေထိုင်သည်။
    problem.addConstraint(lambda nigerian, blue: abs(nigerian - blue) == 1, ("Nigerian", "Blue"))
    # ၄။ အဖြေရှာခြင်း (Get Solution)
    solutions = problem.getSolutions()
    # ၅။ ရလာသော အဖြေကို ရှင်းလင်းစွာ ဖော်ပြခြင်း
    if not solutions:
        print("No solution found!")
    else:
        # အဖြေတစ်ခုတည်းသာ ထွက်လေ့ရှိသည်
        sol = solutions[0] 
        print(f"{'House':<10} {'Color':<10} {'Nation':<12} {'Drink':<15} {'Sport':<12} {'Pet':<10}")
        print("-" * 70)
        
        # အိမ်နံပါတ် ၁ မှ ၅ အထိ Loop ပတ်ပြီး စီခြင်း
        for i in range(1, 6):
            # လက်ရှိအိမ်နံပါတ် i နှင့် ကိုက်ညီသော variable များကို ရှာခြင်း
            c = [k for k, v in sol.items() if v == i and k in colors][0]
            n = [k for k, v in sol.items() if v == i and k in nationalities][0]
            d = [k for k, v in sol.items() if v == i and k in drinks][0]
            s = [k for k, v in sol.items() if v == i and k in sports][0]
            p = [k for k, v in sol.items() if v == i and k in pets][0]
            
            print(f"{i:<10} {c:<10} {n:<12} {d:<15} {s:<12} {p:<10}")
        print("\n--- Final Answer ---")
        # Zebra နှင့် Water ရှာခြင်း
        zebra_owner = [k for k, v in sol.items() if k in nationalities and sol[k] == sol["Zebra"]][0]
        water_drinker = [k for k, v in sol.items() if k in nationalities and sol[k] == sol["Water"]][0] # Water is implied as the remaining drink
        
        print(f"Zebra lives in the house of the: {zebra_owner}")
        print(f"The person who drinks Water is the: {water_drinker}")
if __name__ == "__main__":
    solve_zebra_puzzle()