/* Copyright (C) Stephen Lee 2008 .
* Email:stephen@tachyos.org
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
package godel;
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import javax.swing.*;
import javax.swing.plaf.basic.BasicArrowButton;
import java.awt.datatransfer.*;
import java.math.*;
/**This is an applet to implement a numerical encoding of arithmetical proofs.
* Such an encoding is required in the proof of Gödel's incompleteness theorem.
* It uses the axiom system describes in A proof system for arithmetic
* For further information see Gödel numbering applet
* @author Stephen Lee */
public class Godel2 extends Applet implements ActionListener,MouseListener {
private static final long serialVersionUID = 1L;
//Representation of an expression as a BigInteger always includes an extra leaing bit.
public Godel2(){}
Font cf1;
/** Text area for Godel number of proof */
JTextArea prnum=new JTextArea();
/** Text area for Godel numbers of lines of proof */
JTextArea plines=new JTextArea();
//Label lab1=new Label();
/** Set when end of proof number reached */
boolean endflg;
/** Press button to generate proof lines from proof number */
BasicArrowButton but2 =new BasicArrowButton(SwingConstants.SOUTH);
final BigInteger THREE=BigInteger.valueOf(3);
final BigInteger FOUR=BigInteger.valueOf(4);
//final BigInteger LARGE=new BigInteger("9444732965739290427391");
/**Stack of bound variables
* vstack,vlist,vsp and vlp are not currently used*/
int[] vstack=new int[20];
/** List of bound variables relevant to current term*/
int[] vlist=new int[44];
/** Stack pointer for vstack */
int vsp;
/** Count for vlist */
int vlp;
/** int form of variable in Ax4 or Ind axioms
* Will be replaced by Termx*/
long varep;
/** replacement term for varep */
BigInteger Termx;
/** Godel numbers of integer axioms */
BigInteger[] IntAx={new BigInteger("57459223650"),
new BigInteger("205311074"),new BigInteger("6545"),
new BigInteger("207818546"),new BigInteger("12756"),
new BigInteger("833340372"),new BigInteger("2524"),
new BigInteger("7276970972")};
/** Store for Godel numbers of lines of proof */
BigInteger line[]=new BigInteger[200];
/** Current line number for lines of proof */
int curlin;
/** Holds Gödel number of proof (bitstream)*/
BigInteger Proofin;
/** Holds bitstream number to be parsed */
BigInteger Source;
/** */
JCheckBox binar=new JCheckBox("binary",false);
/** Radix for proof number input (10 or 2)*/
int radx=10;
/** respond to down button or change of proof number radix */
public void actionPerformed(ActionEvent e) {
String ac=e.getActionCommand();
try{
if (ac=="down"){
plines.setText("");
// Proofin=new BigInteger("11100001001101011000111101000100111000000000111100000100111010000000111011011110000000101101100100101110101100101100000100101110101100100010110010111011100001011011000001100011111001000001110010000001110110111100000001011011110001011000110001000100101110101111001011010100001101111100010000111010001111010010110100000011000101001111010000001100010100111100000000111010100011101100101110111000001100000101100101110100100010010111010111100001011011010110001111100101011100110001111011000001100011000111110001011001011101110010110010001101111100100011011111000110110010010011111000101101001000111100001100100101110101100110000010010111010010001011110000101100001011000111111010011101100100111100001111001100110001100010001001011101110010001011101111110010111010101001111000111010100001011110010010111100011111100001110100010011110000011010111100001100110100,00111000010110000011100011111101000110110000011110001101010111100001111010100001011110010110001101010111100001111010100001011110010011011101111100010011100100001111010100110110001111000110001101100000011110000011010000001111011000001101100011000110000101111110111010001111010110000011010110001011000110001011011010010000111101011111001001011001111100111010100111101011000110100011101010010110110100101100011101011111100001010001111000111000000111101011000001101000111010100101100000111010100101101100001011011100011111011100001111010110000011010110001011000110001000111010111001000011110111",2);
Proofin=new BigInteger(prnum.getText(),radx);
proves();
/*for (int i=1;i0){
BigInteger pc=new BigInteger(prtxt ,radx);
prnum.setText(pc.toString(12-radx));}}
finally {radx=12-radx;}
} catch (Error ii){JOptionPane.showMessageDialog(null, "Input not valid");}
}
/** Paste into upper (proof number) text area on right mouse click */
public void mouseClicked(MouseEvent me) {
try{
if (me.getButton()==MouseEvent.BUTTON3)
prnum.setText((String)Toolkit.getDefaultToolkit().getSystemClipboard().getContents(null).getTransferData(
DataFlavor.stringFlavor));
}catch(Exception e){}
}
public void mouseEntered(MouseEvent arg0) {}
public void mouseExited(MouseEvent arg0) {}
public void mousePressed(MouseEvent arg0) {}
public void mouseReleased(MouseEvent arg0) {}
/** Set up applet */
public void init() {
setLayout(null);
setBackground(new Color(230,240,240));
cf1=new Font("Lucida Sans Unicode",Font.PLAIN,14);
cf1=new Font("",Font.PLAIN,14);
// add(plines);
// plines.setBounds(10,10,200,20);
add(but2);
but2.setBounds(60,275,40,20);
JScrollPane scroll1 = new JScrollPane(prnum);
add(scroll1);
JScrollPane scroll2 = new JScrollPane(plines);
add(scroll2);
prnum.setFont(cf1);
scroll1.setBounds(10,20,600,250);
scroll2.setBounds(10,300,600,250);
add(binar);
binar.setBounds(10, 5, 60, 15);
binar.addActionListener(this);
prnum.setLineWrap(true);
but2.addActionListener(this);
but2.getModel().setActionCommand("down");
//add(lab1);
//lab1.setBounds(110,275,240,20);
prnum.addMouseListener(this);
}
/** get 2 bits from bitstream */
int get2(){
endflg=(Source.signum()==0);
int result=Source.and(THREE).intValue();
Source=Source.shiftRight(2);
return result;
}
/*int get4(){
int result=Source.and(THREE).intValue();
Source=Source.shiftRight(4);
return result;
}*/
/** Get int from bitstream */
long getint(){
long n,res=0;
do {n=get2(); if (n<3)res=3*res+n+1;}while (n<3&&!endflg);
return res;
}
/** Gets variable from input bitstream
* @param stk - set if variable is to be put on stack
* @return bitstream form of variable
*/
BigInteger Sgetvar(boolean stk){
int varg=(int)getint();
if (stk) {vstack[vsp++]=varg;}
if (varg==varep){
for (int i=0;i=4){op=2*op-7;shft=3;}
else shft=2;
return X1.shiftLeft(shft).add(BigInteger.valueOf(op));
}
/** Encodes the result of a binary operator
* @param X1 first term or formula
* @param op code for operator
* @param X2 second term or formula
* @return code for operator result
*/
BigInteger Binop(BigInteger X1,int op,BigInteger X2){
int n2=X1.bitLength();
BigInteger t=X2.shiftLeft(n2-1).add(X1.clearBit(n2-1));
return Unop(op,t);
}
/** gets a term from the proof bitstream
* @return encoded form of term
*/
BigInteger Sterm(){
boolean isvar=!Source.testBit(0);
Source=Source.shiftRight(1);
if (isvar)return Sgetvar(false);
else switch (get2()){
case 0:return BigInteger.valueOf(9);
case 1:return Unop(5,Sterm());
case 2:return Binop(Sterm(),6,Sterm());
default:return Binop(Sterm(),7,Sterm());}
}
/**Gets a formula from the proof bitstream
* @return encoded form of formula
*/
BigInteger Swff(){BigInteger T1;
switch (get2()){
case 0: return Binop(Sterm(),0,Sterm());
case 1: return Unop(1,Swff());
case 2:return Binop(Swff(),2,Swff());
default: { T1=Binop(Sgetvar(true),3,Swff());vsp--;return T1;}
}
}
/** Gets low order bits of a number
* @param x Input number
* @param n Number of bits
* @return Low order n bits of x
*/
BigInteger LowOrder(BigInteger x,int n){
return x.and(BigInteger.ONE.shiftLeft(n).subtract(BigInteger.ONE));
}
/**Converts int form of a variable bitstream form.
* The terminator is included,
* but the starting 3 must be added separately if needed.
* @param V Variable in int form
* @return Variable coded as a BigInteger
*/
BigInteger Varb(long V){
long n=V;
BigInteger Num=BigInteger.valueOf(7);
while (n>0){n--;
Num=Num.multiply(FOUR).add(BigInteger.valueOf(n%3));
n/=3;}
return Num;
}
/** Gets previously established formula from line number
* 1st bit 1 -> next 4 bits define number of axiom
* 1st bit 0 -> encoded line number of proof follows
* @return encoded form of formula
*/
BigInteger Glin(){
int l;
boolean isax=Source.testBit(0);
Source=Source.shiftRight(1);
if (isax){
l=Source.and(BigInteger.valueOf(15)).intValue();
Source=Source.shiftRight(4);
return IntAx[l-1];}
else return line[(int)getint()];
}
/** Axiom 1: WF1⇒(WF2⇒WF1)
* Gets two formulae
* @return resulting line of proof
*/
BigInteger Ax1(){
BigInteger WF1=Swff();
BigInteger WF2=Swff();
BigInteger t=Binop(WF2,2,WF1);
return Binop(WF1,2,t);
}
/** Axiom 2: (WF1⇒(WF2⇒WF3))⇒((WF1⇒WF2)⇒(WF1⇒WF3))
* Gets three formulae
* @return resulting line of proof
*/
BigInteger Ax2(){
BigInteger WF1=Swff();
BigInteger WF2=Swff();
BigInteger WF3=Swff();
BigInteger T=Binop(WF1,2,WF2);
BigInteger T1= Binop(WF1,2,WF3);
T1=Binop(T,2,T1);
T=Binop(WF2,2,WF3);
T=Binop(WF1,2,T);
return Binop(T,2,T1);
}
/** Axiom 3 (¬WF2⇒¬WF1)⇒((¬WF2⇒WF1)⇒WF2)
* Gets two formulae
* @return resulting line of proof
*/
BigInteger Ax3(){
BigInteger WF1=Swff();
BigInteger WF2=Swff();
BigInteger T1=Unop(1,WF2);
BigInteger T=Binop(T1,2,Unop(1,WF1));
T1=Binop(T1,2,WF1);
T1=Binop(T1,2,WF2);
return Binop(T,2,T1);}
/** Axiom 4:∀V WF(V)⇒WF(T)
* (T is a term free for V in WF)
* Gets a variable, a term and a formula
* @return resulting line of proof
*/
BigInteger Ax4(){
BigInteger rep;
long varx=getint();
Termx=Sterm();
BigInteger WF=Swff();
Proofin=Source;varep=varx;
Source=WF;rep=Swff();//replace
Source=Proofin;
//if (erflg) return BigInteger.ZERO;
WF=Binop(Varb(varx),3,WF);
return Binop(WF,2,rep);
}
/** Axiom 5: ∀V(WF1⇒WF2)⇒(WF1⇒∀V WF2)
* (WF1 has no free occurence of V)
* Gets a variable and two formulae
* @return resulting line of proof
*/
BigInteger Ax5(){
long varx=getint();
BigInteger WF1=Swff();
BigInteger WF2=Swff();
BigInteger T=Binop(WF1,2,WF2);
T=Binop(Varb(varx),3,T);
BigInteger T1=Binop(Varb(varx),3,WF2);
T1=Binop(WF1,2,WF2);
return Binop(T,2,T1);
}
/** Modus Ponens: WF1,WF1 ⇒ WF2 |- WF2
* Gets two formulae
* @return resulting line of proof */
BigInteger MP(){
BigInteger Tres;
BigInteger WF1=Glin();
Tres=Glin();
Proofin=Source;
Source=Tres;
if (get2()!=2)Tres=BigInteger.ZERO;
if (WF1.compareTo(Swff())!=0)Tres=BigInteger.ZERO;
Tres=Swff();
Source=Proofin;
return Tres;
}
/** Generalisation: WF |- ∀V WF
* Gets a variable and a formula
* @return resulting line of proof */
BigInteger Gen(){
long varx=getint();
BigInteger WF1=Glin();
return Binop(Varb(varx),3,WF1);
}
/** Induction: WF(0) ⇒((∀V (WF(V) ⇒ WF(V'))) ⇒ ∀V WF(V))
* * Gets a variable and a formula
* @return resulting line of proof */
BigInteger Ind(){
long varx=getint();
BigInteger V=Varb(varx);
BigInteger WF=Swff();
Proofin=Source;
Termx=V.shiftLeft(4).add(THREE);//V'
Source=WF;varep=varx;BigInteger t1=Swff();//replace
t1=Binop(WF,2,t1);
t1=Binop(V,3,t1);
BigInteger t=Binop(V,3,WF);
t1=Binop(t1,2,t);
Source=WF;
Termx=BigInteger.valueOf(9); t=Swff();//0
Source=Proofin;
return Binop(t,2,t1);
}
/** Gets a line of a proof
* @param c0 intial two bits - previously obtained
* @return resulting line of proof */
BigInteger proofline(int c0){
varep=-1;
switch (c0){
case 1:switch (get2()){ //propositional axiom
case 0:return Ax1();
case 1:return Ax2();
default:return Ax3();
}
case 2:switch (get2()){// predicate & induction
case 0:return Ax4();
case 1:return Ax5();
default: return Ind();
}
default: switch (get2()){ //rules
case 0:return MP();
default:return Gen();
}
}
}
/**Produces Gödel numbers of formulae of proof from Gödel number of proof in Proofin */
void proves(){
int c0;
curlin=1;
Source=Proofin;
while ((c0=get2())>0) {
line[curlin]=proofline(c0);
plines.append(line[curlin].toString()+"\n");
curlin++;
}}
public String getAppletInfo() {
return "Godel number";
}
}
/*
13977428729055444594
972062322
59137
231
*/