แปลงการแสดงออกเชิงตรรกะเพื่อรูปแบบปกติซึ่งเชื่อมต่อกัน


10

เป้าหมาย:

เขียนโปรแกรมหรือฟังก์ชั่นที่สมบูรณ์ซึ่งใช้สูตรในตรรกะเชิงประพจน์ (ต่อจากนี้ไปจะเรียกว่าการแสดงออกเชิงตรรกะหรือการแสดงออก ) และผลลัพธ์สูตรนั้นในรูปแบบปกติซึ่งเชื่อมต่อกัน มีสองคงอยู่และเป็นตัวแทนของความจริงและเท็จผู้ประกอบการเอกภาค¬เป็นตัวแทนของการปฏิเสธและผู้ประกอบการไบนารี, , และตัวแทนปริยายสมมูลร่วมและความร้าวฉานตามลำดับซึ่งเชื่อฟังทั้งหมดของตรรกะการดำเนินงานปกติ ( กฎหมาย DeMorgan ของ , คู่ปฏิเสธการกำจัดฯลฯ )

รูปแบบปกติร่วมกันกำหนดไว้ดังนี้

  1. นิพจน์อะตอมใด ๆ (รวมถึงและ) อยู่ในรูปแบบปกติซึ่งเชื่อมต่อกัน
  2. การปฏิเสธของการแสดงออกใด ๆ ที่สร้างไว้ก่อนหน้านี้อยู่ในรูปแบบปกติซึ่งเชื่อมต่อกัน
  3. ความแตกต่างของสองนิพจน์ที่สร้างไว้ก่อนหน้านี้อยู่ในรูปแบบปกติซึ่งเชื่อมต่อกัน
  4. การรวมกันของสองนิพจน์ที่สร้างไว้ก่อนหน้านี้อยู่ในรูปแบบปกติซึ่งเชื่อมต่อกัน
  5. การแสดงออกอื่น ๆ ไม่ได้อยู่ในรูปแบบปกติของการเชื่อมต่อ

นิพจน์แบบลอจิคัลใด ๆ สามารถแปลง (ไม่ใช่แบบไม่ซ้ำกัน) ให้เป็นนิพจน์ที่มีเหตุผลเชิงตรรกะในรูปแบบปกติแบบ conjunctive (ดูอัลกอริทึมนี้ ) คุณไม่จำเป็นต้องใช้อัลกอริทึมนั้น

การป้อนข้อมูล:

คุณสามารถป้อนข้อมูลในรูปแบบที่สะดวกใด ๆ เช่นการแสดงออกเชิงตรรกะสัญลักษณ์ (ถ้าภาษาของคุณรองรับ), สตริง, โครงสร้างข้อมูลอื่น ๆ คุณไม่จำเป็นต้องใช้สัญลักษณ์เดียวกันสำหรับตัวดำเนินการจริงเท็จและตัวดำเนินการทางตรรกะเช่นเดียวกับที่นี่ แต่ตัวเลือกของคุณควรสอดคล้องกันและคุณควรอธิบายตัวเลือกของคุณในคำตอบหากยังไม่ชัดเจน คุณไม่สามารถยอมรับอินพุตอื่นหรือเข้ารหัสข้อมูลเพิ่มเติมใด ๆ ในรูปแบบอินพุตของคุณ คุณควรมีวิธีแสดงจำนวนอะตอมนิพจน์จำนวนหนึ่งโดยพลการ เช่นจำนวนเต็มอักขระสตริง ฯลฯ

เอาท์พุท:

สูตรในรูปแบบปกติซึ่งเชื่อมต่ออีกครั้งในรูปแบบที่สะดวก ไม่จำเป็นต้องอยู่ในรูปแบบเดียวกับอินพุตของคุณ แต่คุณควรอธิบายหากมีความแตกต่างใด ๆ

กรณีทดสอบ:

P ∧ (P ⇒ R) -> P ∧ R
P ⇔ (¬ P) -> ⊥
(¬ P) ∨ (Q ⇔ (P ∧ R)) -> ((¬ P) ∨ ((¬ Q) ∨ R)) ∧ ((¬ P) ∨ (Q ∨ (¬ R)))

หมายเหตุ:

  1. หากการแสดงออกของการป้อนข้อมูลเป็นซ้ำซาก จะเป็นผลลัพธ์ที่ถูกต้อง ในทำนองเดียวกันถ้าการแสดงออกของการป้อนข้อมูลเป็นความขัดแย้งจะเป็นผลลัพธ์ที่ถูกต้อง
  2. ทั้งรูปแบบอินพุตและเอาต์พุตของคุณควรมีลำดับของการดำเนินการที่ชัดเจนซึ่งสามารถแสดงนิพจน์เชิงตรรกะที่เป็นไปได้ทั้งหมด คุณอาจต้องการวงเล็บในบางประเภท
  3. คุณสามารถใช้สัญกรณ์ของ infix, prefix หรือ postfix ที่กำหนดไว้อย่างดีสำหรับการดำเนินการทางตรรกะ หากตัวเลือกของคุณแตกต่างจากมาตรฐาน (การปฏิเสธคือส่วนนำหน้าส่วนที่เหลือเป็นมัด) โปรดอธิบายว่าในคำตอบของคุณ
  4. รูปแบบปกติของรอยต่อนั้นไม่ซ้ำกันโดยทั่วไป (แม้จะไม่เรียงลำดับใหม่) คุณต้องการเพียงเพื่อส่งออกฟอร์มที่ถูกต้องเท่านั้น
  5. อย่างไรก็ตามคุณเป็นตัวแทนของการแสดงออกของอะตอมพวกเขาจะต้องแตกต่างจากค่าคงที่ตรรกะผู้ประกอบการและสัญลักษณ์การจัดกลุ่ม (ถ้าคุณมีพวกเขา)
  6. บิวด์อินที่อนุญาตให้ใช้รูปแบบปกติที่เชื่อมต่อกันได้
  7. ช่องโหว่มาตรฐานเป็นสิ่งต้องห้าม
  8. นี่คือ ; คำตอบที่สั้นที่สุด (เป็นไบต์) ชนะ


1
CNF นั้นไม่ซ้ำกันในการจัดลำดับใหม่: นิพจน์ที่เทียบเท่าPและ(P ∨ Q) ∧ (P ∨ (¬Q))อยู่ในรูปแบบปกติซึ่งเชื่อมต่อกัน
Greg Martin

1
การตรวจสอบซ้ำซาก / ขัดแย้งเป็นงานที่สองที่ไม่เกี่ยวข้องกับการเปลี่ยนแปลงของ CNF ดังนั้นฉันขอแนะนำให้ทิ้งข้อกำหนดนี้และนำไปสู่ความท้าทายของตัวเอง
Laikoni

@Laikoni จริงมาก ฉันอัปเดตคำถามเพื่อบอกว่าสิ่งเหล่านี้เป็นผลลัพธ์ที่เป็นไปได้สำหรับการพูดซ้ำซากและความขัดแย้งมากกว่าผลที่ต้องการ
ngenisis

คำตอบ:



8

คุณจะเกลียดฉัน ....

Mathematica ขนาด 23 ไบต์

#~BooleanConvert~"CNF"&

การป้อนข้อมูลที่จะใช้TrueและFalseแทนและแต่อย่างอื่นจะมีลักษณะคล้ายกันมากกับสัญกรณ์ของคำถาม: ทุกตัวอักษร¬, , , และได้รับการยอมรับใน Mathematica (เมื่อป้อนข้อมูลด้วยอักขระ UTF-8 00AC, F523, 29E6, 2227 และ 2228 ตามลำดับ) และวงเล็บทำตามที่คุณคาดหวัง

โดยค่าเริ่มต้นออกจะใช้สัญลักษณ์ที่ต้องการ Mathematica ของ: ยกตัวอย่างเช่นการทดสอบที่ผ่านมากรณีที่ออกจะแทน(! P || ! Q || R) && (! P || Q || ! R) ((¬ P) ∨ ((¬ Q) ∨ R)) ∧ ((¬ P) ∨ (Q ∨ (¬ R)))อย่างไรก็ตามการเปลี่ยนฟังก์ชั่นเป็น

TraditionalForm[#~BooleanConvert~"CNF"]&

จะทำให้เอาต์พุตดูสวยและสอดคล้องกับสัญลักษณ์ปกติเหล่านี้:

รูปแบบดั้งเดิม


2

JavaScript (ES6), 127 ไบต์

f=(s,t='',p=s.match(/[A-Z]/),r=RegExp(p,'g'))=>p?'('+f(s.replace(r,1),t+'|'+p)+')&('+f(s.replace(r,0),t+'|!'+p)+')':eval(s)?1:0+t

รูปแบบ I / O มีดังต่อไปนี้ (ตามลำดับความสำคัญ):

  • (: (
  • ): )
  • : 1
  • : 0
  • ¬: !
  • : <=
  • : ==
  • : &
  • : |

ตัวอย่าง:

P&(P<=R) -> ((1)&(0|P|!R))&((0|!P|R)&(0|!P|!R))
P==(!P) -> (0|P)&(0|!P)
(!P)|(Q==(P&R)) -> (((1)&(0|P|Q|!R))&((0|P|!Q|R)&(1)))&(((1)&(1))&((1)&(1)))

ฟังก์ชั่นถูกเขียนใหม่เพื่อสร้างรูปแบบปกติที่ไม่ต่อเนื่อง:

f=(s,t='',p=s.match(/[A-Z]/),r=RegExp(p,'g'))=>p?'('f(s.replace(r,1),t+'&'+p)+')|('+f(s.replace(r,0),t+'&!'+p)+')':eval(s)?1+t:0

8 ไบต์สามารถบันทึกได้จากรุ่นนี้หากฉันได้รับอนุญาตให้ถือว่าลำดับความสำคัญข้างต้นเป็นผลลัพธ์เช่นกันซึ่งจะลบวงเล็บทั้งหมดออกจากตัวอย่างผลลัพธ์:

P&(P<=R) -> ((1&P&R)|(0))|((0)|(0))
P==(!P) -> (0)|(0)
(!P)|(Q==(P&R)) -> (((1&P&Q&R)|(0))|((0)|(1&P&!Q&!R)))|(((1&!P&Q&R)|(1&!P&Q&!R))|((1&!P&!Q&R)|(1&!P&!Q&!R)))
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.