๊ณต์ ๊ฒ์ฆ์ ๋ค๋ฅธ ํ๋ก๊ทธ๋จ์ด๋ ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํ์ฌ ๊ฒ์ฆํ๋ ๊ฒ์ ๋๋ค.
์ด๋ ํ๋ก๊ทธ๋จ์ ๋ชจ๋ ์ทจ์ฝ์ ์ ์ฐพ๊ฑฐ๋ ์กด์ฌํ์ง ์์์ ์ฆ๋ช ํ ์ ์๋ ๊ฐ์ฅ ๊ฐ๋ ฅํ ๋ฐฉ๋ฒ ์ค ํ๋์ ๋๋ค.
ํ์ ๊ฒ์ฆ์ ๋ํ ์์ธํ ์ค๋ช
์ ๋ฌธ์ ํด๊ฒฐ์ ์์์ ๋ณผ ์ ์์ต๋๋ค.
์ด ๊ธฐ์ฌ์์๋ ๋ฌธ์ ์ ๊ณต์ ๊ฒ์ฆ์์ ํ๋ก๊ทธ๋จ์ผ๋ก ์ด๋ํ๊ณ ๋ฐฉ๋ฒ์ ์ค๋ช
ํฉ๋๋ค.
์ด๋ป๊ฒ ์๋์ผ๋ก ๊ณต์ ๊ท์น ์์คํ
์ผ๋ก ๋ณํํ ์ ์์ต๋๊น?
์ด๋ฅผ ์ํด ๋๋ ์์ง์ ์๋ฆฌ๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ์ ๋จธ์ ์ ์๋ ๋ก๊ทธ๋ฅผ ์ง์ ์์ฑํ์ต๋๋ค.
์ด๋ ํ๋ก๊ทธ๋จ ์ฝ๋๋ฅผ ๊ตฌ๋ฌธ ๋ถ์ํ์ฌ ์ด๋ฏธ ํ๋ก๊ทธ๋๋ฐ ๋ฐฉ์์ผ๋ก ํ ์ ์๋ ๋ฐฉ์ ์ ์์คํ (SMT)์ผ๋ก ๋ณํํฉ๋๋ค.
๊ธฐํธ๊ณ์ฐ์ ๊ดํ ์ ๋ณด๋ ์ธํฐ๋ท์์ ๋ค์ ๋จํธ์ ์ผ๋ก ์ ์๋์ด ์๊ธฐ ๋๋ฌธ์,
๊ทธ๊ฒ์ด ๋ฌด์์ธ์ง ๊ฐ๋ตํ๊ฒ ์ค๋ช
ํ๊ฒ ์ต๋๋ค.
๊ธฐํธ๊ณ์ฐ์ ๊ด๋ฒ์ํ ๋ฐ์ดํฐ์ ๋ํด ํ๋ก๊ทธ๋จ์ ๋์์ ์คํํ๋ ๋ฐฉ๋ฒ์ผ๋ก, ๊ณต์์ ์ธ ํ๋ก๊ทธ๋จ ๊ฒ์ฆ์ ์ํ ์ฃผ์ ๋๊ตฌ์
๋๋ค.
์๋ฅผ ๋ค์ด, ์ฒซ ๋ฒ์งธ ์ธ์๊ฐ ์์ ๊ฐ, ๋ ๋ฒ์งธ ์์, ์ธ ๋ฒ์งธ 42, ์ถ๋ ฅ ์ธ์(์: XNUMX)๋ฅผ ์ทจํ ์ ์๋ ์ ๋ ฅ ์กฐ๊ฑด์ ์ค์ ํ ์ ์์ต๋๋ค.
ํ ๋ฒ์ ์คํ์ผ๋ก ๊ธฐํธ ๊ณ์ฐ์ ์ํํ๋ฉด ์ํ๋ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ์ ์๋์ง ์ฌ๋ถ์ ๋ํ ๋ต๊ณผ ์ด๋ฌํ ์ ๋ ฅ ๋งค๊ฐ๋ณ์ ์งํฉ์ ์๋ฅผ ์ป์ ์ ์์ต๋๋ค. ๋๋ ๊ทธ๋ฌํ ๋งค๊ฐ๋ณ์๊ฐ ์๋ค๋ ์ฆ๊ฑฐ์ ๋๋ค.
๋ํ ์ ๋ ฅ ์ธ์๋ฅผ ๊ฐ๋ฅํ ๋ชจ๋ ์ธ์๋ก ์ค์ ํ๊ณ ์ถ๋ ฅ ์ธ์(์: ๊ด๋ฆฌ์ ๋น๋ฐ๋ฒํธ)๋ง ์ ํํ ์ ์์ต๋๋ค.
์ด ๊ฒฝ์ฐ ํ๋ก๊ทธ๋จ์ ๋ชจ๋ ์ทจ์ฝ์ ์ ์ฐพ์๋ด๊ฑฐ๋ ๊ด๋ฆฌ์์ ๋น๋ฐ๋ฒํธ๊ฐ ์์ ํ๋ค๋ ์ฆ๊ฑฐ๋ฅผ ํ๋ณดํ๊ฒ ๋ฉ๋๋ค.
ํน์ ์ ๋ ฅ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ง ํ๋ก๊ทธ๋จ์ ๊ณ ์ ์ ์ธ ์คํ์ ๊ธฐํธ ์คํ์ ํน๋ณํ ๊ฒฝ์ฐ๋ผ๋ ์ ์ ์ ์ ์์ต๋๋ค.
๋ฐ๋ผ์ ๋ด ์บ๋ฆญํฐ VM์ ํ์ค ๊ฐ์ ๋จธ์ ์ ์๋ฎฌ๋ ์ด์ ๋ชจ๋์์๋ ์๋ํ ์ ์์ต๋๋ค.
์ด์ ๊ธฐ์ฌ์ ๋ํ ๋ ผํ์์ ๊ณต์์ ์ธ ๊ฒ์ฆ์ ์ฝ์ ์ ๋ํ ๋ ผ์์ ํจ๊ป ๊ณต์ ํ ๋นํ์ ์ฐพ์ ์ ์์ต๋๋ค.
์ฃผ์ ๋ฌธ์ ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- ๊ณต์ ๊ฒ์ฆ์ด ๊ถ๊ทน์ ์ผ๋ก P=NP๋ก ๊ท๊ฒฐ๋๋ฏ๋ก ์กฐํฉ ํญ๋ฐ
- ํ์ผ ์์คํ , ๋คํธ์ํฌ ๋ฐ ๊ธฐํ ์ธ๋ถ ์ ์ฅ์์ ๋ํ ํธ์ถ ์ฒ๋ฆฌ๋ฅผ ํ์ธํ๊ธฐ๊ฐ ๋ ์ด๋ ต์ต๋๋ค.
- ๊ณ ๊ฐ์ด๋ ํ๋ก๊ทธ๋๋จธ๊ฐ ํ ๊ฐ์ง๋ฅผ ์๋ํ์ง๋ง ๊ธฐ์ ์ฌ์์์ ์ด๋ฅผ ์ถฉ๋ถํ ์ ํํ๊ฒ ์ค๋ช ํ์ง ์์ ๊ฒฝ์ฐ ์ฌ์์ ๋ฒ๊ทธ์ ๋๋ค.
๊ฒฐ๊ณผ์ ์ผ๋ก ํ๋ก๊ทธ๋จ์ ์ฌ์์ ๊ฒ์ฆํ๊ณ ์ค์ํ์ง๋ง ์ ์์๊ฐ ๊ธฐ๋ํ๋ ๊ฒ๊ณผ๋ ์์ ํ ๋ค๋ฅธ ์์ ์ ์ํํ๊ฒ ๋ฉ๋๋ค.
์ด ๊ธฐ์ฌ์์๋ ์ค์ ๋ก ํ์ ๊ฒ์ฆ์ ์ฌ์ฉ์ ์ฃผ๋ก ๊ณ ๋ คํ๋ฏ๋ก ์ง๊ธ์ ๋ฒฝ์ ๋ถ๋ช์น์ง ์๊ณ ์๊ณ ๋ฆฌ์ฆ์ ๋ณต์ก์ฑ๊ณผ ์ธ๋ถ ํธ์ถ ์๊ฐ ์ต์ํ๋๋ ์์คํ ์ ์ ํํ๊ฒ ์ต๋๋ค.
์ค๋งํธ ๊ณ์ฝ์ ์ด๋ฌํ ์๊ตฌ ์ฌํญ์ ๊ฐ์ฅ ์ ํฉํ๊ธฐ ๋๋ฌธ์ Waves ํ๋ซํผ์ RIDE ๊ณ์ฝ์ ์ ํํ์ต๋๋ค. ์ด๋ Turing ์์ ํ์ง ์์ผ๋ฉฐ ์ต๋ ๋ณต์ก์ฑ์ด ์ธ์์ ์ผ๋ก ์ ํ๋ฉ๋๋ค.
๊ทธ๋ฌ๋ ์ฐ๋ฆฌ๋ ๊ธฐ์ ์ ์ธก๋ฉด์์๋ง ์ด๋ฅผ ๊ณ ๋ คํ ๊ฒ์ ๋๋ค.
๋ชจ๋ ๊ฒ ์ธ์๋ ๋ชจ๋ ๊ณ์ฝ์ ๋ํด ๊ณต์์ ์ธ ๊ฒ์ฆ์ด ํนํ ์๊ตฌ๋ฉ๋๋ค. ์ผ๋ฐ์ ์ผ๋ก ๊ณ์ฝ์ด ์์๋ ํ์๋ ๊ณ์ฝ ์ค๋ฅ๋ฅผ ์์ ํ๋ ๊ฒ์ด ๋ถ๊ฐ๋ฅํฉ๋๋ค.
๊ทธ๋ฆฌ๊ณ ๊ทธ๋ฌํ ์ค๋ฅ๋ก ์ธํ ๋น์ฉ์ ๋งค์ฐ ๋์ ์ ์์ต๋๋ค. ์๋ํ๋ฉด ๊ฝค ๋ง์ ์์ ์๊ธ์ด ์ค๋งํธ ๊ณ์ฝ์ ์ ์ฅ๋๋ ๊ฒฝ์ฐ๊ฐ ๋ง๊ธฐ ๋๋ฌธ์
๋๋ค.
๋ด ๊ธฐํธ ๊ฐ์ ๋จธ์ ์ PHP์ Python์ผ๋ก ์์ฑ๋์์ผ๋ฉฐ Microsoft Research์ Z3Prover๋ฅผ ์ฌ์ฉํ์ฌ ๊ฒฐ๊ณผ SMT ๊ณต์์ ํด๊ฒฐํฉ๋๋ค.
๊ทธ ํต์ฌ์๋ ๊ฐ๋ ฅํ ๋ค์ค ํธ๋์ญ์
๊ฒ์์ด ์์ต๋๋ค.
๋ง์ ํธ๋์ญ์
์ด ํ์ํ ๊ฒฝ์ฐ์๋ ์๋ฃจ์
์ด๋ ์ทจ์ฝ์ ์ ์ฐพ์ ์ ์์ต๋๋ค.
์กฐ์ฐจ
๊ทธ๋ฌ๋ ์ํ ๋ฅด ๊ณ์ฝ์ด ๋ ๋ณต์กํ๊ณ ํ๋ง ์์ ํ๋ค๋ ์ ์ ์ฃผ๋ชฉํ ๊ฐ์น๊ฐ ์์ต๋๋ค.
PHP๋ RIDE ์ค๋งํธ ๊ณ์ฝ์ ์์ค ์ฝ๋๋ฅผ Python ์คํฌ๋ฆฝํธ๋ก ๋ณํํฉ๋๋ค. ์ฌ๊ธฐ์ ํ๋ก๊ทธ๋จ์ ๊ณ์ฝ ์ํ ๋ฐ ์ ํ ์กฐ๊ฑด์ ๋ํ Z3 SMT ํธํ ์์คํ ์ผ๋ก ํ์๋ฉ๋๋ค.
์ด์ ๋ด๋ถ์์ ์ผ์ด๋๋ ์ผ์ ๋ ์์ธํ ์ค๋ช
ํ๊ฒ ์ต๋๋ค.
ํ์ง๋ง ๋จผ์ RIDE ์ค๋งํธ ๊ณ์ฝ ์ธ์ด์ ๋ํด ๋ช ๋ง๋ ๋ง์๋๋ฆฌ๊ฒ ์ต๋๋ค.
์ค๊ณ์ ๊ฒ์ผ๋ฅธ ๊ธฐ๋ฅ์ ํํ ๊ธฐ๋ฐ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด์
๋๋ค.
RIDE๋ ๋ธ๋ก์ฒด์ธ ๋ด์์ ๋
๋ฆฝ์ ์ผ๋ก ์คํ๋๋ฉฐ ์ฌ์ฉ์์ ์ง๊ฐ์ ์ฐ๊ฒฐ๋ ์ ์ฅ์์์ ์ ๋ณด๋ฅผ ๊ฒ์ํ๊ณ ์ธ ์ ์์ต๋๋ค.
๊ฐ ์ง๊ฐ์ RIDE ๊ณ์ฝ์ ์ฒจ๋ถํ ์ ์์ผ๋ฉฐ, ์คํ ๊ฒฐ๊ณผ๋ TRUE ๋๋ FALSE๋ก๋ง ํ์๋ฉ๋๋ค.
TRUE๋ ์ค๋งํธ ๊ณ์ฝ์ด ๊ฑฐ๋๋ฅผ ํ์ฉํ๋ค๋ ๊ฒ์ ์๋ฏธํ๊ณ , FALSE๋ ๊ฑฐ๋๋ฅผ ๊ธ์งํ๋ค๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค.
๊ฐ๋จํ ์: ์ง๊ฐ ์์ก์ด 100 ๋ฏธ๋ง์ธ ๊ฒฝ์ฐ ์คํฌ๋ฆฝํธ๋ ์ด์ฒด๋ฅผ ๊ธ์งํ ์ ์์ต๋๋ค.
์๋ฅผ ๋ค์ด, ๋์ผํ ๋๋, ์ผ์, ์๋ฐฐ์ถ๋ฅผ ์ฌ์ฉํ์ง๋ง ์ด๋ฏธ ์ค๋งํธ ๊ณ์ฝ์ ํํ๋ก ์ ์๋์ด ์์ต๋๋ค.
์ฌ์ฉ์๋ ๋ชจ๋ ์ฌ๋์ ์๋๋ฐฉ์๊ฒ ๋ณด๋ผ ๋๊น์ง ๊ณ์ฝ์ด ๋ฐฐํฌ๋ ์ง๊ฐ์์ ๋์ ์ธ์ถํ ์ ์์ต๋๋ค.
#ะะทะฒะปะตะบะฐะตะผ ะฟะพะปะพะถะตะฝะธะต ะฒัะตั
ะพะฑัะตะบัะพะฒ ะธะท ะฑะปะพะบัะตะนะฝะฐ
let contract = tx.sender
let human= extract(getInteger(contract,"human"))
let wolf= extract(getInteger(contract,"wolf"))
let goat= extract(getInteger(contract,"goat"))
let cabbage= extract(getInteger(contract,"cabbage"))
#ะญัะพ ัะฐะบ ะฝะฐะทัะฒะฐะตะผะฐั ะดะฐัะฐ-ััะฐะฝะทะฐะบัะธั, ะฒ ะบะพัะพัะพะน ะฟะพะปัะทะพะฒะฐัะตะปั ะฟัะธััะปะฐะตั ะฝะพะฒัะต 4 ะฟะตัะตะผะตะฝะฝัะต.
#ะะพะฝััะฐะบั ัะฐะทัะตัะธั ะตั ัะพะปัะบะพ ะฒ ัะปััะฐะต ะตัะปะธ ะฒัะต ะพะฑัะตะบัั ะพััะฐะฝัััั ะฒ ัะพั
ัะฐะฝะฝะพััะธ.
match tx {
case t:DataTransaction =>
#ะะทะฒะปะตะบะฐะตะผ ะฑัะดััะตะต ะฟะพะปะพะถะตะฝะธะต ะฒัะตั
ะพะฑัะตะบัะพะฒ ะธะท ััะฐะฝะทะฐะบัะธะธ
let newHuman= extract(getInteger(t.data,"human"))
let newWolf= extract(getInteger(t.data,"wolf"))
let newGoat= extract(getInteger(t.data,"goat"))
let newCabbage= extract(getInteger(t.data,"cabbage"))
#0 ะพะฑะพะทะฝะฐัะฐะตั, ััะพ ะพะฑัะตะบั ะฝะฐ ะปะตะฒะพะผ ะฑะตัะตะณั, ะฐ 1 ััะพ ะฝะฐ ะฟัะฐะฒะพะผ
let humanSide= human == 0 || human == 1
let wolfSide= wolf == 0 || wolf == 1
let goatSide= goat == 0 || goat == 1
let cabbageSide= cabbage == 0 || cabbage == 1
let side= humanSide && wolfSide && goatSide && cabbageSide
#ะัะดัั ัะฐะทัะตัะตะฝั ัะพะปัะบะพ ัะต ััะฐะฝะทะฐะบัะธะธ, ะณะดะต ั ะบะพะทะพะน ะฝะธะบะพะณะพ ะฝะตั ะฒ ะพััััััะฒะธะธ ัะตัะผะตัะฐ.
let safeAlone= newGoat != newWolf && newGoat != newCabbage
let safe= safeAlone || newGoat == newHuman
let humanTravel= human != newHuman
#ะกะฟะพัะพะฑั ะฟััะตัะตััะฒะธั ัะตัะผะตัะฐ ััะดะฐ ะธ ะพะฑัะฐัะฝะพ, ั ะบะตะผ-ัะพ ะปะธะฑะพ ะฒ ะพะดะธะฝะพัะบั.
let t1= humanTravel && newWolf == wolf + 1 && newGoat == goat && newCabbage == cabbage
let t2= humanTravel && newWolf == wolf && newGoat == goat + 1 && newCabbage == cabbage
let t3= humanTravel && newWolf == wolf && newGoat == goat && newCabbage == cabbage + 1
let t4= humanTravel && newWolf == wolf - 1 && newGoat == goat && newCabbage == cabbage
let t5= humanTravel && newWolf == wolf && newGoat == goat - 1 && newCabbage == cabbage
let t6= humanTravel && newWolf == wolf && newGoat == goat && newCabbage == cabbage - 1
let t7= humanTravel && newWolf == wolf && newGoat == goat && newCabbage == cabbage
let objectTravel = t1 || t2 || t3 || t4 || t5 || t6 || t7
#ะะพัะปะตะดะฝัั ัััะพะบะฐ ะฒ ัะฐะทะดะตะปะต ััะฐะฝะทะฐะบัะธะธ ะพะฟะธััะฒะฐะตั ัะฐะทัะตัะฐััะตะต ััะฐะฝะทะฐะบัะธั ััะปะพะฒะธะต.
#ะะตัะตะผะตะฝะฝัะต ััะฐะฝะทะฐะบัะธะธ ะดะพะปะถะฝั ะธะผะตัั ะทะฝะฐัะตะฝะธั 1 ะธะปะธ 0, ะฒัะต ะพะฑัะตะบัั ะดะพะปะถะฝั
#ะฑััั ะฒ ะฑะตะทะพะฟะฐัะฝะพััะธ, ะฐ ัะตัะผะตั ะดะพะปะถะตะฝ ะฟะตัะตะฟะปัะฒะฐัั ัะตะบั ะฒ ะพะดะธะฝะพัะบั
#ะธะปะธ ั ะบะตะผ-ัะพ ะฝะฐ ะบะฐะถะดะพะผ ัะฐะณั
side && safe && humanTravel && objectTravel
case s:TransferTransaction =>
#ะขัะฐะฝะทะฐะบัะธั ะฒัะฒะพะดะฐ ััะตะดััะฒ ัะฐะทัะตัะตะฝะฐ ัะพะปัะบะพ ะฒ ัะปััะฐะต ะตัะปะธ ะฒัะต ะฟะตัะตะฟะปัะปะธ ะฝะฐ ะดััะณะพะน ะฑะตัะตะณ
human == 1 && wolf == 1 && goat == 1 && cabbage == 1
#ะัะต ะฟัะพัะธะต ัะธะฟั ััะฐะฝะทะฐะบัะธะน ะทะฐะฟัะตัะตะฝั
case _ => false
}
PHP๋ ๋จผ์ ํค์ ํด๋น ๋ถ์ธ ํํ์ ๋ณ์์ ํํ๋ก ์ค๋งํธ ๊ณ์ฝ์์ ๋ชจ๋ ๋ณ์๋ฅผ ์ถ์ถํฉ๋๋ค.
cabbage: extract ( getInteger ( contract , "cabbage" ) )
goat: extract ( getInteger ( contract , "goat" ) )
human: extract ( getInteger ( contract , "human" ) )
wolf: extract ( getInteger ( contract , "wolf" ) )
fState: human== 1 && wolf== 1 && goat== 1 && cabbage== 1
fState:
wolf:
goat:
cabbage:
cabbageSide: cabbage== 0 || cabbage== 1
human: extract ( getInteger ( contract , "human" ) )
newGoat: extract ( getInteger ( t.data , "goat" ) )
newHuman: extract ( getInteger ( t.data , "human" ) )
goatSide: goat== 0 || goat== 1
humanSide: human== 0 || human== 1
t7: humanTravel && newWolf== wolf && newGoat== goat && newCabbage== cabbage
t3: humanTravel && newWolf== wolf && newGoat== goat && newCabbage== cabbage + 1
t6: humanTravel && newWolf== wolf && newGoat== goat && newCabbage== cabbage - 1
t2: humanTravel && newWolf== wolf && newGoat== goat + 1 && newCabbage== cabbage
t5: humanTravel && newWolf== wolf && newGoat== goat - 1 && newCabbage== cabbage
t1: humanTravel && newWolf== wolf + 1 && newGoat== goat && newCabbage== cabbage
t4: humanTravel && newWolf== wolf - 1 && newGoat== goat && newCabbage== cabbage
safeAlone: newGoat != newWolf && newGoat != newCabbage
wolfSide: wolf== 0 || wolf== 1
humanTravel: human != newHuman
side: humanSide && wolfSide && goatSide && cabbageSide
safe: safeAlone || newGoat== newHuman
objectTravel: t1 || t2 || t3 || t4 || t5 || t6 || t7
๊ทธ๋ฐ ๋ค์ PHP๋ ์ด๋ฅผ Python์ Z3Prover SMT ํธํ ์์คํ
์ค๋ช
์ผ๋ก ๋ณํํฉ๋๋ค.
๋ฐ์ดํฐ๋ ์คํ ๋ฆฌ์ง ๋ณ์๊ฐ ์ธ๋ฑ์ค i, ํธ๋์ญ์
๋ณ์ ์ธ๋ฑ์ค i + 1์ ์์ ํ๊ณ ํํ์์ด ์๋ ๋ณ์๊ฐ ์ด์ ์ํ์์ ๋ค์ ์ํ๋ก ์ ํํ๊ธฐ ์ํ ๊ท์น์ ์ค์ ํ๋ ๋ฃจํ๋ก ๋ํ๋ฉ๋๋ค.
์ด๊ฒ์ด ๋ค์ค ํธ๋์ญ์ ๊ฒ์ ์์ง์ ์ ๊ณตํ๋ ๊ฐ์ ๋จธ์ ์ ํต์ฌ์ ๋๋ค.
fState: And( And( And( human[Steps] == 1 , wolf[Steps] == 1 ) , goat[Steps] == 1 ) , cabbage[Steps] == 1 )
final: fState[Steps]
fState:
wolf:
goat:
cabbage:
cabbageSide: Or( cabbage[i] == 0 , cabbage[i] == 1 )
goatSide: Or( goat[i] == 0 , goat[i] == 1 )
humanSide: Or( human[i] == 0 , human[i] == 1 )
t7: And( And( And( humanTravel[i] , wolf == wolf[i] ) , goat[i+1] == goat[i] ) , cabbage == cabbage[i] )
t3: And( And( And( humanTravel[i] , wolf == wolf[i] ) , goat[i+1] == goat[i] ) , cabbage == cabbage[i] + 1 )
t6: And( And( And( humanTravel[i] , wolf == wolf[i] ) , goat[i+1] == goat[i] ) , cabbage == cabbage[i] - 1 )
t2: And( And( And( humanTravel[i] , wolf == wolf[i] ) , goat[i+1] == goat[i] + 1 ) , cabbage == cabbage[i] )
t5: And( And( And( humanTravel[i] , wolf == wolf[i] ) , goat[i+1] == goat[i] - 1 ) , cabbage == cabbage[i] )
t1: And( And( And( humanTravel[i] , wolf == wolf[i] + 1 ) , goat[i+1] == goat[i] ) , cabbage == cabbage[i] )
t4: And( And( And( humanTravel[i] , wolf == wolf[i] - 1 ) , goat[i+1] == goat[i] ) , cabbage == cabbage[i] )
safeAlone: And( goat[i+1] != wolf , goat[i+1] != cabbage )
wolfSide: Or( wolf[i] == 0 , wolf[i] == 1 )
humanTravel: human[i] != human[i+1]
side: And( And( And( humanSide[i] , wolfSide[i] ) , goatSide[i] ) , cabbageSide[i] )
safe: Or( safeAlone[i] , goat[i+1] == human[i+1] )
objectTravel: Or( Or( Or( Or( Or( Or( t1[i] , t2[i] ) , t3[i] ) , t4[i] ) , t5[i] ) , t6[i] ) , t7[i] )
data: And( And( And( side[i] , safe[i] ) , humanTravel[i] ) , objectTravel[i] )
์กฐ๊ฑด์ ์ ๋ ฌ๋์ด Python์ SMT ์์คํ ์ ์ค๋ช ํ๋๋ก ์ค๊ณ๋ ์คํฌ๋ฆฝํธ ํ ํ๋ฆฟ์ ์ฝ์ ๋ฉ๋๋ค.
๋น ํ ํ๋ฆฟ
import json
from z3 import *
s = Solver()
Steps=7
Num= Steps+1
$code$
#template, only start rest
s.add(data + start)
#template
s.add(final)
ind = 0
f = open("/var/www/html/all/bin/python/log.txt", "a")
while s.check() == sat:
ind = ind +1
print ind
m = s.model()
print m
print "traversing model..."
#for d in m.decls():
#print "%s = %s" % (d.name(), m[d])
f.write(str(m))
f.write("nn")
exit()
#s.add(Or(goat[0] != s.model()[data[0]] )) # prevent next model from using the same assignment as a previous model
print "Total solution number: "
print ind
f.close()
์ ์ฒด ์ฒด์ธ์ ๋ง์ง๋ง ์ํ์ ๋ํด์๋ ์ ์ก ํธ๋์ญ์ ์น์ ์ ์ง์ ๋ ๊ท์น์ด ์ ์ฉ๋ฉ๋๋ค.
์ด๋ Z3Prover๊ฐ ๊ถ๊ทน์ ์ผ๋ก ๊ณ์ฝ์์ ์๊ธ์ ์ธ์ถํ ์ ์๋ ์กฐ๊ฑด ์ธํธ๋ฅผ ์ ํํ๊ฒ ์ฐพ์ ๊ฒ์์ ์๋ฏธํฉ๋๋ค.
๊ฒฐ๊ณผ์ ์ผ๋ก ์ฐ๋ฆฌ๋ ๊ณ์ฝ์ ์์ ํ ๊ธฐ๋ฅ์ ๊ฐ์ถ SMT ๋ชจ๋ธ์ ์๋์ผ๋ก ๋ฐ๊ฒ ๋ฉ๋๋ค.
๋ด๊ฐ ์๋์ผ๋ก ์ปดํ์ผํ ์ด์ ๊ธฐ์ฌ์ ๋ชจ๋ธ๊ณผ ๋งค์ฐ ์ ์ฌํ๋ค๋ ๊ฒ์ ์ ์ ์์ต๋๋ค.
์์ฑ๋ ํ ํ๋ฆฟ
import json
from z3 import *
s = Solver()
Steps=7
Num= Steps+1
human = [ Int('human_%i' % (i + 1)) for i in range(Num) ]
wolf = [ Int('wolf_%i' % (i + 1)) for i in range(Num) ]
goat = [ Int('goat_%i' % (i + 1)) for i in range(Num) ]
cabbage = [ Int('cabbage_%i' % (i + 1)) for i in range(Num) ]
nothing= [ And( human[i] == human[i+1], wolf[i] == wolf[i+1], goat[i] == goat[i+1], cabbage[i] == cabbage[i+1] ) for i in range(Num-1) ]
start= [ human[0] == 1, wolf[0] == 0, goat[0] == 1, cabbage[0] == 0 ]
safeAlone= [ And( goat[i+1] != wolf[i+1] , goat[i+1] != cabbage[i+1] ) for i in range(Num-1) ]
safe= [ Or( safeAlone[i] , goat[i+1] == human[i+1] ) for i in range(Num-1) ]
humanTravel= [ human[i] != human[i+1] for i in range(Num-1) ]
cabbageSide= [ Or( cabbage[i] == 0 , cabbage[i] == 1 ) for i in range(Num-1) ]
goatSide= [ Or( goat[i] == 0 , goat[i] == 1 ) for i in range(Num-1) ]
humanSide= [ Or( human[i] == 0 , human[i] == 1 ) for i in range(Num-1) ]
t7= [ And( And( And( humanTravel[i] , wolf[i+1] == wolf[i] ) , goat[i+1] == goat[i] ) , cabbage[i+1] == cabbage[i] ) for i in range(Num-1) ]
t3= [ And( And( And( humanTravel[i] , wolf[i+1] == wolf[i] ) , goat[i+1] == goat[i] ) , cabbage[i+1] == cabbage[i] + 1 ) for i in range(Num-1) ]
t6= [ And( And( And( humanTravel[i] , wolf[i+1] == wolf[i] ) , goat[i+1] == goat[i] ) , cabbage[i+1] == cabbage[i] - 1 ) for i in range(Num-1) ]
t2= [ And( And( And( humanTravel[i] , wolf[i+1] == wolf[i] ) , goat[i+1] == goat[i] + 1 ) , cabbage[i+1] == cabbage[i] ) for i in range(Num-1) ]
t5= [ And( And( And( humanTravel[i] , wolf[i+1] == wolf[i] ) , goat[i+1] == goat[i] - 1 ) , cabbage[i+1] == cabbage[i] ) for i in range(Num-1) ]
t1= [ And( And( And( humanTravel[i] , wolf[i+1] == wolf[i] + 1 ) , goat[i+1] == goat[i] ) , cabbage[i+1] == cabbage[i] ) for i in range(Num-1) ]
t4= [ And( And( And( humanTravel[i] , wolf[i+1] == wolf[i] - 1 ) , goat[i+1] == goat[i] ) , cabbage[i+1] == cabbage[i] ) for i in range(Num-1) ]
wolfSide= [ Or( wolf[i] == 0 , wolf[i] == 1 ) for i in range(Num-1) ]
side= [ And( And( And( humanSide[i] , wolfSide[i] ) , goatSide[i] ) , cabbageSide[i] ) for i in range(Num-1) ]
objectTravel= [ Or( Or( Or( Or( Or( Or( t1[i] , t2[i] ) , t3[i] ) , t4[i] ) , t5[i] ) , t6[i] ) , t7[i] ) for i in range(Num-1) ]
data= [ Or( And( And( And( side[i] , safe[i] ) , humanTravel[i] ) , objectTravel[i] ) , nothing[i]) for i in range(Num-1) ]
fState= And( And( And( human[Steps] == 1 , wolf[Steps] == 1 ) , goat[Steps] == 1 ) , cabbage[Steps] == 1 )
final= fState
#template, only start rest
s.add(data + start)
#template
s.add(final)
ind = 0
f = open("/var/www/html/all/bin/python/log.txt", "a")
while s.check() == sat:
ind = ind +1
print ind
m = s.model()
print m
print "traversing model..."
#for d in m.decls():
#print "%s = %s" % (d.name(), m[d])
f.write(str(m))
f.write("nn")
exit()
#s.add(Or(goat[0] != s.model()[data[0]] )) # prevent next model from using the same assignment as a previous model
print "Total solution number: "
print ind
f.close()
์ถ์ ํ Z3Prover๋ ์ค๋งํธ ๊ณ์ฝ์ ํด๊ฒฐํ๊ณ ์๊ธ์ ์ธ์ถํ ์ ์๋ ์ผ๋ จ์ ๊ฑฐ๋๋ฅผ ์ ๊ณตํฉ๋๋ค.
Winning transaction chain found:
Data transaction: human= 0, wolf= 0, goat= 1, cabbage= 0
Data transaction: human= 1, wolf= 0, goat= 1, cabbage= 1
Data transaction: human= 0, wolf= 0, goat= 0, cabbage= 1
Data transaction: human= 1, wolf= 1, goat= 0, cabbage= 1
Data transaction: human= 0, wolf= 1, goat= 0, cabbage= 1
Data transaction: human= 1, wolf= 1, goat= 1, cabbage= 1
Data transaction: human= 1, wolf= 1, goat= 1, cabbage= 1
Transfer transaction
ํ๋ฆฌ ๊ณ์ฝ ์ธ์๋ ์์ ๋ง์ ๊ณ์ฝ์ ์คํํ๊ฑฐ๋ 2๋ฒ์ ํธ๋์ญ์ ์ผ๋ก ํด๊ฒฐ๋๋ ๊ฐ๋จํ ์๋ฅผ ์๋ํด ๋ณผ ์ ์์ต๋๋ค.
let contract = tx.sender
let a= extract(getInteger(contract,"a"))
let b= extract(getInteger(contract,"b"))
let c= extract(getInteger(contract,"c"))
let d= extract(getInteger(contract,"d"))
match tx {
case t:DataTransaction =>
let na= extract(getInteger(t.data,"a"))
let nb= extract(getInteger(t.data,"b"))
let nc= extract(getInteger(t.data,"c"))
let nd= extract(getInteger(t.data,"d"))
nd == 0 || a == 100 - 5
case s:TransferTransaction =>
( a + b - c ) * d == 12
case _ => true
}
์ฒซ ๋ฒ์งธ ๋ฒ์ ์ด๋ค ๋ณด๋ ๊ตฌ๋ฌธ์ด ๋งค์ฐ ์ ํ๋์ด ์๊ณ ๋ฒ๊ทธ๊ฐ ์์ ์ ์์ต๋๋ค.
๋ค์ ๊ธฐ์ฌ์์๋ VM์ ์ถ๊ฐ ๊ฐ๋ฐ์ ๋ํด ๋ค๋ฃจ๊ณ VM์ ๋์์ ๋ฐ์ ๋จ์ํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๊ฒ์ด ์๋๋ผ ๊ณต์์ ์ผ๋ก ๊ฒ์ฆ๋ ์ค๋งํธ ๊ณ์ฝ์ ์์ฑํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ค ๊ณํ์
๋๋ค.
์บ๋ฆญํฐ ๊ฐ์๋จธ์ ์ ๋ค์์์ ์ด์ฉ ๊ฐ๋ฅํฉ๋๋ค.
์ฌ๋ณผ๋ฆญ VM์ ์์ค์ฝ๋๋ฅผ ์ ๋ฆฌํ๊ณ ๊ฑฐ๊ธฐ์ ์ฝ๋ฉํธ๋ฅผ ์ถ๊ฐํ ํ GitHub์ ์ฌ๋ ค ๋ฌด๋ฃ๋ก ์ ๊ทผํ ์์ ์
๋๋ค.
์ถ์ฒ : habr.com