Power Logic
C. Second Edition
.
1. Basic IDEA:
I Even change the whole
Design of Logic Class from "Bool" Value to "Logic State" == 1: Positive; 0: Possible; -1: Negative. Because in My
Mind, as for an unknown logic object, its state is always unknown or "possible". we can notware
Object of which the logic state is each "positive" or "negative" to DEDUCT All UNOWN LOGIC OBJECT. OF COURSE
During Deduction, if you find out you are attempting to change an knower logic object from one state (Positive
Or Negative) To Its Opposite State, We Reach An Contradiction. I Basically Define 4 Logic Operation, But The
4th One "Conditional" IS Actually Aable To Be Expressed by The Other Three --- "AND", "OR", "Not".
I stubbornly try to Avoid To Write a "Parser" Which is Possibly Beyond My Ability, Energy. So, I USE A
Similar Method to Record Each Step of Logic Calculation of A Rule (or Logic Expression Involving Several Logic
Objects connection by logic operats). IT IS A Stack of A Record --- Oprec Which is Containing A Status Flag
INDICATING WHETER IT IS An OPERAND, OPERATOR OR A Result, A Pointer In Case Operand Or Result, OR SIMPLY AN
Operator flag if it is an operator. in ORDER TO SAVE SPACE, I Use an off ion to represent "operator" and "operand".
(It doesn't matter, nobody carties. I mean space.)
The Most Important Part Is That I Implement A Series of Judgement Function According to Different Operators.
For example, for "AND" operator, if either of the two operand is false, and the result is true, you definitely reacha conclusion that they are contradictive. If the result is true, only one possible solution is that both operands
Are true. this is caled "DEDUction". SO Simple IS.
2. Program design: in Logic Class, There is one static Object of Analyze Class Objects Which Fulfill Analysis
Function. in this analyse Object there is a stack to contain array of record --- * Oprec - in this record, I Record
Each Logic Objects, Operators, Even INCLUDING THE TEMPERATORY LOGIC Objects. for Example, ~ R | W i Have To Record
"R" as first Operand, "!" As operator, "~ r" as result; "~ r" as first Operand for second step, "|" as operator,
"W" as operand, "~ r | w" as result. So, you see i actually like use stack to do some similar jobs.
3. Major Function:
A. Bool Analyze :: ReadStack (int index)
Major Function Getting Info from Stack of Analyze Class, Judging The Operator The Call Appropriate Analsing Function.
RESULT Means if The IS New Discovery Or Deductions, Like Find A New Value for Any Step of Logic Objects.
B. Void Analyze ::=alysis ()
Keep Finding The "Result" TYPE IN OPREC (THE Stack) And Call "Readstack", doing the analysis. Have to clear stack for
Next Expression Checking.
C. Bool Analyz :: Analynd (Logic * OP1, Logic * OP2, Logic * Result)
Bool Analynot (Logic * OP1, Logic * Result)
Bool Analyz :: Analyble (Logic * OP1, Logic * OP2, Logic * Result)
Bool Analyz :: Analyconditional (Logic * OP1, Logic * OP2, Logic * Result)
These functions actually do the deduction job, given the state of result, there is certain chance you can get the stateof certain operand under certain operator For example:. "OR" operator will only give a "Negative" result when two operand
Are Both "Negative". That's the IDEA.
D. Void Logic :: PushStack (const logic * self, const logic * pdummy, logicop opcode)
This Function Will Put The Pointer of Each Operand, Operator, Result Which IS in Array of "Temp" INTO AnalySE's
STACK.
E. LogicState Logic :: And (LogicState Self, LogicState Dummy)
This is logic "and"! Have you found out? Say, true = 1, false = -1 Ten Result = true "and" false = (-1 * 1)
There is online exception: -1 * (- 1) = 1, SO, I Only Have to Judge When Two Operands Are Same. In this case, the result is
Same as any of operand. (True && true = true; false&& false = false) Even possible is incnation by the rule as 1 * 0 = 0 (Possible with
Any Other State Is Still Possible.)
F. LogicState Logic :: AND (LogicState Self, LogicState Dummy)
This is logic "or". The result is always the bigger one among two operands. Right? (Say True || false = true, Even Possible
Which is 0 Also Falls Withnin the rule.)
G. logicstate logic :: Not (logicstate self)
This Is Logic "Not". WHENEVER TIMES -1. (! True = false)
H. void setFacts (); void setFactstr ()
The There TWO Global Function Doitization Job To set the logic objects with initial logic state and name express.
I. Logic & (* Checklists [10]) () = {CHECK1, Check2, Check3, Check4, Check5, Check6, Check7, Check8, Check9, Check10}
This is a function array which initialize to 10 checking functions each of which is a logic expression with Logic objectsin the logic list of "element [ElementNum]" and connected by logic operators. The return value is actually the final result
Logic Objects Which is Stored in The Internal List "Temp" Along All Other Transpositional Results. And this Last Result
Itself is the so-caled "rule" Which shouth be true. and i set up its state to be ba posient before desi
Void Analyze ::=Aalysing ()
4. Further Improvement:
A. I Always Want To Write Those Global Function To Make THEM Part of Class Function. But it is not a easy
Job.
B.
D. The Problem:
R: "IT is raining."
S: "IT is snowing."
I: "I get Ill."
W: "I get wet."
D: "I NEED A Doctor."
H: "IT IS Hot."
F: "I Have a flec."
Now I Give You Some Facts Which Can Be Regarded AS A Collection of Rules:
1) ~ r | w (r-> w) if it is raining, the I get WET.
2) r | w (~ r-> s) if it is not raining, the IT is snowing.
3) ~ R | ~ S (r-> ~ s) if it is raining, the IT is not snowing.
4) ~ s | ~ h (S-> ~ h) IF IT IS Snowing, The IT IT IS NOT.
5) ~ w | h | i (w -> (h | i)) IF IT IS WET, The IT IS Either Hot OR i Get Ill.
6) ~ i | ~ f | d (i-> (~ f | d)) IF I get Ill, Then i Either Don't Have A Fever or NEED A DOCTOR.
7) f | ~ d (~ f-> ~ d) if I do not have a fever, Then i don't need a doctor.
8) ~ s | ~ h (S-> ~ H) IF IT IS SNOWING, THEN IT IS NOT.
9) ~ I | H | D (i-> (h | d)) IF I get illl dam 台 it is estart.
10) H | ~ i | ~ w | f ((i && w) -> (h | f)) IF I get Both Wet And Ill The ITHER HOT
OR I Have A Fever.
Suppose We Have Following Facts:
1) R 2) ~ h
Can We make conclusion That D?
Or in Other Words That Suppose "It is raining" and "it is not hot", can we complude That
"I NEED A Doctor"?
The answer is yes! And the program outcome proves.
E. The Problem of Last Edition:
The answer of last edition for Same Question IS Different from now! Because in Last Edition,
I found finic "d".
#include
Using namespace std;
Const int stacklimit = 30;
ENUM LOGICOP
{AND, OR, NOT, CONDitional};
ENUM OPSTATE
{OPERAND, OPERATOR, RESULT};
ENUM logicState
{POSITIVE = 1, Possible = 0, Negative = -1};
Bool Operator == (LogicState Self, LogicState Dummy)
{
Return (Self - Dummy) == 0);
}
// forward decaration
Class AnalySe;
Char * OPSTR [4] = {"AND", "or", "not", "conditional"};
Class Logic
{
Private:
STATIC AnalySE * Analyzes;
Static bool status;
Static int Logiccount;
Char * express;
Int index;
LogicState State;
Void catname (char *, const char *, logicop);
Static Logic * Temp [100];
Static int Tempcount;
Static Logic * true;
Static Logic * false;
Bool DefinedStatus;
LogicState and (LogicState Self, LogicState Dummy);
LogicState or (LogicState Self, LogicState Dummy);
LogicState Not (LogicState Self);
Void Pushstack (Const Logic * Self, Const Logic * Pdummy, Logicop Opcode);
Logic * getTemp () {return temp [Tempcount-1];
protected:
Voidinitialize ();
BOOL Compare (Const Logic & Dummy);
Void uninitialize ();
PUBLIC:
Analyze * getAnalyse ();
Logic (Const Char * NewExpress, Const LogicState Value = POSSIBLE); ~ Logic ();
Logic ();
Void prepare ();
Bool getStatus () const {return definedstatus;
Void setStatus (const bool newstatus) {definedstatus = newstatus;
Void setExpress (const char *);
Char * getExpress () const {return.com
Void setIndex (const INT newIndex) {index = newIndex;}
Int getIndex () const {return index;}
Void setState (logicstate newstate) {state = newstate;
LogicState getState () const {return state;}
Static const Int count () {return logiccount;
Logic & Operator && (Logic & Dummy);
Logic & Operator || (Logic & Dummy);
Logic & Operator! ();
Bool Operator == (Const Logic & Dummy);
Logic & Operator && (Const Bool Value);
Logic & Operator || (Const Bool Value);
Logic & Operator = (const logic& ";
Logic & Operator >> (Logic & Dummy);
Void doanalysis ();
}
Union unknown
{
Logicop Operator = (Logicop Dummy);
Logic * Operator = (const logic * dummy);
Logic * logic;
Logicop OP;
}
Struct OPREC
{
OpState Optype;
Union unknown UNKNOWN;
}
Logic * unknown :: Operator = (const logic * dummy)
{
Logic = (logic *) Dummy;
Return Logic;
}
Logicop unknown :: Operator = (Logicop Dummy)
{
Op = Dummy;
Return OP;
}
Class AnalySe
{
Private:
BOOL Analyand (Logic * OP1, Logic * OP2, Logic * Result);
Bool Analyble (Logic * OP1, Logic * OP2, Logic * Result);
Bool Analyconditional (Logic * OP1, Logic * OP2, Logic * Result);
BOOL Analynot (Logic * OP1, Logic * Result);
Static OPREC * OPSTACK [stacklimit];
Int top;
Void clearstack ();
Logicop Findopcode (INT INDEX);
Bool SetNewop (Logic * Dummy, LogicState NewValue);
INT FINDPRERESULT (INT INDEX);
OPREC * gettop () {if (TOP> 0) Return Opstack [TOP-1]; else return null;} public:
Analyze ();
~ Analyze ();
Void Push (OPREC * NEWREC) {IF (TOP OPREC * POP () {if (TOP> 0) Return Opstack [- TOP]; Bool ReadStack (int INDEX); (); } Const Elementnum = 7; ENUM ELEMENT {R, S, I, W, D, H, F}; Char * Factstr [7] = {"IT IS Raining", "IT ILL", "I get Wet", "I NEED Doctor", "IT IS Hot", "I Have a flec"}; Logic element [ElementNum]; Logic & Check1 (); Logic & CHECK2 (); Logic & CHECK3 (); Logic & CHECK4 (); Logic & CHECK5 (); Logic & Check6 (); Logic & CHECK7 (); Logic & Check8 (); Logic & Check9 (); Logic & CHECK10 (); Logic & (* Checklisms [10]) () = {Check1, Check2, Check3, Check4, Check5, Check6, Check7, Check8, Check9, Check10}; Char * logicstr [3] = {"true", "unknown", "false"}; Void DisplayResult (); Void setFactstr (); Void setFacts (); int main () { SetFactstr (); SetFacts (); For (int J = 0; j <2; j ) { For (int i = 0; i <10; i ) { COUT << "/ nnow check rule of no" << i << endl; CHECKLISTS [I] ()). Doanalysing (); } } DISPLAYRESULT (); Return 0; } Void setFacts () { Element [R] .SetState (POSITIVE); Element [h] .SetState (negative); } Void setFactstr () { For (int i = 0; i { ELEMENT [I] .SETEXPRESS (FactStr [I]); } } Void DisplayResult () { For (int i = 0; i { COUT << "/ nthe logic expression '" << FactStr [i] << "" "" " Switch (Element [i] .getState ()) { Case Positive: COUT << Logicstr [0]; Break; Case Possible: Cout << Logicstr [1]; Break; Case NEGATIVE: COUT << Logicstr [2]; Break; } Cout << "/ n"; } } Logic & CHECK10 () { Return (! Element [R]) || (Element [W]); } Logic & CHECK2 () { Return (Element [R]) || (Element [S]); } Logic & Check3 () { Return (! Element [r]) || (! Element [s]); } Logic & Check4 () { Return (! Element [S]) || (! Element [h]); } Logic & Check5 () { Return (! Element [W]) || (Element [H]) || (Element [i]); } Logic & Check6 () { Return (! Element [i]) || (! Element [f]) || (Element [D]); } Logic & Check7 () { Return (Element [f]) || (! Element [D]); } Logic & Check1 () { Return (! Element [S]) || (! Element [h]); } Logic & Check9 () { Return (! Element [i]) || (Element [H]) || (Element [D]); } Logic & Check8 () { Return (Element [H]) || (! Element [i]) || (! Element [w]) || (Element [f]); } Analyze * logic :: getAnalyse () { Return AnalySe; } Void logic :: doanalysis () { () -> analyysing (); } Int AnalySE :: FINDPRERESULT (int INDEX) { While (INDEX> 0) { Index -; IF (OpStack [index] -> OPTYPE == Result) Return Index; } Return -1; } Void Analyze ::=Aalysing () { IF (Gettop () -> Optype! = Result { Cout << "/ NOPSTACK IS NOT Ended with Result: << Endl; Return; } Else { INT i = TOP -1; Opstack [i] -> Unknown.logic-> setState (POSITIVE); While (i! = -1) { Readstack (i); I = FINDPRERESULT (i); } } Clearstack (); } Logicop Analyz :: Findopcode (int index) { INT i = index; While (Opstack [i] -> OPTYPE! = Operator) { I-; } Return Opstack [I] -> Unknown.op; } Bool Analyz :: readstack (int index) { Bool result = false; Logicop opcode; IF (OpStack [index] -> OPTYPE! = Result) { COUT << "stack error! / n"; Return False; } Opcode = Findopcode (INDEX); Switch (opcode) { Case and: Result = analynd (Opstack [index-3] -> unknown.logic, Opstack [INDEX - 1] -> Unknown.logic, Opstack [index] -> unknown.logic; Break; Case or: Result = analyyor (Opstack [index-3] -> unknown.logic, Opstack [INDEX - 1] -> Unknown.logic, Opstack [index] -> unknown.logic; Break; Case Conditional: Result = analysis -> unknown.logic, Opstack [INDEX - 1] -> Unknown.logic, Opstack [index] -> unknown.logic; Break; Case NOT: Result = analysis -> unknown.logic, Opstack [index] -> unknown.logic; Break; } Return Result; } Bool Analyze :: setNewop (Logic * Dummy, LogicState NewValue) { IF (Dummy-> getState ()! = newValue) { IF (Dummy-> getState ()! = possible) { Cout << "/ NYOU Are Changing Expression '" << Dummy-> getExpress () << "Value!" Return False; } Else { Dummy-> setState (NewValue); Return True; } } Else Return False; } Bool Analyz :: Analyans (Logic * OP1, Logic * OP2, Logic * Result) { Bool newop = false; Switch (result-> getState ()) { Case Positive: IF (op1-> getState () == negative || OP2-> getState () == NEGATIVE { Cout << "/ Nthere IS ContraDictive At:" << result-> getExpress (); Return False; } NEWOP = setnewop (op1, posacy) || setnewop (op2, posacy); Break; Case NEGATIVE: IF (op1-> getState () == posTIVE && OP2-> getState () == posTIVE) { Cout << "/ Nthere IS ContraDictive At:" << result-> getExpress (); Return False; } IF (op1-> getState () == posTIVE) { Newop = setnewop (OP2, NEGATIVE); } Else { IF (OP2-> getState () == posTIVE) { Newop = newop || SetNewop (OP1, NEGATIVE); } } Break; Case Possible: Break; } Return False; } Bool Analyz :: Analyble (Logic * OP1, Logic * OP2, Logic * Result) { Bool newop = false; Switch (result-> getState ()) { Case Positive: IF (op1-> getState () == Negative && op2-> getState () == NEGATIVE) { Cout << "/ Nthere IS ContraDictive At:" << result-> getExpress (); Return False; } IF (OP1-> getState () == NEGATIVE) { NEWOP = setnewop (op2, posacy); } Else { IF (OP2-> getState () == NEGATIVE) { Newop = newop || SetNewop (OP1, POSTIVE); } } Break; Case NEGATIVE: IF (op1-> getState () == posTIVE || OP2-> getState () == posTIVE) { Cout << "/ Nthere IS ContraDictive At:" << result-> getExpress (); Return False; } Break; Case Possible: Break; } Return newop; } Bool Analyz :: Analyconditional (Logic * OP1, Logic * OP2, Logic * Result) { Bool newop = false; Switch (result-> getState ()) { Case Positive: IF (op1-> getState () == posTIVE && OP2-> getState () == NEGATIVE { Cout << "/ Nthere IS ContraDictive At:" << result-> getExpress (); Return False; } IF (op1-> getState () == posTIVE) { NEWOP = setnewop (op2, posacy); } Else { IF (OP2-> getState () == posTIVE) { Newop = setnewop (OP1, POSTIVE); } } Break; Case NEGATIVE: IF (OP1-> getState () == NEGATIVE) { Cout << "/ Nthere IS ContraDictive At:" << result-> getExpress (); Return false;} Newop = setnewop (OP2, NEGATIVE); Newop = newop || SetNewop (OP1, POSTIVE); Break; Case Possible: Break; } Return newop; } Bool Analynot (Logic * OP1, Logic * Result) { Bool newop = false; Switch (result-> getState ()) { Case Positive: IF (op1-> getState () == posTIVE) { Cout << "/ Nthere IS ContraDictive At:" << result-> getExpress (); Return False; } Else { Newop = setnewop (OP1, NEGATIVE); } Break; Case NEGATIVE: IF (OP1-> getState () == NEGATIVE) { Cout << "/ Nthere IS ContraDictive At:" << result-> getExpress (); Return False; } Else { Newop = setnewop (OP1, POSTIVE); } Break; Case Possible: Break; } Return newop; } Analyze * Logic :: Analyze = New Analyz OPREC * Analyz :: opstack [stacklimit]; Void analyse :: clearstack () { For (INT i = 0; i { Delete Opstack [i]; } TOP = 0; } Analyzes :: analyse () { TOP = 0; } Analyz :: ~ Analyze () { Clearstack (); } LogicState Logic :: And (LogicState Self, LogicState Dummy) { IF (Self! = Dummy) { Return (LogicState) (Self * Dummy); } Else { Return Self; } } LogicState Logic :: OR (LogicState Self, LogicState Dummy) { Return (Self> = DUMMY)? Self: Dummy); } LogicState Logic :: Not (LogicState Self) { Return (LogicState) (- 1 * Self); } void logic :: prepare () { For (int i = 0; i { Free (Temp [i]); } Tempcount = 0; } Logic & Logic :: Operator >> (Logic & Dummy) { Char buffer [256]; Catname (Buffer, Dummy.getexpress (), Conditional Temp [Tempcount] = New Logic (buffer); Temp [Tempcount] -> SetState (Not (State), Dummy.getState ())); Tempcount ; Pushstack (this, & demmy, conditional); Return * Temp [Tempcount-1]; } void logic :: uninitialize () { STATUS = TRUE; For (int i = 0; i { Delete Temp [I]; } } Bool logic :: status = false; Logic * logic :: temp [100] = {null}; // = new logic INT logic :: tempcount = 0; Logic * logic :: false = new logic ("false", negative); Logic & Logic :: Operator = (Const Logic & Dummy) { setExpress (Dummy.Getexpress ()); SetState (Dummy.getState ()); Return * this; } Logic * logic :: true = new logic ("true", posTIVE) ;; Logic & Logic :: Operator && (Const Bool Value) { IF (Value) { Return (* this) && (* true); } Else { Return (* this) && (* false); } } Logic & Logic :: Operator || (Const Bool Value) { IF (Value) { Return (* this) || (* TRUE); } Else { Return (* this) || (* false); } } BOOL Logic :: Operator == (Const Logic & Dummy) { Return Compare (DUMMY); } BOOL Logic :: Compare (Const Logic & Dummy) { Return (index == Dummy.GetIndex ()); } Void Logic :: CatName (Char * Buffer, Const Char * SECOND, LOGICOP OPCODE) { STRCPY (Buffer, getExpress ()); STRCAT (Buffer, Opstr [OPCode]); STRCAT (Buffer, Second); } Logic & Logic :: Operator! () { Char buffer [256]; OPREC * PTR; STRCPY (Buffer, Opstr [not]); Strcat (buffer, getExpress ()); Temp [Tempcount] = New Logic (buffer); Temp [Tempcount] -> SetState (not (getState ())); Tempcount ; PTR = New OPREC; Ptr-> OPTYPE = Operator; Ptr-> unknown = NOT; Analyze-> Push (PTR); PTR = New OPREC; Ptr-> OPTYPE = OPERAND; Ptr-> unknown = this; Analyze-> Push (PTR); PTR = New OPREC; Ptr-> Optype = Result; Ptr-> unknown = Temp [Tempcount-1]; Analyze-> Push (PTR); Return * Temp [Tempcount-1]; } Void Logic :: Pushstack (const logic * self, const logic * pdummy, logicop opcode) { OPREC * PTR; PTR = New OPREC; Ptr-> OPTYPE = OPERAND; Ptr-> unknown = Self; Analyze-> Push (PTR); PTR = New OPREC; Ptr-> OPTYPE = Operator; Ptr-> unknown = opcode; Analyze-> Push (PTR); PTR = New OPREC; Ptr-> OPTYPE = OPERAND; Ptr-> unknown = pdummy; Analyze-> Push (PTR); PTR = New OPREC; PTR-> OPTYPE = Result; Ptr-> unknown = getTemp (); Analyze-> Push (PTR); } Logic & Logic :: Operator && (Logic & Dummy) { Char buffer [256]; CatName (Buffer, Dummy.Gtexpress (), and); Temp [Tempcount] = New Logic (buffer); Temp [Tempcount] -> setState (getState (), Dummy.getState ()))); Tempcount ; Pushstack (this, & dummy, and); Return * Temp [Tempcount-1]; } Logic & Logic :: Operator || (Logic & Dummy) { Char buffer [256]; CatName (Buffer, Dummy.Getexpress (), OR) Temp [Tempcount] = New Logic (buffer); Temp [Tempcount] -> setState (or (getState (), Dummy.getState ()); Tempcount ; Pushstack (this, & dummy, or); Return * Temp [Tempcount-1]; } INT logic :: logiccount = 0; void logic :: initialize () { Express = NULL; State = possible; DefinedStatus = false; SetIndex (Logiccount); Logiccount ; STATUS = false; } Logic :: ~ logic () { IF (! status) // if you destroy one, then you destroy all !!!!! { uninitialize (); } IF (Express! = NULL) { FREE (Express); } } Logic :: Logic (Const Char * NewExpress, Const LogicState Value) { INITIALIZE (); SetExpress (newExpress); SetState (Value); Logic :: Logic () { Initialize (); } Void Logic :: setExpress (const char * newexpress) { INT I; I = Strlen (newExpress) 1; IF (express == null) { Express = (char *) Malloc (i); } Else { Express = (char *) Realloc (void *) Express, i); } STRCPY (Express, NewExpress); } http://www3.sympatico.ca/qingzhehuang/powerlogic.htm