离散数学实验
/*1.对给出的任意一个命题公式(不超过四个命题变元),
* 使学生会利用编程软件表示出来,并且能够计算它在各组真值指派下所应有的真值,
* 画出其真值表。
* (1)﹁(﹁p∨q)∧q的真值表;
* (2)(p∨q)→﹁r的真值表;
*/
/*2.输入命题公式(p→﹁q)→r
*输出主析取范式、主合取范式
*输出成真赋值、成假赋值
*/
实现思路:先求出命题公式变元由000~111的真值储存在数组中,循环遍历输出真值表;当命题公式真值为1时对应的变元值为成真赋值,此时若对应变元值为0输出对应变元的非,否则直接输出变元与变元之间用合取联结词连接,公式与公式之间用析取联结词连接(此时为主析取范式);当命题公式真值为0时对应变元值为成假赋值,此时若对应变元值为0输出对应变元的非,否则直接输出,变元与变元之间用析取联结词连接,公式与公式间用合取联结词连接(此时为主合取范式)。
命题公式的计算用后缀表达式(逆波兰表达式)求解,后缀表达式用栈来存储。
在思考解决主析取范式、主合取范式时走了很多的弯路,后来经过很久才发现真值表与范式之间的联系,其实想通了写起来非常的顺畅。写完也非常的有成就感。
打印真值表代码运行结果:
主析取范式、主合取范式、成真赋值、成假赋值代码运行结果:
package experiment;
public class LogicalOperation {
int disjunction(int x,int y){//析取∨
if(x==1||y==1) {
return 1;
}
else return 0;
}
int conjunction(int x,int y) {//合取∧
if(x==y&&x==1) {
return 1;
}
else return 0;
}
int nagation(int x) {//否定
if(x==0) {
return 1;
}
else return 0;
}
int implication(int x,int y) {//蕴涵
if(x==1&&y==0) {
return 0;
}
else return 1;
}
int equivalence(int x,int y) {//等价
if(x==y) {
return 1;
}
else return 0;
}
}
NormalForm.java
包含求取真值表、主析取范式、主合取范式、成真赋值、成假赋值等的方法
package experiment;
public class NormalForm {
String form;
int count=0;
int count0=0;
int count1=0;
Proposition fo;
Translation tr;
NormalForm(String form){
this.form=form;
fo = new Proposition(form);
tr = new Translation(form);
tr.judge();
}
void calculate() {
int [] x=new int[4];
for(int i=0;i<2;i++) {
for(int j=0;j<2;j++) {
for(int k=0;k<2;k++) {
for(int l=0;l<2;l++) {
fo.va1[count]=i;
fo.va2[count]=j;
fo.va3[count]=k;
fo.va4[count]=l;
x[0]=i;
x[1]=j;
x[2]=k;
x[3]=l;
fo.truth[count]=tr.operate(x);
if(fo.truth[count]==0) {
count0++;
}
else
count1++;
count++;
}
}
}
}
}
void table() {
if(tr.judge()==2) {
System.out.println(tr.va[0]+" "+tr.va[1]+" "+tr.pfr);
for(int i=0;i<4;i++) {
System.out.println(fo.va1[i*4]+" "+fo.va2[i*4]+" "+fo.truth[i*4]);
}
}
if(tr.judge()==3) {
System.out.println(tr.va[0]+" "+tr.va[1]+" "+tr.va[2]+" "+tr.pfr);
for(int i=0;i<8;i++) {
System.out.println(fo.va1[i*2]+" "+fo.va2[i*2]+" "+fo.va3[i*2]+" "+fo.truth[i*2]);
}
}
if(tr.judge()==4) {
System.out.println(tr.va[0]+" "+tr.va[1]+" "+tr.va[2]+" "+tr.va[3]+" "+tr.pfr);
for(int i=0;i<16;i++) {
System.out.println(fo.va1[i]+" "+fo.va2[i]+" "+fo.va3[i]+" "+fo.va4[i]+" "+fo.truth[i]);
}
}
}
void pdnf() {
//this.calculate();
count1=count1/2;
count1--;
System.out.println("主析取范式为:");
for(int i=0;i<8;i++) {
if(fo.truth[i*2]==1) {
System.out.print("(");
if(fo.va1[i*2]==0) {
System.out.print("﹁"+tr.va[0]);
}
else {
System.out.print(tr.va[0]);
}
System.out.print("∧");
if(fo.va2[i*2]==0) {
System.out.print("﹁"+tr.va[1]);
}
else {
System.out.print(tr.va[1]);
}
System.out.print("∧");
if(fo.va3[i*2]==0) {
System.out.print("﹁"+tr.va[2]);
}
else {
System.out.print(tr.va[2]);
}
System.out.print(")");
if(count1>0) {
System.out.print("∨");
count1--;
}
}
}
System.out.println();
}
void pcnf() {
count0=count0/2;
count0--;
System.out.println("主合取范式为:");
for(int i=0;i<8;i++) {
if(fo.truth[i*2]==0) {
System.out.print("(");
if(fo.va1[i*2]==0) {
System.out.print("﹁"+tr.va[0]);
}
else {
System.out.print(tr.va[0]);
}
System.out.print("∨");
if(fo.va2[i*2]==0) {
System.out.print("﹁"+tr.va[1]);
}
else {
System.out.print(tr.va[1]);
}
System.out.print("∨");
if(fo.va3[i*2]==0) {
System.out.print("﹁"+tr.va[2]);
}
else {
System.out.print(tr.va[2]);
}
System.out.print(")");
if(count0>0) {
System.out.print("∧");
count0--;
}
}
}
System.out.println();
}
void comeTrue() {
System.out.println("成真赋值为:");
for(int i=0;i<8;i++) {
if(fo.truth[i*2]==1) {
System.out.print(fo.va1[i*2]+" "+fo.va2[i*2]+" "+fo.va3[i*2]);
System.out.print(" ");
}
}
System.out.println();
}
void aFalse() {
System.out.println("成假赋值为:");
for(int i=0;i<8;i++) {
if(fo.truth[i*2]==0) {
System.out.print(fo.va1[i*2]+" "+fo.va2[i*2]+" "+fo.va3[i*2]);
System.out.print(" ");
}
}
System.out.println();
}
}
Translation.java
包含命题公式后缀表达式的转换和求解,变元个数的判断
package experiment;
public class Translation {
String pfr;
char[] op;//命题公式
char[] op1;//后缀表达式
char[] op2;//符号,中间数组
char[] va=new char[4];//变量储存
int[] variable=new int[4];
int count1=-1;//op1计数器
int count2=-1;//op2计数器
int count3=0;//va计数器
int x1,x2,x3,x;//x储存表达式的值
LogicalOperation lg = new LogicalOperation();
Translation(String pfr){
this.pfr=pfr;
op=pfr.toCharArray();
op1=new char[op.length];
op2=new char[op.length];
for(int i=0;i<op.length;i++) {//转化为后缀表达式,遍历op数组;
if(op[i]>='a'&&op[i]<='z') {
count1++;
op1[count1]=op[i];
}
else if(op[i]=='(') {
count2++;
op2[count2]=op[i];
}
else if(op[i]=='﹁') {
if(count2==-1||op2[count2]=='∨'||op2[count2]=='∧'||op2[count2]=='→'||op2[count2]=='↔'||op2[count2]=='(') {
count2++;
op2[count2]=op[i];
}
else if(op2[count2]=='﹁') {
count1++;
op1[count1]='﹁';
}
}
else if(op[i]=='∨'||op[i]=='∧'||op[i]=='→'||op[i]=='↔') {
if(count2==-1||op2[count2]=='(') {
count2++;
op2[count2]=op[i];
}
else if(op2[count2]=='∨'||op2[count2]=='∧'||op2[count2]=='→'||op2[count2]=='﹁'||op2[count2]=='↔') {
count1++;
op1[count1]=op2[count2];
op2[count2]=op[i];
}
}
else if(op[i]==')') {
while(op2[count2]!='(') {
count1++;
op1[count1]=op2[count2];
count2--;
}
count2--;
}
}//循环结束
while(count2>=0) {
count1++;
op1[count1]=op2[count2];
count2--;
}//后缀表达式完成
}
int judge() {//判断变量个数
va[0]=op1[0];
for(int i=1;i<=count1;i++) {
if(op1[i]>='a'&&op1[i]<='z') {
if(op1[i]!=va[0]&&op1[i]!=va[1]&&op1[i]!=va[2]) {
if(va[1]==0) {
va[1]=op1[i];
count3=2;
}
else if(va[2]==0) {
va[2]=op1[i];
count3=3;
}
else {
va[3]=op1[i];
count3=4;
}
}
}
}
return count3;
}
int operate(int []xi) {
int num=-1;
for(int i=0;i<=count1;i++) {
if(op1[i]>='a'&&op1[i]<='z') {
if(op1[i]==va[0]) {
num++;
variable[num]=xi[0];
}
else if(op1[i]==va[1]) {
num++;
variable[num]=xi[1];
}
else if(op1[i]==va[2]) {
num++;
variable[num]=xi[2];
}
else if(op1[i]==va[3]) {
num++;
variable[num]=xi[3];
}
}
else if(op1[i]=='﹁') {
variable[num]=lg.nagation(variable[num]);
}
else if(op1[i]=='∨') {
variable[num-1]=lg.disjunction(variable[num-1], variable[num]);
num--;
}
else if(op1[i]=='∧') {
variable[num-1]=lg.conjunction(variable[num-1], variable[num]);
num--;
}
else if(op1[i]=='→') {
variable[num-1]=lg.implication(variable[num-1], variable[num]);
num--;
}
else if(op1[i]=='↔') {
variable[num-1]=lg.equivalence(variable[num-1], variable[num]);
num--;
}
}
return variable[num];
}
}
Proposition.java
命题公式类,包含命题公式所具有的成员变量
package experiment;
public class Proposition {
String formula;
int[] va1 = new int[16];
int[] va2 = new int[16];
int[] va3 = new int[16];
int[] va4 = new int[16];
int[] truth = new int[16];
Proposition(String formula) {
this.formula=formula;
}
}
experiment2.java
求真值表执行类
package experiment;
import java.util.*;
/*2.对给出的任意一个命题公式(不超过四个命题变元),
* 使学生会利用编程软件表示出来,并且能够计算它在各组真值指派下所应有的真值,
* 画出其真值表。
* (1)﹁(﹁p∨q)∧q的真值表;
* (2)(p∨q)→﹁r的真值表;
*/
public class experiment2 {
public static void main(String[] args) {
// TODO 自动生成的方法存根
Scanner scanf=new Scanner(System.in);
int[] w=new int[4];
System.out.println("输入命题公式(不超过四个命题变元):");
System.out.println("非为‘﹁’,析取为‘∨’,合取为‘∧’蕴涵为‘→’,等价为‘↔’");
String prf = scanf.nextLine();
NormalForm form = new NormalForm(prf);
form.calculate();
form.table();
}
}
experiment3.java
求主析取范式主合取范式、成真赋值、成假赋值执行类
package experiment;
import java.util.*;
public class experiment3 {
public static void main(String[] args) {
/*输入命题公式(p→﹁q)→r
*输出主析取范式、主合取范式
*输出成真赋值、成假赋值
* 非为‘﹁’,析取为‘∨’,合取为‘∧’蕴涵为‘→’,等价为‘↔’*/
String form;
Scanner scanf = new Scanner(System.in);
System.out.println("请输入命题公式:(非为‘﹁’,析取为‘∨’,合取为‘∧’蕴涵为‘→’,等价为‘↔’)");
form = scanf.nextLine();
NormalForm normal = new NormalForm(form);
normal.calculate();
normal.pdnf();
normal.pcnf();
normal.comeTrue();
normal.aFalse();
}
}