From d3d9a1aa8e1ad1a1e13b108b7f8273022b21f794 Mon Sep 17 00:00:00 2001 From: Yingjian Wang <yingjian.wang@mailbox.tu-dresden.de> Date: Wed, 19 Jan 2022 00:24:44 +0100 Subject: [PATCH] Update Move.jadd --- src/main/jastadd/hanoi/Move.jadd | 289 ++++++++++++++++--------------- 1 file changed, 152 insertions(+), 137 deletions(-) diff --git a/src/main/jastadd/hanoi/Move.jadd b/src/main/jastadd/hanoi/Move.jadd index 86e03df..5e6430c 100644 --- a/src/main/jastadd/hanoi/Move.jadd +++ b/src/main/jastadd/hanoi/Move.jadd @@ -1,139 +1,154 @@ -import java.util.*; -aspect Connectives{ - uncache Connective.eval(); - syn boolean Connective.eval(); - eq Conjunction.eval(){ - return this.getLeft().eval() && this.getRight().eval(); - } - eq Disjunction.eval(){ - return this.getLeft().eval() || this.getRight().eval(); - } - eq Implication.eval(){ - return (!this.getLeft().eval()) || this.getRight().eval(); - } - eq Negation.eval()= !getConnective().eval(); - eq Atom.eval(){ - return this.getRelation().eval(); - } - uncache Relation.eval(); - syn boolean Relation.eval(); - eq Subsetof.eval(){ - Set left=new HashSet<>(); - for(String element : this.getLeft().Set()){ - left.add(element); - } - Set right=new HashSet<>(); - for(String element : this.getRight().Set()){ - right.add(element); - } - return right.containsAll(left); - } - eq Compare.eval(){ - return (this.getLeft().eval() - this.getRight().eval())<0; - } - eq Equal.eval(){ - return this.getLeft().eval() - this.getRight().eval()==0; - } - uncache Term.eval(); - syn int Term.eval(); - eq Plus.eval(){ - return this.getLeft().eval() + this.getRight().eval(); - } - eq Minus.eval(){ - return this.getLeft().eval() - this.getRight().eval(); - } - eq Multi.eval(){ - return this.getLeft().eval() * this.getRight().eval(); - } - eq Divide.eval(){ - return this.getLeft().eval() / this.getRight().eval(); - } - eq Mod.eval(){ - return this.getLeft().eval() % this.getRight().eval(); - } - eq IfThenElse.eval(){ - if(this.getIf().Satisfied()){ - return this.getThen().eval(); - } - return this.getElse().eval(); - } - eq CompareFunction.eval(){ - if(this.getLeft().eval() < this.getRight().eval()){ - return 1; - } - return 0; - } - eq EqualFunction.eval(){ - if(this.getLeft().eval() == this.getRight().eval()){ - return 1; - } - return 0; - } - eq SubsetofFunction.eval(){ - Set left=new HashSet<>(); - for(String element : this.getLeft().Set()){ - left.add(element); - } - Set right=new HashSet<>(); - for(String element : this.getRight().Set()){ - right.add(element); - } - if(right.containsAll(left)){ - return 1; - } - return 0; - } - eq ConstantNum.eval(){ - return this.getNum(); - } - eq PillarID.eval(){ - return this.getRel().ID(); - } - eq TotalDiskAmount.eval(){ - return this.getRel().AmountD(); - } - eq DisksOnPillar.eval(){ - return this.getRel().getNumDisk(); - } - eq TopDiskSize.eval(){ - return this.getRel().getDisk(this.getRel().getNumDisk()-1).getSize(); - } -//customerized terms - eq Term1.eval(){//return the size of top disk - if(this.getRel().getNumDisk()>0){ - //if the pillar is not empty, check if the top disk has size 1 - return this.getRel().getDisk(this.getRel().getNumDisk()-1).getSize(); +aspect Move{ + public boolean Constraint.oddTurnMove(Pillar P0, Pillar P1){ + /*for every odd turn(turn==true), move the smallest disk D0 in sequence. |-----------Right:DisksOnPillar(P0) + Therefore, ValidTarget checks for a move from P0 to P1, when D0 is on the top of P0. |------If():ComparFunction()------Left:ConstantNumM0(0) + Conjunction()-------------hasSmallestDisk()---------R0()-----------------F0()----------------|------Then():P0TopDiskSize() + | TopDiskSizeEq1 IfThenElse |------Else():ConstantNumM1(-1) + | | + | |----------ConstantNum1(1) + |---ValidTarget()---------R1()---------P1.ID() + P1EqTarget + | + |-----Mod0()------Left:Plus0()------Left:Plus1()------Left:Mod1()------TotalDiskAmount(); + | | | |------------ConstantNum2(2) + | | |--------ConstantNum1(1) + | |------P0.ID + |------ConstantNum3(3)*/ + Conjunction ValidMove=new Conjunction(); + + Atom hasSmallestDisk=new Atom();//if the smallest disk is on this pillar + Equal TopDiskSizeEq1= new Equal(); + IfThenElse TopDiskChecher=new IfThenElse(); + CompareFunction PillarHasDisk=new CompareFunction(); + TopDiskSize P0TopDiskSize=new TopDiskSize(); + ConstantNum NumM1=new ConstantNum(); + ConstantNum Num1=new ConstantNum(); + ConstantNum Num0=new ConstantNum(); + DisksOnPillar DisksOnP0=new DisksOnPillar(); + + Atom ValidTarget=new Atom();//check if the move sequence from P0 to P1 is valid + Equal P1EqTarget= new Equal(); + PillarID P1ID=new PillarID(); + Mod Mod0=new Mod(); + Mod Mod1=new Mod(); + Plus Plus0=new Plus(); + Plus Plus1=new Plus(); + TotalDiskAmount DisksOverall=new TotalDiskAmount(); + PillarID P0ID=new PillarID(); + ConstantNum Num2=new ConstantNum(); + ConstantNum Num3=new ConstantNum(); + + ValidMove.setLeft(hasSmallestDisk); + ValidMove.setRight(ValidTarget); + + NumM1.setNum(-1); + Num0.setNum(0); + Num1.setNum(1); + Num2.setNum(2); + Num3.setNum(3); + + TopDiskSizeEq1.setLeft(TopDiskChecher); + TopDiskChecher.setIf(PillarHasDisk); + PillarHasDisk.setLeft(Num0); + PillarHasDisk.setRight(DisksOnP0); + DisksOnP0.setRel(P0); + TopDiskChecher.setThen(P0TopDiskSize); + P0TopDiskSize.setRel(P0); + TopDiskChecher.setElse(NumM1); + TopDiskSizeEq1.setRight(Num1); + hasSmallestDisk.setRelation(TopDiskSizeEq1); + + ValidTarget.setRelation(P1EqTarget); + P1EqTarget.setLeft(P1ID); + P1ID.setRel(P1); + P1EqTarget.setRight(Mod0); + Mod0.setLeft(Plus0); + Mod0.setRight(Num3); + Plus0.setLeft(Plus1); + Plus0.setRight(P0ID); + P0ID.setRel(P0); + Plus1.setLeft(Mod1); + Plus1.setRight(Num1); + Mod1.setLeft(DisksOverall); + DisksOverall.setRel(P0); + Mod1.setRight(Num2); + + this.addConnective(ValidMove); + if(this.getConnective(0).eval()){ + System.out.println("Odd turn: P" + P0.ID() +".hahasSmallestDisk0 && (P" + P0.ID() +".target == P" + P1.ID()+")"); + return true;//odd turn and valid move }else{ - return -1;//no disk, the number is invalid, return -1 + return false; } - } - eq Term2.eval(){ - return this.getRel().moveSeq(); - } - eq Term3.eval(){ - return this.getRel().ID(); - } - uncache Condition.Satisfied(); - syn boolean Condition.Satisfied(); - eq CompareFunction.Satisfied(){ - return this.getLeft().eval() < this.getRight().eval(); - } - eq EqualFunction.Satisfied(){ - return this.getLeft().eval() == this.getRight().eval(); - } - eq SubsetofFunction.Satisfied(){ - Set left=new HashSet<>(); - for(String element : this.getLeft().Set()){ - left.add(element); - } - Set right=new HashSet<>(); - for(String element : this.getRight().Set()){ - right.add(element); - } - return right.containsAll(left); - } - public String[] Term.Set(){ - String[] str=new String[]{}; - return str; - } -} + } + public boolean Constraint.evenTurnMove(Pillar P0, Pillar P1){ + /*for every even turn(turn==false), move the disk D on top of P0 to P1: + D is not D0(the smallest disk). + There is always one D can be moved in the even turn according to the game rules. + Statements: + 1.P0 is not empty: not OND(). + 2.When condition 1 holds, P1 can be empty: TND(). + 3.When 1 holds and 2 doesn’t hold, D0 < D1(for the disks on the top of P0 and P1 respectively). + Therefore, we want not OND() and (TND() or ValidTarget()) to be true. + |-----------hasSmallestDisk()-----------------R0---------------T0() + C1 |C3 |----------------T3() + Conjunction()-------------Negation()------Disjunction()----OND()----------------R1()----------------T0() + C0 | |----------------T2() + |---Disjunction()-----------TND()--------------R2()---------T1() + |C2 |-----------T2() + |------------------ValidTarget()-----------------R3()---------T0() + |---------T1*/ + Conjunction C0=new Conjunction(); + Negation C1=new Negation(); + Disjunction C2=new Disjunction(); + Disjunction C3=new Disjunction(); + Atom hasSmallestDisk=new Atom();//if the smallest disk is on this pillar + Atom OND=new Atom();//origin has no disk + Atom TND=new Atom();//target has no disk + Atom ValidTarget=new Atom();//check the size, if the disk on the top of origin has smaller size than the one on target + + C0.setLeft(C1); + C0.setRight(C2); + C1.setConnective(C3); + C2.setLeft(TND); + C2.setRight(ValidTarget); + C3.setLeft(hasSmallestDisk); + C3.setRight(OND); + + Term1 T0=new Term1();//return size of top disk, return -1 when no disk. + Term1 T1=new Term1(); + ConstantNum T2=new ConstantNum(); + ConstantNum T3=new ConstantNum(); + + T0.setRel(P0); + T1.setRel(P1); + T2.setNum(0); + T3.setNum(1); + + Equal R0=new Equal(); + Compare R1=new Compare(); + Compare R2=new Compare(); + Compare R3=new Compare(); + + R0.setLeft(T0); + R0.setRight(T3); + R1.setLeft(T0); + R1.setRight(T2); + R2.setLeft(T1); + R2.setRight(T2); + R3.setLeft(T0); + R3.setRight(T1); + hasSmallestDisk.setRelation(R0); + OND.setRelation(R1); + TND.setRelation(R2); + ValidTarget.setRelation(R3); + + this.addConnective(C0); + if(this.getConnective(0).eval()){ + System.out.println("Even turn: !(P" + P0.ID() +".#disk == 0 || P" + P0.ID() +".hahasSmallestDisk0) && (P" + P1.ID() +".#disk == 0 || P" + P0.ID() +".topDisk < P" + P1.ID() +".topDisk)"); + return true;//even turn and valid move + } + return false; + } + } + -- GitLab