离散数学主析取范式主合取范式.docx
《离散数学主析取范式主合取范式.docx》由会员分享,可在线阅读,更多相关《离散数学主析取范式主合取范式.docx(15页珍藏版)》请在冰豆网上搜索。
离散数学主析取范式主合取范式
实验二
实验题目:
生成主析取范式和主合取范式
实验目的:
1.熟悉地掌握计算机科学技术常用的离散数学中的概念、性质和运算;通过实验提高学生编写实验报告、总结实验结果的能力;使学生具备程序设计的思想,能够独立完成简单的算法设计和分析。
2.掌握命题逻辑中的联接词、真值表、主范式等,进一步能用它们来解决实际问题。
实验内容:
利用计算机构造真值表来建立主析取范式和主合取范式
实验原理:
1.合取:
二元命题联结词。
将两个命题P、Q联结起来,构成一个新的命题P∧Q。
这个新命题的真值与构成它的命题P、Q的真值间的关系为只有当两个命题变项P为真,Q为真时方可P∧Q为真,而P、Q只要有一为假则P∧Q为假。
2.析取:
二元命题联结词。
将两个命题P、Q联结起来,构成一个新的命题P∨Q。
这个新命题的真值与构成它的命题P、Q的真值间的关系为只有当两个命题变项P为假,Q为假时方可P∨Q为假,而P、Q只要有一为真则P∨Q为真。
3.真值表:
表征逻辑事件输入和输出之间全部可能状态的表格。
列出命题公式真假值的表。
通常以1表示真,0表示假。
命题公式的取值由组成命题公式的命题变元的取值和命题联结词决定,命题联结词的真值表给出了真假值的算法。
真值表是在逻辑中使用的一类数学表,用来确定一个表达式是否为真或有效。
4.主析取范式:
在含有n个命题变元的简单合取式中,若每个命题变元与其否定不同时存在,而两者之一出现一次且仅出现一次,称该简单合取式为小项。
由若干个不同的小项组成的析取式称为主析取范式;与A等价的主析取范式称为A的主析取范式。
任意含n个命题变元的非永假命题公式A都存在与其等价的主析取范式,并且是惟一的。
5.主合取范式:
在含有n个命题变元的简单析取式中,若每个命题变元与其否定不同时存在,而两者之一出现一次且仅出现一次,称该简单析取式为大项。
由若干个不同的大项组成的合取式称为主合取范式;与A等价的主合取范式称为A的主合取范式。
任意含n个命题变元的非永真命题公式A都存在与其等价的主合取范式,并且是惟一的。
实验结果与分析:
实验结果:
实验分析:
参考前面实验的代码,生成真值表,然后找出所有值为1时,各变元的取值,从而生成相应的小项,最终得到主析取范式。
找出值为0时各个变元的取值,从而生成相应的大项,最终得到主合取范式。
附:
程序源代码:
3
functiongetTrueTable()
{
vartext=document.getElementById('text').value;
alert("输入的公式:
"+text);
varvarList="";
vari=0;
varn=text.length;
varvalue="";
varcode=0;
varaddList="";
vardecList="";
for(i=0;i{
code=text.charCodeAt(i);
if((code>=97)&&(code<123))
{
x=text.substr(i,1);
if(varList.indexOf(x)<0)
{
if(varList.length==0)
{varList=x;}
else
{varList+=","+x;}
}
}
}
alert("公式中字母列表:
"+varList);
vararrList=varList.split(",");
varn=arrList.length;
vartable="";
vart="
";for(i=0;i{
t+="
"+arrList[i]+" | ";
}
t+="
"+text+" | ";t+="
真值 | ";t+="
";
table+=t;
varm=1;
vartrow=newArray(n+1);
for(i=0;i{
m*=2;
trow[i]=0;
}
varj=0;
varflag=0;
vark=0;
vars="";
for(i=0;i{
t="
";value=text;
for(j=0;j{
x=arrList[j];
for(k=0;k{
if(value.substr(k,1)==x)
{value=value.substr(0,k)+trow[j]+value.substr(k+1);}
}
t+="
"+trow[j]+" | ";
}
t+="
"+value+" | ";
t+="
"+calcValue(value)+" | ";t+="
";
table+=t;
if(calcValue(value)==1)
{
s="";
for(j=0;j{
x=arrList[j];
if(trow[j]==1)
{
if(s=="")
{
s=x;
}
else
{
s+="^"+x;
}
}
else
{
if(s=="")
{
s="!
"+x;
}
else
{
s+="^"+"!
"+x;
}
}
}
if(addList=="")
{
addList="("+s+")";
}
else
{
addList+="+"+"("+s+")";
}
}
else
{
s="";
for(j=0;j{
x=arrList[j];
if(trow[j]==0)
{
if(s=="")
{
s=x;
}
else
{
s+="+"+x;
}
}
else
{
if(s=="")
{
s="!
"+x;
}
else
{
s+="+"+"!
"+x;
}
}
}
if(decList=="")
{
decList="("+s+")";
}
else
{
decList+="^"+"("+s+")";
}
}
flag=1;
for(j=n-1;j>-1;j--)
{
flag=flag+trow[j];
if(flag==2)
{
trow[j]=0;
flag=1;
}
else
{
trow[j]=1;
break;
}
}
}
table+="";
table+="
主析取范式是:
"+addList;
table+="
主合取范式是:
"+decList;
document.getElementById('disp').innerHTML=table;
}
functioncalcValue(Value)
{
//计算真值表的值
//方法:
//第一:
计算括号内的值
//1.从左到右遍历,记录新找到的左括号(的位置
//2.若新出现的字符是右括号),则说明这对括号是最内层括号,
//将这对括号的内容发送给计算函数,求出其值,再将该括号内换成新值
//3.再从原来左括号(起,向右寻找.)
varnlp=Value.indexOf("(");
vari=nlp+1;
varnrp=Value.length;
varx="";//第k个字符
varv="";//某个中间公式的值
while(nlp>=0)
{
x=Value.substr(i,1);
if(x=="(")
{
//如果是左括号则将其记下来
nlp=i;
i=i+1;//考虑下一个字符
}
else
{
//如果不是左括号,则判断是否为右括号
if(x==")")
{
//第一个右括号之前的最后一个左括号的内容应该没有括号了
//调用无括号的计算函数calcValueNoP()计算其值
nrp=i;
//alert("去括号前:
"+Value);
v=calcValueNoP(Value.substr(nlp+1,nrp-nlp-1));
//起止范围的公式
Value=(nlp>0?
Value.substr(0,nlp):
"")+v+
((nrp+1)<=Value.length?
Value.substr(nrp+1):
"");
//用值替换
//重新找第一个左括号
nlp=Value.indexOf("(");
//测出左括号的起位
i=nlp+1;
}
else
{
//不是右括号,则为普通的字符,直接看下一个字符
i=i+1;
}
}
//alert(i+","+Value.length);
if(i>=Value.length)
{
//超出字符串的长度
nlp=Value.indexOf("(");
//测出左括号的起位
i=nlp+1;
}
}
//经过这轮循环后,应该没有左右括号
returncalcValueNoP(Value);
XX文库-让每个人平等地提升自我}
functioncalcValueNoP(Value)
{
//先算否定
varnnot=Value.indexOf("!
");
//第一个合取符号的位置
while(nnot>=0)
{
//这个符号可能在第0个位置
//!
符号后一个是运算数,
//alert("否定以前的值:
"+Value);
Value=(nnot>0?
Value.substr(0,nnot):
"")+
caclNot(Value.substr(nnot+1,1))+
((nnot+2)<=Value.length?
Value.substr(nnot+2):
"");
//alert("否定以后的值:
"+Value);
nnot=Value.indexOf("!
");
}
//先算合取
varnand=Value.indexOf("^");
//第一个合取符号的位置
while(nand>0)
{
//这个符号不可能在第0个位置,肯定大于0
//^符号前一个是运算数,
//alert("合取前的值:
"+Value);
Value=((nand-1)>0?
Value.substr(0,nand-1):
"")+
caclAnd(Value.substr(nand-1,1),Value.substr(nand+1,1))+
((nand+2)<=Value.length?
Value.substr(nand+2):
"");
//alert("合取后的值:
"+Value);
nand=Value.indexOf("^");
}
//再算析取
varnOr=Value.indexOf("+");
//第一个合取符号的位置
while(nOr>0)
{
//这个符号不可能在第0个位置,肯定大于0
//^符号前一个是运算数,
Value=((nOr-1)>0?
Value.substr(0,nOr-1):
"")+
caclOr(Value.substr(nOr-1,1),Value.substr(nOr+1,1))+
((nOr+2)<=Value.length?
Value.substr(nOr+2):
"");
//alert("求析取后的值:
"+Value);
nOr=Value.indexOf("+");
}
returnValue;
}
functioncaclAnd(x,y)
{
if((x=="1")&&(y=="1"))
{
return1;
}
else
{
return0;
}
}
functioncaclOr(x,y)
{
if((x=="0")&&(y=="0"))
{
return0;
}
else
{
return1;
}
}
functioncaclNot(x)
{
if(x=="1")
{
return0;
}
else
{
return1;
}
}
生成一个公式主析取、主合取范式
基本方法:
生成一个公式的真值表,并且将各变元的值保留下来
公式一: